Beta

Create a tenant

A new tenant starts with its own users, OAuth settings, audit history and logs. You are its first Tenant Admin.

BTL Admin

SCIM provisioning in your tenant

SCIM lets a system of record, such as an HR system, create, update and remove your tenant's users and groups as people join, move and leave.

This page is a console for your tenant's SCIM 2.0 API. Connect a provisioning client, get an access token, then work through every method in order: discovery, users, groups, bulk requests and clean-up. Each step shows the exact request and the response your tenant returned, and fills in the ids and versions the next step needs.

Connect to your tenant

Requests on this page are real. They go from your browser straight to your tenant, change its users and groups, and appear in its Audit and Logs. The client secret and access token stay in this page's memory and are gone when you leave it.

Your tenant's address, shown on its Provisioning page. Choosing a tenant above fills it in.

The steps below need the full scope. A narrower scope shows which requests it refuses.

No access token yet.

Create a provisioning client for me

Creates a confidential client in the tenant you chose. It may use only the client credentials grant, holds the SCIM scopes you pick, and gets a new secret, which is filled in above. You can manage or delete it on the tenant's Clients page.

Sign in with a BTL account that can create OAuth clients and their secrets in a tenant to do this in one step. Otherwise create the client by hand: allow the client credentials grant in Flow policy, create a confidential client with that grant, assign it a SCIM scope, and generate its secret.

POST/oauth/token 1. Get an access tokenNot sent

The client signs in with its ID and secret using the client credentials grant and asks for one SCIM scope. The access token it receives goes in the Authorization: Bearer header of every SCIM request until it expires.

POST /oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=scim-<id>

Discover what the API supports

A SCIM client usually starts by reading what the service supports and the attributes it stores. Any SCIM scope can read these documents.

GET/ServiceProviderConfig 2. Read the service configurationNot sent

Which optional SCIM features this service supports: PATCH, Bulk with its limits, filtering with its maximum results, sorting, ETags and password changes, and how to authenticate.

Scopes: any SCIM scope (scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups, scim-<id>.passwords)

GET/ResourceTypes 3. List resource typesNot sent

The kinds of resources this service manages, User and Group, with each one's endpoint and schemas.

Scopes: any SCIM scope (scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups, scim-<id>.passwords)

GET/ResourceTypes/{id} 4. Read one resource typeNot sent

One resource type. The User type lists the enterprise extension, which carries employee number, department and manager.

Scopes: any SCIM scope (scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups, scim-<id>.passwords)

Parameters

User or Group.

GET/Schemas 5. List schemasNot sent

Every attribute this tenant stores, with its type, whether it is required, and whether it can be changed. Attributes the tenant does not store are left out, so a client can see exactly what persists.

Scopes: any SCIM scope (scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups, scim-<id>.passwords)

GET/Schemas/{id} 6. Read one schemaNot sent

One schema by its URN.

Scopes: any SCIM scope (scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups, scim-<id>.passwords)

Parameters

The schema URN.

Users

Create a user, read it back, find it, then change it. Each step fills in the id and version from the one before it.

POST/Users 7. Create a userNot sent

A user needs a userName, a given and family name, and a work email. userName, externalId and email must be unique in the tenant. The response is 201 with the new user, its id, and its version in the ETag header. Add a password only when the tenant accepts passwords over SCIM and the client holds the passwords scope.

Scopes: scim-<id>, scim-<id>.users

Parameters

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

GET/Users/{id} 8. Read a userNot sent

One user by id. The password is never returned.

Scopes: scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups

Parameters

Filled in from the user you created. You can paste another user id.

Comma-separated attributes to return, such as userName,emails. id and schemas are always returned.

Comma-separated attributes to leave out.

Paste the ETag you last read to get 304 Not Modified when nothing changed.

GET/Users 9. List and filter usersNot sent

Users that match a filter, a page at a time. totalResults counts every match; Resources holds this page.

Scopes: scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups

Parameters

A SCIM filter, such as userName eq "[email protected]" or emails[type eq "work" and value co "@example.com"]. Operators: eq, ne, co, sw, ew, gt, ge, lt, le, pr, and, or, not.

The 1-based position of the first result.

Results per page, up to 200. The default is 50.

The attribute to sort by.

ascending (the default) or descending.

