---
title: Provisioning with SCIM Integration
slug: provisioning-with-scim-integration
docTags: 
createdAt: 2025-08-11T11:13:48.000Z
---

Swimlane Turbine supports integration with System for Cross-domain Identity Management (SCIM) 2.0. This helps streamline user management by automating onboarding and off boarding of users. Managing groups and the association of users to groups can be handled efficiently without manual intervention.

Swimlane Turbine supports SCIM 2.0 integration with:

- [Okta SCIM Integration](docId\:MQuNiQc1hs6AkS15roIPx)
- [Azure SCIM Integration](docId\:zw6AyNXm_yzpYacPFUwkR)
- [JumpCloud SCIM Integration](docId\:sJVsY89msBvQma91aid5k)
- [Ping Identity SCIM Integration](docId\:ytOezir1nBw_xKYr-qg6n)

## Choose Your Path

| Goal                            | Go to                                                                                                                                 |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Configure SCIM in your IdP      | IdP links in the info callout above                                                                                                   |
| Prerequisites and network       | [Prerequisites for Configuring SCIM](https://docs.swimlane.com/provisioning-with-scim-integration#prerequisites-for-configuring-scim) |
| Base URL and PAT authentication | [Authentication](https://docs.swimlane.com/provisioning-with-scim-integration#authentication)                                         |
| SCIM REST API reference         | [REST API Endpoints for SCIM](https://docs.swimlane.com/provisioning-with-scim-integration#rest-api-endpoints-for-scim)               |
| Attribute mapping               | [Field Mapping with Swimlane](https://docs.swimlane.com/provisioning-with-scim-integration#field-mapping-with-swimlane)               |

With SCIM integration you can:

- Create, retrieve, update, and deactivate users
- Delete users in Swimlane Turbine (Turbine 26.0.0 and later)
- Create, retrieve, update, and delete groups
- Manage group membership through SCIM PUT or PATCH operations
- Sync user profile fields from your IdP (see [Field Mapping with Swimlane](https://docs.swimlane.com/provisioning-with-scim-integration#field-mapping-with-swimlane))

Roles assigned in Swimlane Turbine are **not** overwritten by SCIM. Assign roles to synced groups manually after provisioning.

### Common User Lifecycle Behavior

User deprovisioning actions received through SCIM do not always result in user deletion. Depending on the provisioning event, users may be disabled in Swimlane Turbine rather than removed.

Examples include user suspension or removal from all SCIM-managed groups. Explicit SCIM DELETE operations continue to delete users when supported by the identity provider and Turbine version.

## Prerequisites for Configuring SCIM

- **Supported IdP**: Verify that your Identity Provider (IdP) supports SCIM integration.
- **SCIM-Compatible Configuration**: Ensure Swimlane is configured to support SCIM integration and provides the required SCIM endpoints.
- **Network Configuration**: Confirm that network settings allow communication between your IdP and Swimlane over HTTPS.
- **Authentication Credentials**: Create a Swimlane Personal Access Token (PAT) for a user with Account Admin privileges at the account level.

## Configuring SCIM

Provisioning a SCIM (System for Cross-domain Identity Management) application in an Identity Provider (IdP) involves configuring the IdP to communicate with the Service Provider (SP) using the SCIM protocol, ensuring efficient user identity management and automation.

See your IdP documentation for more information on provisioning SCIM in your IdP.

:::hint{type="info"}
If you already have SAML and LDAP, you can still enable SCIM.
:::

## REST API Endpoints for SCIM

Following are the endpoints as part of the implementation on the tenant service (swimlane-tenant).

In the paths below, substitute `ACCOUNT_ID` with your Swimlane account UUID. For operations on a single resource, substitute `userId` or `groupId` with the SCIM resource id.

**User endpoints**

| Method | Path                                                  |
| ------ | ----------------------------------------------------- |
| GET    | `/tenant/api/account/ACCOUNT_ID/scim/v2/Users`        |
| POST   | `/tenant/api/account/ACCOUNT_ID/scim/v2/Users`        |
| GET    | `/tenant/api/account/ACCOUNT_ID/scim/v2/Users/userId` |
| PUT    | `/tenant/api/account/ACCOUNT_ID/scim/v2/Users/userId` |
| PATCH  | `/tenant/api/account/ACCOUNT_ID/scim/v2/Users/userId` |
| DELETE | `/tenant/api/account/ACCOUNT_ID/scim/v2/Users/userId` |

:::hint{type="info"}
`DELETE /tenant/api/account/ACCOUNT_ID/scim/v2/Users/userId` is supported in Turbine 26.0.0 and later. In earlier versions, user deprovisioning must be handled by updating the user status with PUT or PATCH and setting `active` to `false`.
:::

**Groups endpoints**

| Method | Path                                                    |
| ------ | ------------------------------------------------------- |
| GET    | `/tenant/api/account/ACCOUNT_ID/scim/v2/Groups`         |
| POST   | `/tenant/api/account/ACCOUNT_ID/scim/v2/Groups`         |
| GET    | `/tenant/api/account/ACCOUNT_ID/scim/v2/Groups/groupId` |
| PUT    | `/tenant/api/account/ACCOUNT_ID/scim/v2/Groups/groupId` |
| PATCH  | `/tenant/api/account/ACCOUNT_ID/scim/v2/Groups/groupId` |
| DELETE | `/tenant/api/account/ACCOUNT_ID/scim/v2/Groups/groupId` |

### User Endpoint Examples

**GET** — Accepts `startIndex` and `count` query parameters. Accepts a filter query string such as `filter=userName eq "${email}"`.

Returns the list of users that match the supplied filter criteria.

:::hint{type="info"}
- An empty or unsupported filter returns an empty result set by design. User lookups currently support filtering by userName.
- Responses returned from userName-based filtering do not include group membership information. To retrieve complete group membership details, use `GET /Users/{userId}`.
:::

Schema for empty Response:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:api\:messages:2.0\:ListResponse"],
&#x20;   "totalResults": 0,
&#x20;   "startIndex": 1,
&#x20;   "itemsPerPage": 0,
&#x20;   "Resources": \[]
}
:::

Schema for Response with Users:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:api\:messages:2.0\:ListResponse"],
&#x20;   "totalResults": 0,
&#x20;   "startIndex": 1,
&#x20;   "itemsPerPage": 0,
&#x20;   "Resources": \[
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:User"],
&#x20;   "id": "23a35c27-23d3-4c03-b4c5-6443c09e7173",
&#x20;   "userName": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;   "name": \{
&#x20;       "givenName": "Test",
&#x20;       "familyName": "User"
&#x20;   },
&#x20;   "emails": \[\{
&#x20;       "primary": true,
&#x20;       "value": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;       "type": "work"
&#x20;   }],
&#x20;   "displayName": "Test User",
&#x20;   "locale": "en-US",
&#x20;   "externalId": "00ujl29u0le5T6Aj10h7",
&#x20;   "active": true,
&#x20;   "groups": \[],
&#x20;   "meta": \{
&#x20;       "resourceType": "User"
&#x20;   }
}
]
}
:::

Schema for Response with User Group Membership:

```json
{
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "totalResults": 1,
    "startIndex": 1,
    "itemsPerPage": 100,
    "Resources": [
        {
            "userName": "jane.doe@example.com",
            "name": {
                "givenName": "Jane",
                "familyName": "Doe"
            },
            "emails": [
                {
                    "primary": true,
                    "value": "jane.doe@example.com",
                    "type": "work"
                }
            ],
            "displayName": "Jane Doe",
            "groups": [
                {
                    "value": "019f12cb-5197-7647-abc6-11c8e31fd0b0",
                    "display": "Engineering",
                    "type": "direct"
                }
            ],
            "active": true,
            "schemas": [
                "urn:ietf:params:scim:schemas:core:2.0:User"
            ],
            "id": "019f1375-8d45-7077-ad89-a8026805f545"
        }
    ]
}
```

**Get a Specific User** - GET Users/userId

Response Schema for getting a user:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:User"],
&#x20;   "id": "23a35c27-23d3-4c03-b4c5-6443c09e7173",
&#x20;   "userName": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;   "name": \{
&#x20;       "givenName": "Test",
&#x20;       "middleName": "",
&#x20;       "familyName": "User"
&#x20;   },
&#x20;   "active": true,
&#x20;   "emails": \[\{
&#x20;       "primary": true,
&#x20;       "value": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;       "type": "work",
&#x20;       "display": "[test.user@okta.local](mailto\:test.user@okta.local)"
&#x20;   }],
&#x20;   "groups": \[],
&#x20;   "meta": \{
&#x20;       "resourceType": "User"
&#x20;   }
}
:::

:::hint{type="info"}
Beginning with Turbine 26.2, `GET /Users/{userId}` returns the user's group memberships when group associations exist in Swimlane Turbine.
:::

**Create - Post**

It accepts the user details from SCIM and returns the user with additional fields added by Swimlane.

Request Schema:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:User"],
&#x20;   "userName": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;   "name": \{
&#x20;       "givenName": "Test",
&#x20;       "familyName": "User"
&#x20;   },
&#x20;   "emails": \[\{
&#x20;       "primary": true,
&#x20;       "value": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;       "type": "work"
&#x20;   }],
&#x20;   "displayName": "Test User",
&#x20;   "locale": "en-US",
&#x20;   "externalId": "00ujl29u0le5T6Aj10h7",
&#x20;   "groups": \[],
&#x20;   "active": true
}
:::

