SCIM 2.0 API Reference

Base URL: https://auth.calimatic.com/api/v1/scim/v2

System for Cross-domain Identity Management (SCIM) 2.0 endpoints for automated user provisioning and deprovisioning.


Prerequisites

  • An organization on an Enterprise plan (SCIM is a plan-gated feature; gating is enforced by the calling app)
  • Either an org-scoped API key for that organization (preferred for customer IdP callers) or app-client credentials with the target org passed as ?org=<orgId>
  • An identity provider that supports SCIM 2.0 (e.g., Azure AD / Entra ID, Okta, OneLogin, JumpCloud)

Overview

SCIM provides a standardized protocol for identity providers to automatically:

  • Create users when they are assigned to your application in the IdP
  • Update user profiles when changes are made in the IdP
  • Deactivate users when they are unassigned or removed from the IdP
  • Manage groups for role-based access control

Supported SCIM Endpoints

MethodEndpointDescription
GET/scim/v2/ServiceProviderConfigSCIM service provider capabilities
GET/scim/v2/SchemasSupported SCIM schemas
GET/scim/v2/ResourceTypesAvailable resource types
GET/scim/v2/UsersList/search users
GET/scim/v2/Users/{id}Get a single user
POST/scim/v2/UsersCreate a user
PUT/scim/v2/Users/{id}Replace a user
PATCH/scim/v2/Users/{id}Update specific user attributes
DELETE/scim/v2/Users/{id}Delete a user
GET/scim/v2/GroupsList/search groups
GET/scim/v2/Groups/{id}Get a single group
POST/scim/v2/GroupsCreate a group
PUT/scim/v2/Groups/{id}Replace a group
PATCH/scim/v2/Groups/{id}Update group membership
DELETE/scim/v2/Groups/{id}Delete a group

Groups note: SCIM Groups map to Calimatic organizations. Because a tenant-scoped caller only has visibility into a single org, GET /Groups returns exactly one row (the caller's own org) and GET /Groups/{id} returns 404 for any id other than the caller's own org id. POST /Groups is not supported (501) — organizations are provisioned through the platform admin API, not by a customer's IdP.


Authentication and Tenant Scoping

Every SCIM data request is scoped to exactly one organization. The tenant is derived from the caller and cannot be widened by query params. Reads never return data from other orgs; writes reject targets in other orgs with 404 Not Found.

Three ways to authenticate:

MethodHeader(s)Tenant Resolution
Bearer token (API key)Authorization: Bearer <api_key>Org is derived from the API key. If ?org= is also present and it doesn't match, request is rejected 403.
x-api-key headerx-api-key: <api_key>Same as Bearer.
App-client credentialsx-client-id: cca_... + x-client-secret: ccas_...?org=<orgId> is required on every request. 400 if missing.

Recommended shape for a customer's own IdP connecting to Calimatic: issue an org-scoped API key from the org's admin dashboard and hand it to the IdP. The tenant scope is then baked into the credential and can't be tampered with by URL manipulation.

App-client credentials are the shape a Calimatic app uses when calling SCIM on behalf of one of its customers (e.g. the org-admin UI in the app makes a SCIM read/write). The app passes ?org=<orgId> for the customer it's acting on.

Obtaining an org-scoped API key

Three shapes, pick whichever matches the caller:

  • Platform UI: Developer → API Keys → Create key (session must belong to the target org).
  • Session-authed API: POST /api/v1/api-keys — org is derived from the session; returns the raw key once.
  • App-client-authed API (server-side proxy): POST /api/v1/api-keys?org=<orgId> with x-client-id + x-client-secret. Requires org:users:manage on the app-client. This is the shape a Calimatic app uses when rendering a "Generate SCIM key" button in its own admin UI on behalf of a customer's org admin.

The raw key is only shown in the response body — store it securely on the client side; there is no way to retrieve it later. userIdentityId on the resulting key is null when issued by an app-client; the audit log records the app-client attribution separately.

Breaking change (2026-09)

Prior to this update, SCIM endpoints did not enforce per-tenant scoping — a caller with any valid credential could read/write users across all organizations. That surface has been closed. If you had callers relying on cross-tenant reads, they must now iterate one call per org (using either an org-scoped key per org, or app-client credentials with the appropriate ?org= per call).


ServiceProviderConfig

GET /scim/v2/ServiceProviderConfig

Returns the SCIM service provider configuration document describing supported features.

Response

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
  "documentationUri": "https://auth.calimatic.com/docs/api-reference/scim",
  "patch": { "supported": true },
  "bulk": { "supported": false, "maxOperations": 0, "maxPayloadSize": 0 },
  "filter": { "supported": true, "maxResults": 100 },
  "changePassword": { "supported": false },
  "sort": { "supported": false },
  "etag": { "supported": false },
  "authenticationSchemes": [
    {
      "type": "oauthbearertoken",
      "name": "OAuth Bearer Token",
      "description": "Authentication using a Bearer token",
      "specUri": "https://tools.ietf.org/html/rfc6750"
    }
  ]
}

