SCIM 2.0 reference
Technical reference for identity-management teams connecting an IdP (Microsoft Entra ID, SailPoint IdentityIQ, …) to mTime: which SCIM 2.0 attributes and operations mTime supports, and what each one does.
Overview
| Base URL | https://<your mTime host>/api/scim/v2 |
| Standards | RFC 7643 (schema), RFC 7644 (protocol) |
| Authentication | Bearer token: an API key of the workspace’s provisioning service user (see Set up SCIM with Microsoft Entra ID) |
| Media type | application/scim+json |
| Resources | /Users, /Groups |
| Errors | SCIM error responses (RFC 7644 §3.12) |
What SCIM manages, and what it does not
mTime separates the user (login, roles, access) from the employee and their employments:
User → Employee → n Employments
SCIM manages the user: who may sign in, under which name, and with which roles. Employees and employments — org unit, manager, employment terms, working-time norm, start and end dates — are dated data that mTime calculates on, and they come from your HR integration, not from SCIM. A SCIM user is linked to its employee through the externalId (see How users are provisioned).
This is why mTime does not support the Enterprise User Extension: department, manager and employeeNumber are single values without a validity date, while an employee in mTime can hold several dated employments.
Users
Attributes
Schema urn:ietf:params:scim:schemas:core:2.0:User.
| Attribute | Read | Create | Update | Notes |
|---|---|---|---|---|
id | ✅ | — | — | Assigned by mTime, immutable |
externalId | ✅ | ✅ | ✅ | Stable key (e.g. employee number), unique per workspace; a duplicate returns 409 uniqueness. Can be linked to an employee attribute for matching |
userName | ✅ | ✅ | ⚠️ | The user’s email address. Changeable only while the user has not yet activated their invitation |
emails | ✅ | ✅ | ⚠️ | Primary (or first) value is used; same rule as userName. Returned as a single primary email |
name.givenName, name.familyName | ❌ | ✅ | ⚠️ | Combined into the full name — only when both are sent together (in one name object, or both paths in the same PATCH). mTime stores a single full name and never splits it, so a PATCH with only one of them is ignored. On create and PUT, a lone given or family name is used only when there is no name.formatted or displayName. Not returned on read: the name comes back as name.formatted |
name.formatted | ✅ | ✅ | ⚠️ | Full name; takes precedence over given/family name. An update has no visible effect on a user linked to an employee unless the IdP sets employee names — see Which name SCIM sets |
displayName | ✅ | ✅ | ⚠️ | Full name. Same update rule as name.formatted |
active | ✅ | — | ✅ | false suspends the user; true reactivates |
meta.resourceType, meta.location | ✅ | — | — |
Every other Core User attribute (nickName, title, phoneNumbers, addresses, password, …) and the Enterprise User Extension (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User) are not supported: they are ignored on create and update and never returned.
Which name SCIM sets
mTime shows one name for a person: the employee’s name when the user is linked to an employee, otherwise the user’s name.
- A user linked to an employee shows the employee’s name, which your HR integration maintains. By default SCIM does not update an existing employee, so a name sent through SCIM has no visible effect for this user. With Use identity provider names for employee names
turned on, each create,
PUTorPATCHthat carries a name writes it to the linked employee as well — see Using the identity provider’s name for employees. - A user without an employee (such as a draft) shows the user’s own name. SCIM sets it on create and can change it until the person activates their invitation; after that it follows the name on their own mTime account. When a role later creates their employee, the employee starts with this name.
To rename someone who is an employee, change the name in your HR system — or, with that setting turned on, in your IdP.
Operations
| Operation | Supported | Behaviour |
|---|---|---|
POST /Users | ✅ | Creates the user as invited and sends the invitation email. An email is required (emails, or userName when it is an address). Links to an existing employee when one matches; otherwise creates a role-less draft, without an employee or an invitation. 409 if the externalId or the employee is already taken |
GET /Users/{id} | ✅ | |
GET /Users?filter=… | ⚠️ | Only attribute eq "value", on userName or externalId. Other attributes or operators return 400. Combines with paging |
GET /Users (no filter) | ✅ | All users, page by page — see Paging |
PUT /Users/{id} | ✅ | Applies the supported attributes above |
PATCH /Users/{id} | ⚠️ | add and replace on active, userName, emails, displayName, name (object), name.givenName, name.familyName, name.formatted, externalId, or without path (partial resource). A path may carry the schema prefix (urn:ietf:params:scim:schemas:core:2.0:User:name.givenName). remove and other paths are ignored |
DELETE /Users/{id} | ✅ | Deletes the user account (soft delete) and ends all sessions. The employee and their history are kept. Returns 204 |
Users holding the owner role cannot be changed or deleted through SCIM (403).
Deactivate or delete?
PATCH active=false | DELETE | |
|---|---|---|
| Can sign in | No — sessions end immediately | No — sessions end immediately |
| User account | Kept, status suspended | Deleted (soft delete) |
| Employee, time entries, approvals | Kept | Kept |
| Coming back | PATCH active=true restores the same user | A new POST creates a new user, linked to the same employee |
Groups
Groups map to mTime roles: the IdP owns a group’s existence and membership, mTime admins own the role’s permissions. See How groups become roles.
Attributes
Schema urn:ietf:params:scim:schemas:core:2.0:Group.
| Attribute | Read | Create | Update | Notes |
|---|---|---|---|---|
id | ✅ | — | — | Assigned by mTime |
externalId | ✅ | ✅ | ✅ | |
displayName | ✅ | ✅ | ✅ | Binds to the role with the same name, or creates an empty custom role. Renaming renames the role |
members (value, display) | ✅ | ✅ | ✅ | value is the SCIM user id |
Operations
| Operation | Supported | Behaviour |
|---|---|---|
POST /Groups | ✅ | Binds to or creates the role |
GET /Groups/{id} | ✅ | |
GET /Groups?filter=… | ⚠️ | Only attribute eq "value", on displayName or externalId |
GET /Groups (no filter) | ✅ | All IdP-managed roles, page by page — see Paging |
PUT /Groups/{id} | ✅ | Replaces name and members |
PATCH /Groups/{id} | ✅ | add, replace and remove on members (including members[value eq "…"]) and displayName |
DELETE /Groups/{id} | ✅ | Removes the role from its members. The role itself is deleted only if no admin ever configured it |
Paging
GET /Users and GET /Groups support index-based paging (RFC 7644 §3.4.2.4), with or without a filter.
| Parameter | Default | Notes |
|---|---|---|
startIndex | 1 | 1-based position of the first result. Values below 1 count as 1 |
count | 200 | Results per page, at most 200. count=0 returns only totalResults |
The response gives totalResults (all matches), startIndex, and itemsPerPage (the results on this page). Request the next page with startIndex + itemsPerPage until you have totalResults results. Results come in a fixed order, so pages neither skip nor repeat results unless users or groups are added or deleted in between.
Discovery endpoints
All three require the same bearer token as the other SCIM endpoints.
| Endpoint | Content |
|---|---|
GET /ServiceProviderConfig | Capabilities, shown below |
GET /Schemas | Core User and Group schemas, limited to the attributes above |
GET /ResourceTypes | User (/Users) and Group (/Groups), without schema extensions |
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
"documentationUri": "https://help.mtime.app",
"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": [
{
"type": "oauthbearertoken",
"name": "OAuth Bearer Token",
"description": "Bearer token issued for the workspace's provisioning service user",
"primary": true
}
]
}Troubleshooting
| Issue | Solution |
|---|---|
400 Unsupported filter | Use eq on userName or externalId (users) or displayName or externalId (groups) |
409 uniqueness on create | Another user already has this externalId, or the employee already has a user. Look the user up with filter=externalId eq "…" and update it instead |
| A given or family name change does not show | mTime stores one full name and never splits it, so it cannot change only one half. Send givenName and familyName together in the same PATCH, or send name.formatted or displayName |
| A name change from the IdP does not show | Expected for a user linked to an employee while Use identity provider names for employee names is off: the name shown is the employee’s, which comes from your HR integration. Turn the setting on if the IdP should set employee names — see Which name SCIM sets |
| An email change does not show | The user has already activated their account; their sign-in email is no longer managed by provisioning |
403 on a user | The user is a workspace owner, which SCIM cannot manage |