Comma-separated attributes to return, such as userName,emails. id and schemas are always returned.

Comma-separated attributes to leave out.

POST/Users/.search 10. Search users with a request bodyNot sent

The same search as listing, with the parameters in the body. Use it when a filter is too long or too sensitive for a URL.

Scopes: scim-<id>, scim-<id>.read, scim-<id>.users, scim-<id>.groups

PATCH/Users/{id} 11. Update part of a userNot sent

Changes only the attributes named in the operations. Setting active to false locks the user and ends their sessions and tokens. The response has the updated user and its new ETag.

Scopes: scim-<id>, scim-<id>.users

Parameters

Filled in from the user you created. You can paste another user id.

The version (ETag) you last read. If the record changed since then, the request is refused with 412 instead of overwriting the newer change. Clear it to skip the check.

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

PUT/Users/{id} 12. Replace a userNot sent

Replaces every attribute with the body. Attributes left out are cleared. This example also sets active back to true, which unlocks the user.

Scopes: scim-<id>, scim-<id>.users

Parameters

Filled in from the user you created. You can paste another user id.

The version (ETag) you last read. If the record changed since then, the request is refused with 412 instead of overwriting the newer change. Clear it to skip the check.

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

Groups

Groups hold tenant users, for example by department. They carry no permissions. These steps use the user you created above as a member.

POST/Groups 13. Create a groupNot sent

A group needs a displayName that is unique in the tenant. Members are user ids; groups cannot contain groups.

Scopes: scim-<id>, scim-<id>.groups

Parameters

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

GET/Groups/{id} 14. Read a groupNot sent

One group with its members.

Scopes: scim-<id>, scim-<id>.read, scim-<id>.groups

Parameters

Filled in from the group you created. You can paste another group id.

Comma-separated attributes to return, such as userName,emails. id and schemas are always returned.

Comma-separated attributes to leave out.

GET/Groups 15. List and filter groupsNot sent

Groups that match a filter. Add members to excludedAttributes to keep large groups out of the response.

Scopes: scim-<id>, scim-<id>.read, scim-<id>.groups

Parameters

A SCIM filter, such as userName eq "[email protected]" or emails[type eq "work" and value co "@example.com"]. Operators: eq, ne, co, sw, ew, gt, ge, lt, le, pr, and, or, not.

The 1-based position of the first result.

Results per page, up to 200. The default is 50.

The attribute to sort by.

ascending (the default) or descending.

Comma-separated attributes to return, such as userName,emails. id and schemas are always returned.

Comma-separated attributes to leave out.

POST/Groups/.search 16. Search groups with a request bodyNot sent

The same search as listing, with the parameters in the body.

Scopes: scim-<id>, scim-<id>.read, scim-<id>.groups

PATCH/Groups/{id} 17. Change a group's membersNot sent

Adds and removes members without sending the whole list, which keeps large groups cheap to change. A remove whose filter matches no member is refused with noTarget.

Scopes: scim-<id>, scim-<id>.groups

Parameters

Filled in from the group you created. You can paste another group id.

The version (ETag) you last read. If the record changed since then, the request is refused with 412 instead of overwriting the newer change. Clear it to skip the check.

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

PUT/Groups/{id} 18. Replace a groupNot sent

Replaces the name, externalId and the whole member list with the body.

Scopes: scim-<id>, scim-<id>.groups

Parameters

Filled in from the group you created. You can paste another group id.

The version (ETag) you last read. If the record changed since then, the request is refused with 412 instead of overwriting the newer change. Clear it to skip the check.

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

Bulk requests

Bulk sends several operations in one request. Later operations can refer to resources created earlier in the same request by their bulkId.

POST/Bulk 19. Send several operations at onceNot sent

Up to 100 operations run in order, each with its own result and audit record. This example creates a user and a group, changes the user, then deletes both, so it leaves nothing behind. failOnErrors stops after that many errors.

Scopes: scim-<id>

Parameters

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

Clean up

Delete the group and the user you created, so your tenant is as it was.

DELETE/Groups/{id} 20. Delete a groupNot sent

Deletes the group. Its members stay in the tenant. The response is 204 with no body.

Scopes: scim-<id>, scim-<id>.groups

Parameters

Filled in from the group you created. You can paste another group id.

