SCIM
System for Cross-domain Identity Management (also known as SCIM) is a protocol for user management across multiple applications. It allows an IT or Operations team to easily provision (add), de-provision (deactivate), and update user data across multiple applications at once.
Read more about the specification in the official documentation.
Considerations
- Your Identity Provider (or IdP for short) is the source of truth. If you connect Unit's SCIM API to your IdP, any user management change performed in the Unit Dashboard will be overridden by the user data sent via SCIM.
- SCIM is a one-way sync. Changes made in the IdP will be reflected in Unit, but changes made in Unit will not be reflected in the IdP.
Prerequisites
- Active Organization
- Admin privileges
- An Identity Provider (IdP) that supports Custom SCIM
Which SCIM capabilities are supported?
The following SCIM capabilities are supported:
- User Provisioning (creating new users)
- User De-provisioning (disabling users)
- Updating User Details (role, phone, status)
Configure Custom SCIM API
You can configure SCIM with your Identity Provider (IdP) if it supports custom SCIM by providing Unit's SCIM API url and a Bearer Token. Unit's SCIM implementation targets version 2.0 of the protocol.
The base URL for all calls from the identity provider: https://api.unit.co/scim/v2/. All SCIM methods are branches of this base URL.
Bearer Token
An OAuth bearer token must be attached to every SCIM request. To generate a bearer token, you must first create an API key in the Unit dashboard.
The token must be included via an Authorization header with a type of Bearer when calling any of the SCIM methods.
Example of using the bearer token:
GET /scim/v2/Users
Host: api.unit.co
Content-Type: application/vnd.api+json
Authorization: Bearer <YOUR_TOKEN>
Unit User <-> SCIM User Mapping
The following attributes are supported in the SCIM user schema:
Unit User Attribute Name | SCIM Attribute Name | Type | Description | Example value |
---|---|---|---|---|
Username | userName | string | Username (user's work email address) | 'user@example.com' |
User Full Name | name | object | Full name of the user | |
name.givenName | string | First name of the user | 'John' | |
name.familyName | string | Last name of the user | 'Doe' | |
User Status | active | boolean | User status (enabled or disabled) | true |
User Role | userType | string | Role | 'readonly' |
User Phone | phoneNumbers | array of objects | User's phone number | |
phoneNumbers[0].primary | boolean | Indicates primary phone number | true | |
phoneNumbers[0].type | string | Phone number type | 'work' | |
phoneNumbers[0].value | string | Phone number value (rfc3966 format) | 'tel:+1-234-5678912' |
Note that not all attributes are returned or required for every endpoint. See specific endpoint documentation for more details.
SCIM Endpoints
GET /scim/v2/Users
This endpoint returns a paginated list of users in the organization.
Supported Query Parameters
Query Parameter | Type | Description | Example |
---|---|---|---|
filter | string | Filter the results matching email address, by user status, or both. Only eq operator is supported. |
|
count | number | Number of resources that will be returned. Default is 50. Maximum is 1000. | |
startIndex | number | Number of resources to skip. Default is 0. |
Example request:
GET /scim/v2/Users?filter=userName eq user@example.com and active eq false&count=10&startIndex=20
Host: api.unit.co
Content-Type: application/vnd.api+json
Authorization: Bearer <YOUR_TOKEN>
Example successful response (status 200 OK
)
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"itemsPerPage": 50,
"startIndex": 20,
"totalResults": 1,
"Resources": [
{
"id": "123456",
"userName": "user@example.com",
"active": false,
"userType": "admin",
"phoneNumbers": [
{
"value": "tel:+1-646-719-1111",
"type": "work"
}
]
}
]
}
Get /scim/v2/Users/{id}
This endpoint returns a specific user's details.
Example request:
GET /scim/v2/Users/123456
Host: api.unit.co
Content-Type: application/vnd.api+json
Authorization: Bearer <YOUR_TOKEN>
Example successful response (status 200 OK
)
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"meta": {
"resourceType": "User",
"created": "2024-08-07T07:34:31.969Z",
"lastModified": "2025-01-13T13:07:50.267Z",
"location": "",
"version": "W/\"2025-01-13T13:07:50.267Z\""
},
"id": "123456",
"userName": "dschrutte@dundermifflin.com",
"active": false,
"userType": "readonly",
"phoneNumbers": [
{
"value": "tel:+1-6467191111",
"type": "work"
}
]
}
POST /scim/v2/Users
Create a new user in the organization.
Example request:
POST /scim/v2/Users
Host: api.unit.co
Content-Type: application/vnd.api+json
Authorization: Bearer <YOUR_BEARER_TOKEN>
{
"userName": "dschrutte@dundermifflin.com",
"name": {
"givenName": "Dwight",
"familyName": "Schrutte"
},
"phoneNumbers": [
{
"type": "work",
"value": "tel:+1-201-295-0911",
"primary": true
}
],
"userType": "unit-readonly",
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"]
}
Example successful response (status 201 Created
)
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"meta": {
"resourceType": "User",
"created": "2025-01-13T13:05:17.939Z",
"lastModified": "2025-01-13T13:05:17.939Z",
"location": "",
"version": "W/\"2025-01-13T13:05:17.939Z\""
},
"id": "123456",
"userName": "dshrutte@dundermifflin.com",
"active": true,
"userType": "readonly",
"phoneNumbers": [
{
"value": "tel:+1-2012950911",
"type": "work"
}
]
}
PATCH /scim/v2/Users/{id}
Updates a specific user's details.
Supported Operations
Operation | Description |
---|---|
replace | Replaces an existing attribute with a new value. |
add | Same as replace |
Supported Paths and Values
Path | Description | Value type | Example Value |
---|---|---|---|
userType | User's role. | string | "readonly" |
phoneNumbers[type eq "work"].value | User's phone number. | string in rfc3966 format | "tel:+1-646-719-1111" |
active | User's status (enabled or disabled). | boolean | true |
Example request:
PATCH /scim/v2/Users/2
Host: api.unit.co
Content-Type: application/vnd.api+json
Authorization: Bearer <YOUR_TOKEN>
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "replace",
"path": "userType",
"value": "readonly"
},
{
"op": "replace",
"path": "phoneNumbers[type eq \"work\"].value",
"value": "tel:+1-646-719-1111"
},
{
"op": "replace",
"path": "active",
"value": true
}
]
}
Example successful response (status 200 OK
)
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"meta": {
"resourceType": "User",
"created": "2023-08-07T07:34:31.969Z",
"lastModified": "2025-01-13T13:06:56.913Z",
"location": "",
"version": "W/\"2025-01-13T13:06:56.913Z\""
},
"id": "2",
"userName": "dschrutte@dundermifflin.com",
"active": true,
"userType": "readonly",
"phoneNumbers": [
{
"value": "tel:+1-6467191111",
"type": "work"
}
]
}
DELETE /scim/v2/Users/{id}
Disable a specific user in the organization (same as patching a user with active
set to false
).
Example request:
DELETE /scim/v2/Users/123456
Host: api.unit.co
Content-Type: application/vnd.api+json
Authorization: Bearer <YOUR_TOKEN>
Example response (status 204 No Content
)
GET /scim/v2/Schemas
This endpoint returns a list of supported SCIM schemas.
It's helpful for getting a list of supported attributes for a user and their values.
Example request:
GET /scim/v2/Schemas
Host: api.unit.co
Content-Type: application/vnd.api+json
Authorization: <YOUR_TOKEN>
Example response (status 200 OK
)
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Schema"
],
"totalResults": 1,
"Resources": [
{
"id": "urn:ietf:params:scim:schemas:core:2.0:User",
"name": "User",
"mutability": "readWrite",
"description": "SCIM core schema for representing users",
"attributes": [
{
"name": "userName",
"type": "string",
"multiValued": false,
"description": "Unique identifier for the User in the form of their email address.",
"required": true,
"caseExact": false,
"mutability": "readWrite",
"returned": "always",
"uniqueness": "server"
},
{
"name": "name",
"type": "complex",
"multiValued": false,
"description": "The user's full name",
"required": true,
"caseExact": false,
"mutability": "readWrite",
"returned": "always",
"uniqueness": "server",
"subAttributes": [
{
"name": "givenName",
"type": "string",
"multiValued": false,
"description": "First name of the User.",
"required": true,
"caseExact": false,
"mutability": "readWrite",
"returned": "default",
"uniqueness": "none"
},
{
"name": "familyName",
"type": "string",
"multiValued": false,
"description": "Last name of the User.",
"required": true,
"caseExact": false,
"mutability": "readWrite",
"returned": "default",
"uniqueness": "none"
}
]
},
{
"name": "userType",
"type": "string",
"multiValued": false,
"description": "User type",
"required": true,
"caseExact": false,
"mutability": "readWrite",
"returned": "always",
"uniqueness": "none",
"canonicalValues": [
"readonly",
"restricted",
"admin"
]
},
{
"name": "phoneNumbers",
"type": "complex",
"multiValued": true,
"description": "The user's phone number",
"required": true,
"mutability": "readWrite",
"subAttributes": [
{
"name": "value",
"type": "string",
"multiValued": false,
"description": "Phone number.",
"required": false,
"caseExact": false,
"mutability": "readWrite",
"returned": "default",
"uniqueness": "none",
"pattern": "^tel:\\+\\d{1,3}-\\d{1,4}-\\d{3,4}-\\d{4}$"
},
{
"name": "type",
"type": "string",
"multiValued": false,
"description": "Type of phone number (e.g., work, home, mobile).",
"required": false,
"caseExact": false,
"canonicalValues": [
"work"
],
"mutability": "readWrite",
"returned": "default",
"uniqueness": "none"
}
]
}
]
}
]
}