Schemas

GET /scim/v2/Schemas

Returns the list of supported SCIM schemas.


ResourceTypes

GET /scim/v2/ResourceTypes

Returns the resource types supported by this SCIM server (Users and Groups).


Users

User Schema Mapping

SCIM AttributeCalimatic Auth FieldTypeRequired
userNameemailstringYes
name.givenNamefirstNamestringYes
name.familyNamelastNamestringYes
name.formatteddisplayNamestringNo
emails[0].valueemailstringYes
emails[0].primary--booleanNo
activestatus (active/deactivated)booleanNo
externalIdexternalId (metadata)stringNo
displayNamedisplayNamestringNo
phoneNumbers[0].valuephonestringNo
localelocalestringNo
timezonetimezonestringNo
photos[0].valueavatarUrlstringNo

List Users

GET /scim/v2/Users

Query Parameters

ParameterTypeDescription
filterstringSCIM filter expression (e.g., userName eq "jane@example.com")
startIndexnumber1-based starting index for pagination (default: 1)
countnumberNumber of results per page (default: 20, max: 100)

Supported Filter Operators

OperatorExample
equserName eq "jane@example.com"
coname.familyName co "Smi"
swuserName sw "jane"
andactive eq true and name.familyName eq "Smith"

Example Request

curl "https://auth.calimatic.com/scim/v2/Users?filter=userName%20eq%20%22jane%40example.com%22&count=10" \
  -H "Authorization: Bearer scim_your_token"

Response

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
  "totalResults": 1,
  "startIndex": 1,
  "itemsPerPage": 10,
  "Resources": [
    {
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
      "id": "f1g2h3i4-j5k6-7890-lmno-pq1234567890",
      "externalId": "usr_12345",
      "userName": "jane@example.com",
      "name": {
        "givenName": "Jane",
        "familyName": "Smith",
        "formatted": "Jane Smith"
      },
      "displayName": "Jane Smith",
      "emails": [
        {
          "value": "jane@example.com",
          "type": "work",
          "primary": true
        }
      ],
      "active": true,
      "meta": {
        "resourceType": "User",
        "created": "2025-01-10T10:00:00.000Z",
        "lastModified": "2025-01-15T14:30:00.000Z",
        "location": "https://auth.calimatic.com/scim/v2/Users/f1g2h3i4-j5k6-7890-lmno-pq1234567890"
      }
    }
  ]
}

Get a Single User

GET /scim/v2/Users/{id}

Returns the full SCIM User resource.

Create a User

POST /scim/v2/Users
Content-Type: application/scim+json

Example Request

curl -X POST https://auth.calimatic.com/scim/v2/Users \
  -H "Authorization: Bearer scim_your_token" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "userName": "bob@example.com",
    "name": {
      "givenName": "Bob",
      "familyName": "Jones"
    },
    "emails": [
      {
        "value": "bob@example.com",
        "type": "work",
        "primary": true
      }
    ],
    "active": true,
    "externalId": "okta_user_12345"
  }'