The version (ETag) you last read. If the record changed since then, the request is refused with 412 instead of overwriting the newer change. Clear it to skip the check.

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

DELETE/Users/{id} 21. Delete a userNot sent

Deletes the user, ends their access, and frees their userName and externalId for a rehire. To keep a user but stop their access, set active to false instead.

Scopes: scim-<id>, scim-<id>.users

Parameters

Filled in from the user you created. You can paste another user id.

The version (ETag) you last read. If the record changed since then, the request is refused with 412 instead of overwriting the newer change. Clear it to skip the check.

A new UUID for each request. Search for it in Audit to find this change. Repeating a create with the same value returns the first result instead of a duplicate.

Built-in scopes

Every tenant has five SCIM scopes named after the first six characters of its tenant ID. They cannot be deleted, and they are always exclusive: a client can request one only after you assign it. Removing an assignment or disabling the client stops its SCIM access at once, even for tokens it already holds.

SCIM scopes, using an example tenant
ScopeAllows
scim-3f9a1cEverything below.
scim-3f9a1c.readDiscovery and reading users and groups.
scim-3f9a1c.usersCreating, updating, locking, unlocking and deleting users.
scim-3f9a1c.groupsCreating, updating and deleting groups and their members.
scim-3f9a1c.passwordsSetting user passwords, together with the users scope.

No SCIM scope assigns management roles, changes tenant settings or reads Audit and Logs.

Users and passwords

The enterprise extension stores the employee number, cost center, organization, division, department and manager. Attributes the tenant does not store are ignored. A user who holds tenant management roles cannot be changed over SCIM; an administrator manages them in the portal.

Setting active to false locks the user and ends their sessions and tokens; true unlocks them. DELETE removes the user and frees the userName and externalId for a rehire. A password must meet the tenant's password rules; it is stored as a hash and never returned.

Custom schemas

The Schemas page under User Management adds your own extension schemas. Each has a URN you choose, such as urn:example:hr:2.0:User, and attributes of type string, boolean, integer, decimal or dateTime. An attribute can take several values (up to 20), and you choose whether it is required, case-sensitive, unique in the tenant, set once, and returned in every response or only when a client asks for it with attributes. Text attributes can also have a maximum length and a list of allowed values.

Clients send the values under the schema URN, exactly like the enterprise extension: "urn:example:hr:2.0:User": {"badge": "B-100", "skills": ["Go", "SQL"]}. /Schemas and /ResourceTypes/User list your schemas, and filters, sorting and PATCH paths accept the full name, such as urn:example:hr:2.0:User:skills[value eq "Go"]. A short name such as badge also works when no standard attribute or other custom attribute uses it. Values that break a rule are refused with 400 and the matching scimType; a value another user already holds in a unique attribute is refused with 409 uniqueness.

An attribute's name, type and whether it takes several values are fixed after creation. Deleting an attribute or a schema removes its stored values from every user and gives those users a new version. Each tenant has its own schemas, up to 10 with 100 attributes in total, shown under Usage and limits. Nested (complex) attributes and extensions for groups are not available.

Settings and limits

The Provisioning page controls whether the API is on, whether it accepts passwords, whether a new user whose email matches a user created by an administrator is refused or linked, which roles provisioned users receive, and lower request and password budgets for the tenant. SCIM requests and password changes each have a tenant-wide budget per minute. A request over budget receives 429 with Retry-After. Browsers also send a preflight check before calling the API from another site, such as this page; those checks have their own small budget and never spend the SCIM budget. All of these budgets appear under Usage and limits on the Overview page.

Only this website can read SCIM and token responses in a browser. Provisioning integrations normally run on a server, where no browser rule applies.

Audit and Logs

SCIM activity appears in the User directory source of Audit and Logs, and clients created on this page appear in the OAuth management source. Each change names the attributes it changed, never their values. Repeated reads and refusals from one client are summarized once a minute with a request count. Search by request ID or correlation ID to find a single request.

The HR Simulator

The HR Simulator, linked from the Provisioning page, acts as an HR system. It uses a client you configure to onboard, update and offboard fictional people through your tenant's SCIM API on a schedule, and shows each request's correlation ID so you can find it in Audit.

We value your privacy

We use cookies and similar technologies to enhance your browsing experience, and analytics to understand our traffic. By clicking "Allow All", you consent to optional analytics. Cookie Policy

Website docs