SCIM provisioning
Sync users and groups from Okta or Entra ID.
With SCIM, your identity provider creates, updates and deactivates the members of your organization, and pushes groups. Okta, Microsoft Entra ID and any SCIM 2.0 client work. A group mapping turns group membership into a workspace role, an org role and a guardrail.
In the console, open Team > Single sign-on for the SCIM base URL and token.
Connect your identity provider
| Setting | Value |
|---|---|
| SCIM base URL | https://demo-api.routerplus.com/scim/v2 |
| Authentication | HTTP header, Bearer token |
| Token | A management key of the organization (tm_mk_...) |
| Unique identifier for users | userName (the email address) |
| Supported actions | Create users, update user attributes, deactivate users, push groups |
- Create a management key with
POST /v1/management-keys. See the management API. Use the key for this connection only. To stop provisioning, disable the key. - The token selects the organization. A user or group id of another organization returns
404. - A missing, wrong, disabled or expired token returns
401. - In Okta, set the user name format to the email address.
- In Entra ID, map
userPrincipalNameormailtouserName.
Users
A SCIM user is a member of the organization.
| Request | What it does |
|---|---|
POST /Users | Adds the member with the org role viewer, or links the existing member with that email. Returns 201. |
GET /Users?filter=userName eq "[email protected]" | Finds a user. startIndex (from 1) and count (at most 200) page through the list. |
GET /Users/:id | Reads one user. |
PUT /Users/:id | Replaces externalId, displayName, name and active. If you leave out active, it keeps its value. |
PATCH /Users/:id | add, replace or remove operations, with or without a path. |
DELETE /Users/:id | Deactivates the member and removes it from every group. Returns 204. |
Rules:
userNameis the member's email. RouterPlus lowercases it and removes a+tag. You cannot changeuserName. For a new email, create a new user.active: falsedisables the member. The member loses access to the organization. Keys bound to the member stop working.- After
DELETE, the user id returns404. RouterPlus keeps the member's history. A laterPOSTwith the same email enables the member again, with a new id. - SCIM can link the org owner. It never deactivates or deletes the owner, and never changes the owner's role. Those requests return
400withscimType: "mutability". activeacceptstrue,false,"True"and"False".- RouterPlus accepts and ignores attributes other than
userName,externalId,displayName,name,activeandemails.emailsmust matchuserName.
Groups
| Request | What it does |
|---|---|
POST /Groups | {displayName, externalId?, members?: [{value: <user id>}]}. Returns 201. |
GET /Groups?filter=displayName eq "Engineering" | Finds a group. excludedAttributes=members leaves out the members. |
GET /Groups/:id | Reads one group. |
PUT /Groups/:id | Replaces displayName, externalId and the member list. |
PATCH /Groups/:id | Adds or removes members, or replaces displayName. |
DELETE /Groups/:id | Deletes the group and its mapping. Returns 204. |
These PATCH forms work:
{"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{"op": "add", "path": "members", "value": [{"value": "<user id>"}]},
{"op": "remove", "path": "members[value eq \"<user id>\"]"},
{"op": "remove", "path": "members", "value": [{"value": "<user id>"}]},
{"op": "replace", "value": {"displayName": "Platform"}}
]}Each member must be a user of the same organization. Otherwise the request returns 400 with scimType: "invalidValue".
Filters
Filters use eq, joined by and.
| Resource | Attributes |
|---|---|
| Users | userName, externalId, id, displayName, active, emails.value, emails[type eq "work"].value |
| Groups | displayName (case is ignored), externalId, id, members[value eq "<user id>"] |
Other operators, or and not return 400 with scimType: "invalidFilter".
Group mappings
A mapping gives each member of a group these values:
workspace_idandworkspace_role(admin,memberorviewer): the member's role in that workspace. Give both or neither.org_role(adminorviewer): the member's org role.guardrail_id: a guardrail assigned to the member.
A mapping needs at least one of the three.
| Route | What it does |
|---|---|
GET /v1/scim/groups | Lists the SCIM groups with their member count and mapping. |
GET /v1/scim/groups/:id/mapping | Reads a group's mapping. Returns 404 when the group has none. |
PUT /v1/scim/groups/:id/mapping | {workspace_id?, workspace_role?, org_role?, guardrail_id?}. Sets the mapping and applies it to the members. |
DELETE /v1/scim/groups/:id/mapping | Removes the mapping and applies the change to the members. |
These routes use management API authentication. They are served under /v1/... and /api/v1/....
How mappings apply:
- Every change applies immediately. Changes include a member that joins or leaves a group, a changed mapping, and a deleted group or user.
- For a member of several mapped groups, the strongest workspace role wins in each workspace. For the org role,
adminwins overviewer. - When several of a member's groups name a guardrail, the group with the lowest id wins. Ids compare as lowercase text.
- When no group grants a value any more, the member gets back the value from before SCIM set it. If someone changed the value by hand after that, SCIM does not change it.
- A member that SCIM added has the org role
viewerwhen no group grants an org role. - A mapping never changes the org owner.
- A deleted guardrail never applies.
Sign-in audit
GET /v1/audit/sign-ins lists the sign-ins and sign-outs of the organization's members, newest first.
| Query | What it does |
|---|---|
since, until | ISO 8601 times. since is inclusive, until is exclusive. |
email | Only this member. |
limit | 1 to 500. Default 100. |
Each row is {at, email, event, source}.
event | Meaning |
|---|---|
sign_in | The member signed in to the console. |
sign_out | The member signed out. |
session_revoked | The session ended for another reason, for example the identity provider ended it. |
source | Meaning |
|---|---|
clerk | Single sign-on. All three events are recorded. |
email_link | An email sign-in link. Only sign_in is recorded. |
Each event has one row for each organization that the person is a member of. Disabled memberships are included.
Errors
Errors use the SCIM error form, with content-type: application/scim+json:
{"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "409", "scimType": "uniqueness", "detail": "a user with this userName exists"}Discovery
GET /ServiceProviderConfig, GET /ResourceTypes and GET /Schemas need no token. RouterPlus supports PATCH and filters. It does not support bulk, sort, ETags or password changes.
For agents: /docs/scim.md and /llms.txt