Response Schema:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:User"],
&#x20;   "id": "23a35c27-23d3-4c03-b4c5-6443c09e7173",
&#x20;   "userName": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;   "name": \{
&#x20;       "givenName": "Test",
&#x20;       "familyName": "User"
&#x20;   },
&#x20;   "emails": \[\{
&#x20;       "primary": true,
&#x20;       "value": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;       "type": "work"
&#x20;   }],
&#x20;   "displayName": "Test User",
&#x20;   "locale": "en-US",
&#x20;   "externalId": "00ujl29u0le5T6Aj10h7",
&#x20;   "active": true,
&#x20;   "groups": \[],
&#x20;   "meta": \{
&#x20;       "resourceType": "User"
&#x20;   }
}
:::

If the user already exists then response should be returned in following schema:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:api\:messages:2.0\:Error"],
&#x20;   "detail": "User already exists in the database.",
&#x20;   "status": 409
}
:::

Example: Create a User and Assign to an Existing Group

Request

```json
{
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "userName": "jane.doe@example.com",
    "displayName": "Jane Doe",
    "active": true,
    "groups": [
        {
            "value": "019f12cb-5197-7647-abc6-11c8e31fd0b0"
        }
    ]
}
```

Response

```json
{
    "userName": "jane.doe@example.com",
    "displayName": "Jane Doe",
    "groups": [
        {
            "value": "019f12cb-5197-7647-abc6-11c8e31fd0b0",
            "display": "Engineering",
            "type": "direct"
        }
    ],
    "active": true,
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "id": "019f1375-8d45-7077-ad89-a8026805f545"
}
```

