Skip to content

API Reference: SCIM Provisioning

Note: See API Reference — Batch 13 for the current SCIM provisioning API documentation.

Base path: /api/scim/v2

Arbitex implements SCIM 2.0 (RFC 7643/7644) for automated user and group lifecycle management. Identity providers (Okta, Azure Active Directory, JumpCloud, etc.) can provision, update, and deprovision users and groups automatically.

Authentication: All SCIM endpoints use a long-lived SCIM bearer token (not a user session token). Generate this token from the admin console or via the provisioning API.


POST /api/v1/admin/scim/token
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"description": "Okta SCIM provisioner",
"expires_at": null
}

Response 201 Created:

{
"token_id": "scim_tok_01HXYZ",
"token": "scim_01HXYZ...",
"description": "Okta SCIM provisioner",
"created_at": "2026-03-12T10:00:00Z",
"expires_at": null,
"note": "Store this token securely — it will not be shown again."
}
GET /api/v1/admin/scim/tokens
Authorization: Bearer <admin-token>
{
"tokens": [
{
"token_id": "scim_tok_01HXYZ",
"description": "Okta SCIM provisioner",
"created_at": "2026-03-12T10:00:00Z",
"last_used_at": "2026-03-12T14:00:00Z",
"expires_at": null
}
]
}
DELETE /api/v1/admin/scim/tokens/{token_id}
Authorization: Bearer <admin-token>

Response 204 No Content.


GET /api/scim/v2/ServiceProviderConfig
Authorization: Bearer <scim-token>

Response:

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
"documentationUri": "https://docs.arbitex.io/reference/api-scim",
"patch": {"supported": true},
"bulk": {"supported": false, "maxOperations": 0, "maxPayloadSize": 0},
"filter": {"supported": true, "maxResults": 200},
"changePassword": {"supported": false},
"sort": {"supported": false},
"etag": {"supported": false},
"authenticationSchemes": [
{
"name": "OAuth Bearer Token",
"description": "Authentication scheme using OAuth Bearer Token",
"type": "oauthbearertoken",
"primary": true
}
],
"meta": {
"resourceType": "ServiceProviderConfig",
"location": "https://api.arbitex.example.com/api/scim/v2/ServiceProviderConfig"
}
}

GET /api/scim/v2/Users
Authorization: Bearer <scim-token>

Query parameters:

Parameter Type Description
filter string SCIM filter expression, e.g. userName eq "[email protected]"
startIndex integer 1-based pagination start (default: 1)
count integer Max results per page (default: 100, max: 200)

Supported filter attributes: userName, emails, active, externalId

Response:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 250,
"startIndex": 1,
"itemsPerPage": 100,
"Resources": [
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "usr_01HXYZ",
"externalId": "okta_00u1...",
"userName": "[email protected]",
"name": {
"formatted": "Alice Smith",
"familyName": "Smith",
"givenName": "Alice"
},
"emails": [{"value": "[email protected]", "primary": true}],
"active": true,
"groups": [
{"value": "grp_01HXYZ", "display": "Engineering"}
],
"meta": {
"resourceType": "User",
"created": "2026-01-15T10:00:00Z",
"lastModified": "2026-03-01T09:00:00Z",
"location": "https://api.arbitex.example.com/api/scim/v2/Users/usr_01HXYZ"
}
}
]
}
GET /api/scim/v2/Users/{id}
Authorization: Bearer <scim-token>

Returns a single User resource. 404 if not found.

POST /api/scim/v2/Users
Authorization: Bearer <scim-token>
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"externalId": "okta_00u1...",
"userName": "[email protected]",
"name": {
"familyName": "Jones",
"givenName": "Bob"
},
"emails": [{"value": "[email protected]", "primary": true}],
"active": true
}

Response 201 Created: Full User resource with generated id.

If userName already exists, returns 409 Conflict:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"status": "409",
"detail": "User with userName '[email protected]' already exists.",
"scimType": "uniqueness"
}
PUT /api/scim/v2/Users/{id}
Authorization: Bearer <scim-token>
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "usr_01HXYZ",
"externalId": "okta_00u1...",
"userName": "[email protected]",
"name": {"familyName": "Smith", "givenName": "Alice"},
"emails": [{"value": "[email protected]", "primary": true}],
"active": true
}

