Connect a Custom SCIM Application
In addition to supporting integration with popular SCIM provisioning platforms like Okta, Ping, and Entra ID, Tonkean provides an internal SCIM API for custom applications. This reference topic provides the relevant endpoints, request values, and samples to support the creation of a custom SCIM application for Tonkean user provisioning.
Tonkean provides the following SCIM endpoints:
Provision / create user
Deprovision / disable user
Update user fields
Provision user groups
Update user group fields
Update user group memberships (add/remove users from groups)
Delete user groups
Bulk operations
For information regarding the SCIM protocol and API, see the SCIM public documentation.
Create and Configure the Identity Provider
To get started, you must create and configure a new identity provider in Tonkean, generating an API token.
In Tonkean, select your user profile in the upper right, then select Board Settings. The Board Settings screen displays.

In the sidenav, select Identity Provider. The Identity Provider screen displays.

Locate the SCIM API url and select Copy to copy the value. Save this URL in an external document; this is the
BASE_URL.
Select Create New Provider. The Create New Provider window displays.

Select the Provider Type dropdown and choose Custom, enter a Display Name, then select Generate Token. The Access Token displays.

Select Copy to copy the Access Token. Save this token in an external document; this is the
ACCESS_TOKEN.This is the last time you'll be able to view the decrypted token, so make sure you save it somewhere safe in case you need to reference it later.