:::hint{type="info"}
If the specified group exists in the same Swimlane account, the user is created and associated with that group. If the group ID is invalid or belongs to a different account, the user is created successfully and the groups attribute in the response is returned as an empty array.
:::

**PUT** — `PUT /Users/{userId}`

Request schema to update the user:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:User"],
&#x20;   "id": "23a35c27-23d3-4c03-b4c5-6443c09e7173",
&#x20;   "userName": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;   "name": \{
&#x20;       "givenName": "Another",
&#x20;       "middleName": "Excited",
&#x20;       "familyName": "User"
&#x20;   },
&#x20;   "emails": \[\{
&#x20;       "primary": true,
&#x20;       "value": "[test.user@okta.local](mailto\:test.user@okta.local)",
&#x20;       "type": "work",
&#x20;       "display": "[test.user@okta.local](mailto\:test.user@okta.local)"
&#x20;   }],
&#x20;   "active": true,
&#x20;   "groups": \[],
&#x20;   "meta": \{
&#x20;       "resourceType": "User"
&#x20;   }
}
:::

Response should return the updated user.

Example: Add a User to an Existing Group

Request

```json
{
    "groups": [
        {
            "value": "019f12cb-5197-7647-abc6-11c8e31fd0b0"
        }
    ]
}
```