Response 200 OK: Updated User resource.

PATCH /api/scim/v2/Users/{id}
Authorization: Bearer <scim-token>
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{"op": "replace", "path": "active", "value": false},
{"op": "replace", "path": "name.givenName", "value": "Alicia"}
]
}

Supported op values: add, replace, remove

Deprovisioning a user (set active: false):

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{"op": "replace", "path": "active", "value": false}
]
}

Deprovisioned users have their sessions revoked and API keys suspended. The user record is retained for audit purposes.

DELETE /api/scim/v2/Users/{id}
Authorization: Bearer <scim-token>

Response 204 No Content.

Hard-deletes the user. Sessions and API keys are immediately revoked. Audit log entries are anonymized per retention policy. This is irreversible — prefer active: false PATCH for soft deprovisioning.


GET /api/scim/v2/Groups
Authorization: Bearer <scim-token>

Query parameters: filter, startIndex, count (same as Users)

Supported filter attributes: displayName, externalId

Response:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 12,
"startIndex": 1,
"itemsPerPage": 100,
"Resources": [
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"id": "grp_01HXYZ",
"externalId": "okta_00g1...",
"displayName": "Engineering",
"members": [
{"value": "usr_01HXYZ", "display": "Alice Smith"},
{"value": "usr_02HXYZ", "display": "Bob Jones"}
],
"meta": {
"resourceType": "Group",
"created": "2026-01-15T10:00:00Z",
"lastModified": "2026-03-01T09:00:00Z",
"location": "https://api.arbitex.example.com/api/scim/v2/Groups/grp_01HXYZ"
}
}
]
}
GET /api/scim/v2/Groups/{id}
Authorization: Bearer <scim-token>
POST /api/scim/v2/Groups
Authorization: Bearer <scim-token>
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"externalId": "okta_00g1...",
"displayName": "Data Science",
"members": [
{"value": "usr_01HXYZ"}
]
}

Response 201 Created: Full Group resource.

Update Group (PATCH — Add/Remove Members)

Section titled “Update Group (PATCH — Add/Remove Members)”
PATCH /api/scim/v2/Groups/{id}
Authorization: Bearer <scim-token>
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "add",
"path": "members",
"value": [{"value": "usr_03HXYZ"}]
},
{
"op": "remove",
"path": "members[value eq \"usr_01HXYZ\"]"
}
]
}
DELETE /api/scim/v2/Groups/{id}
Authorization: Bearer <scim-token>

Response 204 No Content.

Group members are not deleted — only the group is removed. DLP overrides and model access rules tied to the group are also removed.


In Okta:

  1. Application → Provisioning → Integration → API Authentication

    • SCIM connector base URL: https://api.arbitex.example.com/api/scim/v2
    • Authentication mode: HTTP Header
    • Authorization: Bearer <scim-token>
  2. Enable provisioning features:

    • Push New Users: ✓
    • Push Profile Updates: ✓
    • Push Groups: ✓
    • Deactivate Users: ✓ (sets active: false)
  3. Attribute mapping (Okta → SCIM):

    Okta Attribute SCIM Attribute
    login userName
    firstName name.givenName
    lastName name.familyName
    email emails[primary eq true].value
    appuser.externalId externalId
  1. Enterprise Application → Provisioning → Automatic

    • Tenant URL: https://api.arbitex.example.com/api/scim/v2
    • Secret Token: <scim-token>
  2. Attribute mapping → User:

    • userPrincipalName → userName
    • mail → emails[type eq "work"].value
    • displayName → name.formatted
  3. Scope: Assign to all users or specific groups as needed.


Status SCIM Error Type Description
400 invalidFilter Unsupported filter syntax
400 invalidValue Field value failed validation
401 — Missing or invalid SCIM token
403 — Operation not permitted
404 — Resource not found
409 uniqueness Username or externalId conflict

All errors follow the SCIM error schema:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"status": "400",
"scimType": "invalidFilter",
"detail": "Filter attribute 'nickname' is not supported."
}