Users
This section provides information on provisioning, deprovisioning, and updating users in Tonkean.
User Payload
Below is the payload of the “User” entity in the SCIM protocol as it is expected to be sent and received in the SCIM endpoints.
{
"id": "PRSNxxxyyyzzz",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
"urn:tonkean:scim:schemas:extension:custom"
],
"externalId": "custom_user_id",
"userName": "custom_user_id",
"displayName": "Evelyn Rose",
"name": {
"familyName": "Evelyn",
"givenName": "Rose"
},
"emails": [
{
"value": "evelyn.rose@acme.com",
"primary": true,
"type": "work"
}
],
"active": "true",
"meta": {
"resourceType": "User",
"created": 1740706716
},
"urn:ietf:params:scim:schemas:extension:enterprise": {
"Tonkean": "PROCESS_CONTRIBUTOR,SYSTEM_USER"
},
"urn:tonkean:scim:schemas:extension:custom": {
"department": "Feline Play Coordinator",
"employeeId": 122118,
"location": "Florida",
"isManager": false
}
}
User Payload Fields
Field Name | Type | Input | Description |
|---|---|---|---|
id | Tonkean ID | false | The Tonkean ID of the user. Returned in CREATE response. Used for update/delete endpoints in the URL. |
schemas | SCIM schema | true | Value required as part of SCIM protocol. Value should always be:
If you want to include custom attributes in your operations, you must also add this schema value:
|
externalId | String | true | Field used for audit and reference. Will not be displayed in Tonkean. Can be used for custom user id. |
userName | String | true | Field used for audit and reference. If no email is provided in |
displayName | String | true | Full name to use as the user name in the Tonkean app. Usually should be in format of “FirstName LastName” (for example, “John Smith”). |
name | JSON | true | JSON that contains the familyName and givenName fields representing the name of the user. While this is stored, Tonkean is currently using |
emails | JSON Array | true | Array of JSON elements containing the list of emails for the user. Tonkean will only use the email marked with |
active | boolean | true | Value expected is |
meta | JSON | false | A JSON element containing metadata properties returned from Tonkean backend. |
urn:ietf:params:scim:schemas:extension:enterprise | JSON | true | A JSON element with a single field called “Tonkean” that contains the roles to be set for this user in Tonkean. Possible values are:
NOTE: User can be created without any roles and then roles can be assigned via “instant access” or via group membership. |
urn:scim:tonkean | JSON | false | Old value used for Tonkean roles. Used only for backward compatibility. Please ignore. |
urn:tonkean:scim:schemas:extension:custom | JSON | false | Custom schema URN. To include custom attributes in a request, include this URN under Example of custom attributes in the message body: "urn:tonkean:scim:schemas:extension:custom": {
"department": "Feline Play Coordinator",
"employeeId": 122118,
"location": "Florida",
"isManager": false
} |
Provision / Create User
This is the endpoint to create a new user in Tonkean.
POST: {BASE_URL}/Users (for example, https://api.tonkean.com/scim/v2/Users)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
Request Example
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"externalId": "custom_user_id",
"userName": "custom_user_id",
"displayName": "Evelyn Rose",
"name": {
"familyName": "Evelyn",
"givenName": "Rose"
},
"emails": [
{
"value": "evelyn.rose@acme.com",
"primary": true,
"type": "work"
}
],
"active": "true",
"urn:ietf:params:scim:schemas:extension:enterprise": {
"tonkean": "PROCESS_CONTRIBUTOR,SYSTEM_USER"
}
}
Response Example
{
"id": "PRSNyR6viFqBO73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"userName": "custom_user_id",
"name": {
"givenName": "Evelyn",
"familyName": "Rose"
},
"emails": [
{
"primary": true,
"value": "evelyn.rose@acme.com",
"type": "work"
}
],
"displayName": "Evelyn Rose",
"externalId": "custom_user_id",
"active": true,
"meta": {
"resourceType": "User",
"created": 1740706716
},
"urn:scim:tonkean": {
"tonkeanRoles": [
"PROCESS_CONTRIBUTOR",
"SYSTEM_USER"
]
},
"urn:ietf:params:scim:schemas:extension:enterprise": {
"Tonkean": "[PROCESS_CONTRIBUTOR, SYSTEM_USER]"
}
}
Replace User
This is the endpoint to replace all the data for an existing user in Tonkean.
PUT: BASE_URL}/Users/{TonkeanUserID} (for example, https://api.tonkean.com/scim/v2/Users/PRSNyR6viFqBO73)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
Request Example
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"externalId": "custom_user_id_new_value",
"userName": "custom_user_id_new_value",
"displayName": "Evelyn Rose_new_value",
"name": {
"familyName": "Evelyn_new_value",
"givenName": "Rose_new_value"
},
"emails": [
{
"value": "evelyn.rose@acme.com",
"primary": true,
"type": "work"
}
],
"active": "true",
"urn:ietf:params:scim:schemas:extension:enterprise": {
"tonkean": "PROCESS_CONTRIBUTOR"
}
}
Response Example
{
"id": "PRSNyR6viFqBO73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"userName": "custom_user_id_new_value",
"name": {
"givenName": "Evelyn_new_value",
"familyName": "Rose_new_value"
},
"emails": [
{
"primary": true,
"value": "evelyn.rose@acme.com",
"type": "work"
}
],
"displayName": "Evelyn Rose_new_value",
"externalId": "custom_user_id_new_value",
"active": true,
"meta": {
"resourceType": "User",
"created": 1740706716
},
"urn:scim:tonkean": {
"tonkeanRoles": [
"PROCESS_CONTRIBUTOR"
]
},
"urn:ietf:params:scim:schemas:extension:enterprise": {
"Tonkean": "[PROCESS_CONTRIBUTOR]"
}
}
Update User
Partially update data for an existing user in Tonkean.
PATCH: {BASE_URL}/Users/{TonkeanUserID} (for example, https://api.tonkean.com/scim/v2/Users/PRSNyR6viFqBO73)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
For a helpful resource for PATCH calls in SCIM, see SCIM 2.0 Patch Operations.
Request Example
{
"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations":[
{
"op": "replace",
"path": "displayName",
"value": "Evie Rose"
}
]
}
Response Example
{
"id": "PRSNyR6viFqBO73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"userName": "custom_user_id_new_value",
"name": {
"givenName": "Evelyn_new_value",
"familyName": "Rose_new_value"
},
"emails": [
{
"primary": true,
"value": "evelyn.rose@acme.com",
"type": "work"
}
],
"displayName": "Evie Rose",
"externalId": "custom_user_id_new_value",
"active": true,
"meta": {
"resourceType": "User",
"created": 1740706716
},
"urn:scim:tonkean": {
"tonkeanRoles": [
"PROCESS_CONTRIBUTOR"
]
},
"urn:ietf:params:scim:schemas:extension:enterprise": {
"Tonkean": "[PROCESS_CONTRIBUTOR]"
}
}
Disable / Deprovision User
Disable a user in Tonkean.
Users cannot be deleted in Tonkean—only disabled.
DELETE: {BASE_URL}/Users/{TonkeanUserID} (for example, https://api.tonkean.com/scim/v2/Users/PRSNyR6viFqBO73)
Authorization: Bearer {ACCESS_TOKEN}
Request Example
—
Response Example
204 No Content
Get Users
Get existing users in Tonkean.
GET: {BASE_URL}/Users/
Authorization: Bearer {ACCESS_TOKEN}
Query Params:
Param Name | Default | Description |
|---|---|---|
startIndex | 1 | Index to start listing users from. |
count | 100 | Amount of items to return in the call. |
filter | — | Only supported filter: |
Request Example
—
Response Example
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"totalResults": 3,
"startIndex": 1,
"itemsPerPage": 100,
"Resources": [
{...},
{...},
]
}
Get Users by Tonkean ID
Get user details in Tonkean based on tonkean Id (for example, PRSNxcafa).
Request Example
—
Response Example
{
"id": "PRSNyR6viFqBO73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"userName": "custom_user_id_new_value",
"name": {
"givenName": "Evelyn_new_value",
"familyName": "Rose_new_value"
},
"emails": [
{
"primary": true,
"value": "evelyn.rose@acme.com",
"type": "work"
}
],
"displayName": "Evie Rose",
"externalId": "custom_user_id_new_value",
"active": true,
"meta": {
"resourceType": "User",
"created": 1740706716
},
"urn:scim:tonkean": {
"tonkeanRoles": []
},
"urn:ietf:params:scim:schemas:extension:enterprise": {
"Tonkean": "[]"
}
}
Custom Attributes - Non-standard Behaviors
Tonkean's implementation of custom attributes follows the standard SCIM protocol except for several cases. Take note of these exceptions when using custom attributes:
Single fixed custom schema URN - For extended information/custom attributes, only
urn:tonkean:scim:schemas:extension:customis supported.PUT clears by default - Omitting the custom schema object or its URN in the schema clears existing custom attributes.
Omission of empty custom schema objects - If there are no custom attributes, the custom schema field is omitted;
{}is not left in the payload.Empty strings are allowed -
""is accepted as a valid string value and not treated as a validation error.
Groups
This section provides information on provisioning, deprovisioning, and updating user groups in Tonkean.
Group Payload
Below is the payload of the “Group” entity in the SCIM protocol as it is expected to be sent and received in the SCIM endpoints.
{
"id": "SCGRxxxyyyzzz",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins",
"externalId": "custom_id",
"meta": {
"resourceType": "Group"
},
"projectId": "PROJxxxyyyzzz",
"members": [
]
}
Group Payload Fields
Field Name | Type | Input | Description |
|---|---|---|---|
id | Tonkean ID | false | The tonkean ID of the group. Returned in CREATE response. Used for update/delete endpoints in the URL. |
schemas | SCIM schema | true | Value required as part of SCIM protocol. Value should always be:
|
externalId | String | true | Field used for audit and reference. Will not be displayed in Tonkean. Can be used for custom group id. |
displayName | String | true | Full name to use as the group name in the Tonkean app. |
members | JSON Array | true | Array of JSON elements containing the list of members in the group. NOTE:Can’t be set on CREATE; only on update. |
projectId | Tonkean Id | false | The ID of the Tonkean board associated to this group. Only returned from Tonkean, not input. |
Provision / Create Group
Create a new group in Tonkean.
POST: {BASE_URL}/Groups (for example, https://api.tonkean.com/scim/v2/Groups)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
Request Example
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins",
"externalId": "custom_id"
}
Response Example
{
"id": "SCGRospWarMpa73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins",
"externalId": "custom_id",
"meta": {
"resourceType": "Group"
},
"projectId": "PROJlYbHeXURWb2",
"members": []
}
Add Member to Group
Add a user as a member of a specified group.
PATCH: {BASE_URL}/Groups/{TonkeanGroupId} (for example, https://api.tonkean.com/scim/v2/Groups/SCGRospWarMpa73)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
Request Example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "add",
"path": "members",
"value": [
{
"value": "PRSNyR6viFqBO73"
}
]
}
]
}
Response Example
{
"id": "SCGRospWarMpa73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins",
"externalId": "custom_id",
"meta": {
"resourceType": "Group"
},
"projectId": "PROJlYbHeXURWb2",
"members": [
{
"value": "PRSNyR6viFqBO73"
}
]
}
Remove Member from Group
Remove a user from a specified group.
PATCH: {BASE_URL}/Groups/{TonkeanGroupId} (for example, https://api.tonkean.com/scim/v2/Groups/SCGRospWarMpa73)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
Request Example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "remove",
"path": "members",
"value": [
{
"value": "PRSNyR6viFqBO73"
}
]
}
]
}
Response Example
{
"id": "SCGRospWarMpa73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins",
"externalId": "custom_id",
"meta": {
"resourceType": "Group"
},
"projectId": "PROJlYbHeXURWb2",
"members": []
}
Set List of Members in a Group
Set the list of members in an existing group in Tonkean.
PATCH: {BASE_URL}/Groups/{TonkeanGroupId} (for example, https://api.tonkean.com/scim/v2/Groups/SCGRospWarMpa73)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
Request Example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "replace",
"path": "members",
"value": [
{
"value": "PRSNyR6viFqBO73"
}
]
}
]
}
Response Example
{
"id": "SCGRospWarMpa73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins",
"externalId": "custom_id",
"meta": {
"resourceType": "Group"
},
"projectId": "PROJlYbHeXURWb2",
"members": [
{
"value": "PRSNyR6viFqBO73"
}
]
}
Update Group Name
Update the display-name of an existing group in Tonkean.
PATCH: {BASE_URL}/Groups/{TonkeanGroupId} (for example, https://api.tonkean.com/scim/v2/Groups/SCGRospWarMpa73)
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
Request Example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "replace",
"path": "displayName",
"value": "My Admins 123"
}
]
}
Response Example
{
"id": "SCGRospWarMpa73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins 123",
"externalId": "custom_id",
"meta": {
"resourceType": "Group"
},
"projectId": "PROJlYbHeXURWb2",
"members": []
}
Delete / Deprovision Group
Remove a group in Tonkean.
DELETE: {BASE_URL}/Groups/{TonkeanGroupID} (for example, https://api.tonkean.com/scim/v2/Groups/SCGRospWarMpa73)
Authorization: Bearer {ACCESS_TOKEN}
Request Example
—
Response Example
204 No Content
Get Groups
Get existing groups in Tonkean.
GET: {BASE_URL}/Groups/
Authorization: Bearer {ACCESS_TOKEN}
Query Params:
Param Name | Default | Description |
|---|---|---|
startIndex | 1 | Index to start listing users from. |
count | 100 | Amount of items to return in the call. |
filter | — | Only supported filter: |
Request Example
—
Response Example
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"totalResults": 3,
"startIndex": 1,
"itemsPerPage": 100,
"Resources": [
{...},
{...},
]
}
Get Group by Tonkean ID
Get user details in Tonkean based on tonkean Id (for example, SCGRxxxyyyzzz).
GET: {BASE_URL}/Groups/{TonkeanUserID} (for example, https://api.tonkean.com/scim/v2/Groups/SCGRCmyuSxtya73)
Authorization: Bearer {ACCESS_TOKEN}
Request Example
—
Response Example
{
"id": "SCGRCmyuSxtya73",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"displayName": "My Admins 111",
"externalId": "custom_id 111",
"meta": {
"resourceType": "Group"
},
"projectId": "PROJlYbHeXURWb2",
"members": []
}
Bulk Operations
Instead of sending multiple calls in series, you can use bulk operations to perform multiple SCIM operations in a single call using RFC 7644 §3.7. Bulk operations are helpful for various use cases:
Provisioning many new users or user groups at once
Updating a large number of profiles (such as when a department changes)
Syncing groups in bulk
Bulk operations enable you to make fewer API calls and have a lower chance of encountering rate limits or performance issues.
Bulk Operation Endpoint
POST /scim/v2/Bulk
Property | Value |
|---|---|
Method | POST |
Content-Type |
|
Auth | Required |
Base URLs:
Prod: https://api.tonkean.com/scim/v2
EU: https://api.eu.tonkean.com/scim/v2
Bulk Operation Request
Top-level fields:
schemas: Must contain
urn:ietf:params:scim:api:messages:2.0:BulkRequestOperations: Non-empty array of operation objects (max 100 - configurable)
failOnErrors (optional): Stop after N errors
The request example below contains a mix of successful and unsuccessful operations.
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
"failOnErrors": 5,
"Operations": [
// 1. SUCCESSFUL: Create user
{
"method": "POST",
"bulkId": "newUser1",
"path": "/Users",
"data": {
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "alice.johnson@example.com",
"name": {
"givenName": "Alice",
"familyName": "Johnson"
},
"emails": [
{
"value": "alice.johnson@example.com",
"primary": true
}
],
"active": true
}
},
// 2. FAILED: Update non-existent user (404)
{
"method": "PUT",
"bulkId": "updateUser1",
"path": "/Users/PRSN999999",
"data": {
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "notfound@example.com",
"name": {
"givenName": "Not",
"familyName": "Found"
},
"emails": [
{
"value": "notfound@example.com",
"primary": true
}
],
"active": true
}
}
]
}
Bulk Operation Response Example
For bulk operations, note that a 200 OK at the HTTP level means that the bulk process was successful (even if some ops failed).
The below response example contains a mix of successful and failed operations:
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkResponse"],
"Operations": [
{
"method": "POST",
"bulkId": "newUser1",
"status": "201",
"location": "https://api.tonkean.com/scim/v2/Users/PRSN123456"
},
{
"method": "PUT",
"bulkId": "updateUser1",
"status": "404",
"location": "https://api.tonkean.com/scim/v2/Users/PRSN999999",
"response": {
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"status": "404",
"scimType": "noTarget",
"detail": "SCIM User with id [PRSN999999] wasn't found for project id [PRJ123]."
}
}
]
}Supported Operation Types
Tonkean's SCIM endpoint supports the following operations:
POST
Creates a new user or group.
bulkIdis optional but required for references.Responds
201 Createdor200 OK(upsert mode).
{
"method": "POST",
"path": "/Users",
"bulkId": "user1",
"data": { "userName": "alice@example.com" }
}
PUT
Replaces an entire user record.
{
"method": "PUT",
"path": "/Users/PRSN123",
"data": { "displayName": "Updated Name" }
}
PATCH
Partially updates a record (users or groups).
{
"method": "PATCH",
"path": "/Users/PRSN123",
"data": {
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "replace", "path": "active", "value": false }
]
}
}
DELETE
Removes a user or group.
{
"method": "DELETE",
"path": "/Users/PRSN123"
}