Response

```json
{
    "userName": "jane.doe@example.com",
    "displayName": "Jane Doe",
    "groups": [
        {
            "value": "019f12cb-5197-7647-abc6-11c8e31fd0b0",
            "display": "Engineering",
            "type": "direct"
        }
    ],
    "active": true
}
```

:::hint{type="info"}
When groups is included in a PUT request, the specified groups are added to the user's existing group memberships. Existing group memberships are retained. If a referenced group does not exist or belongs to another account, the user is updated successfully and the groups attribute in the response is returned as an empty array.
:::

**PATCH** — `PATCH /Users/{userId}`

To disable, enable, or update user attributes, PATCH is used.

Example request schema for disabling the users:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:api\:messages:2.0\:PatchOp"],
&#x20;   "Operations": \[\{
&#x20;       "op": "replace",
&#x20;       "value": \{
&#x20;           "active": false
&#x20;       }
&#x20;   }]
}
:::

Response for patch should be updated user or 204.

:::hint{type="info"}
`DELETE /Users/{userId}` deletes the user in Swimlane Turbine. This endpoint is supported in Turbine 26.0.0 and later. In earlier versions, use PATCH with `active` set to `false` to disable the user and revoke access.
:::

### Group Endpoint Examples

**GET** — /Groups — Accepts `startIndex` and `count` query parameters.

:::hint{type="info"}
Group queries currently support filtering by displayName only.
**Example:**
filter=displayName eq "Group Name"
An empty filter returns an empty result set.
:::

GET should accept query string filter = displayName eq "$"

Sample Request:

:::BlockQuote
/tenant/api/account/ACCOUNT\_ID/scim/v2/Groups?filter=displayName%20eq%20%22Test%20SCIMv2%22\&startIndex=1\&count=100
:::

Response Schema if group exists:

:::BlockQuote
\{
&#x20;   "schemas": \[
&#x20;       "urn\:ietf\:params\:scim\:api\:messages:2.0\:ListResponse"
&#x20;   ],
&#x20;   "totalResults": 1,
&#x20;   "startIndex": 1,
&#x20;   "itemsPerPage": 1,
&#x20;   "Resources": \[
&#x20;       \{
&#x20;       "id": "e7d09e9b3faa4888b65cf9e9316cba1c",
&#x20;       "meta": \{
&#x20;           "created": "2024-05-15T09:21:23",
&#x20;           "lastModified": "2024-05-15T09:21:23",
&#x20;           "version": "v1.0"
&#x20;       },
&#x20;       "displayName": "Test SCIMv1"
&#x20;      },
&#x20;   ]
}
:::

Response schema if no group exists:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:api\:messages:2.0\:ListResponse"],
&#x20;   "totalResults": 0,
&#x20;   "startIndex": 1,
&#x20;   "itemsPerPage": 0,
&#x20;   "Resources": \[]
}
:::

**GET** — `GET /Groups/{groupId}`

Response schema:

:::BlockQuote
\{
&#x20; "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:Group"],
&#x20;   "id": "abf4dd94-a4c0-4f67-89c9-76b03340cb9b",
&#x20;   "displayName": "Test SCIMv2",
&#x20;   "members":  \[\{
&#x20;       "value": "b1c794f24f4c49f4b5d503a4cb2686ea",
&#x20;       "display": "SCIM 2 Group A"
&#x20;   }],
&#x20;   "meta": \{
&#x20;       "resourceType": "Group"
&#x20;   }
}
:::

**POST** - Request schema, Response should be group object same as Get.

Example:

:::BlockQuote
\{
&#x20;"schemas": \[
&#x20;  "urn\:ietf\:params\:scim\:schemas\:core:2.0\:Group"
&#x20;],
&#x20;"displayName": "TestGroup",
&#x20;"members": \[
&#x20;  \{
&#x20;    "value": "584a1e86-5de0-4634-80a6-f357156de9f3",
&#x20;    "display": "[aashmi.chaudhary+okta@swimlane.com](mailto\:aashmi.chaudhary+okta@swimlane.com)"
&#x20;  }
&#x20;]
}
:::

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:Group"],
&#x20;   "displayName": "Test SCIMv2",
&#x20;   "members": \[]
}
:::