Response (201 Created)

Returns the created SCIM User resource with the id assigned by Calimatic Auth.

Replace a User

PUT /scim/v2/Users/{id}
Content-Type: application/scim+json

Replaces all user attributes with the provided values. Attributes not included are cleared to defaults.

Update a User (PATCH)

PATCH /scim/v2/Users/{id}
Content-Type: application/scim+json

Update specific attributes without replacing the entire resource.

Example: Deactivate a User

curl -X PATCH https://auth.calimatic.com/scim/v2/Users/f1g2h3i4-j5k6-7890 \
  -H "Authorization: Bearer scim_your_token" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
      {
        "op": "Replace",
        "path": "active",
        "value": false
      }
    ]
  }'

Example: Update Name

curl -X PATCH https://auth.calimatic.com/scim/v2/Users/f1g2h3i4-j5k6-7890 \
  -H "Authorization: Bearer scim_your_token" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
      {
        "op": "Replace",
        "path": "name.givenName",
        "value": "Janet"
      }
    ]
  }'

Delete a User

DELETE /scim/v2/Users/{id}

Deactivates the user in Calimatic Auth. Returns 204 No Content.


Groups

SCIM Groups map to roles within a Calimatic organization. Assigning a user to a SCIM Group grants them the corresponding role.

List Groups

GET /scim/v2/Groups

Query Parameters

ParameterTypeDescription
filterstringSCIM filter (e.g., displayName eq "Admins")
startIndexnumber1-based start index
countnumberResults per page

Example Response

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
  "totalResults": 3,
  "Resources": [
    {
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
      "id": "grp-uuid-...",
      "displayName": "Admins",
      "members": [
        { "value": "user-uuid-1", "display": "Jane Smith" },
        { "value": "user-uuid-2", "display": "Bob Jones" }
      ],
      "meta": {
        "resourceType": "Group",
        "created": "2025-01-10T10:00:00.000Z",
        "lastModified": "2025-01-15T14:30:00.000Z"
      }
    }
  ]
}

Update Group Membership (PATCH)

PATCH /scim/v2/Groups/{id}
Content-Type: application/scim+json

Example: Add a Member

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "Add",
      "path": "members",
      "value": [
        { "value": "user-uuid-..." }
      ]
    }
  ]
}

Example: Remove a Member

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "Remove",
      "path": "members[value eq \"user-uuid-...\"]"
    }
  ]
}

Error Responses

SCIM errors follow the standard SCIM error schema:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
  "status": "404",
  "detail": "User not found"
}

Status Codes

StatusDescription
200Success (GET, PATCH, PUT)
201Created (POST)
204No Content (DELETE)
400Bad request (invalid filter, missing required fields)
401Unauthorized (missing or invalid Bearer token)
404Resource not found
409Conflict (user with this email already exists)
429Rate limit exceeded
500Internal server error

Configuring Your Identity Provider

Azure AD / Entra ID

  1. Go to Enterprise Applications > Your App > Provisioning
  2. Set Provisioning Mode to Automatic
  3. Enter:
    • Tenant URL: https://auth.calimatic.com/scim/v2
    • Secret Token: Your SCIM Bearer token
  4. Click Test Connection
  5. Configure attribute mappings (see User Schema Mapping)
  6. Enable provisioning

Okta

  1. Go to Applications > Your App > Provisioning > Integration
  2. Enable SCIM connector
  3. Enter:
    • SCIM connector base URL: https://auth.calimatic.com/scim/v2
    • Authentication Mode: HTTP Header
    • Authorization: Bearer scim_your_token
  4. Configure supported operations (Create, Update, Deactivate)
  5. Configure attribute mappings

OneLogin

  1. Go to Applications > Your App > Provisioning
  2. Enable provisioning
  3. Enter the SCIM base URL and Bearer token
  4. Map attributes as needed

Rate Limits

EndpointLimitWindow
All SCIM endpoints60 requests1 minute per token

When rate limited, the response includes a Retry-After header.