**PUT** — `PUT /Groups/{groupId}`

Use PUT to send a full SCIM Group resource. Swimlane creates the group if it does not exist (matched by display name or SCIM external ID), updates group details when applicable, and adds members listed in the request body.

:::hint{type="info"}
Many IdPs (for example, Azure and Okta) use **PATCH** for group rename and membership changes instead of PUT. See the PATCH examples below.
:::

Request schema:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:schemas\:core:2.0\:Group"],
&#x20;   "id": "abf4dd94-a4c0-4f67-89c9-76b03340cb9b",
&#x20;   "displayName": "Test SCIMv2",
&#x20;   "members": \[\{
&#x20;       "value": "23a35c27-23d3-4c03-b4c5-6443c09e7173",
&#x20;       "display": "[test.user@okta.local](mailto\:test.user@okta.local)"
&#x20;   }]
}
:::

Response should return the updated group object (HTTP 200), with the same shape as GET group by ID.

**PATCH** — `PATCH /Groups/{groupId}`

PATCH is used to update the group display name or group membership (add or remove members).

Request schema for PATCH to update group name:

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:api\:messages:2.0\:PatchOp"],
&#x20;   "Operations": \[\{
&#x20;       "op": "replace",
&#x20;       "value": \{
&#x20;           "id": "abf4dd94-a4c0-4f67-89c9-76b03340cb9b",
&#x20;           "displayName": "Test SCIMv2"
&#x20;       }
&#x20;   }]
}
:::

Response for patch could be the updated group object or 204.

Users can be added by PATCH for OIN app.

Request schema :

:::BlockQuote
\{
&#x20;   "schemas": \["urn\:ietf\:params\:scim\:api\:messages:2.0\:PatchOp"],
&#x20;   "Operations": \[\{
&#x20;       "op": "remove",
&#x20;       "path": "members\[value eq \\"89bb1940-b905-4575-9e7f-6f887cfb368e\\"]"
&#x20;       },
&#x20;       \{
&#x20;       "op": "add",
&#x20;       "path": "members",
&#x20;       "value": \[\{
&#x20;           "value": "23a35c27-23d3-4c03-b4c5-6443c09e7173",
&#x20;           "display": "[test.user@okta.local](mailto\:test.user@okta.local)"
&#x20;       }]
&#x20;   }]
}
:::

The response should be the updated group or 204.

**DELETE** — `DELETE /Groups/{groupId}` — Returns 204 when the group is deleted.

## Authentication

The SCIM endpoint uses User PAT Token defined for the user at an account level.

:::hint{type="info"}
The SCIM base URL includes your Swimlane hostname and account UUID. Use this format when configuring your IdP (Tenant URL or Base URL):

`https://your-swimlane-host/tenant/api/account/ACCOUNT_ID/scim/v2`

Replace `your-swimlane-host` with your Swimlane Turbine hostname and `ACCOUNT_ID` with your account UUID. IdPs append resource paths such as `/Users` and `/Groups`. See the IdP-specific guides linked at the top of this page.
:::

## Authorization

- User with Account Admin privilege should be able to access the endpoints
- Cross-account access is restricted
- All the roles assigned in Turbine for the users and groups will not be overwritten by the SCIM API Endpoint call

## Field Mapping with Swimlane

| SCIM            | Swimlane    |
| --------------- | ----------- |
| userName        | Email       |
| name.givenName  | firstname   |
| name.familyName | lastname    |
| displayName     | DisplayName |
| groups          | Groups      |
| active          | disabled    |

:::hint{type="info"}
When provisioning from **Azure**, only `userPrincipalName` and `displayName` are required. If `firstname`, `lastname`, or `email` are not provided by Azure, Swimlane will automatically substitute them using the value from `userPrincipalName`.
:::
