SCIM Provisioning API Reference
NICE Knowledge Management supports SCIM 2.0 (System for Cross-domain Identity Management) for automated user and group provisioning. SCIM allows your identity provider (IdP) to automatically create, update, deactivate, and manage user accounts and group memberships in the platform.
SCIM handles provisioning (creating and managing accounts), not authentication (signing in).
SCIM works alongside your existing SSO configuration (SAML or OIDC). You must have SSO configured before enabling SCIM.
Supported IdPs: Okta, PingFederate, Microsoft Entra ID (Azure AD), OneLogin, or any SCIM 2.0-compliant client.
Standards compliance: This implementation follows RFC 7643 (Core Schema) and RFC 7644 (Protocol).
Prerequisites
- An active site
- SSO configured with an IdP service (authentication service ID ≥ 2)
- SCIM enabled on the site. Contact the NICE KM Support team to enable this feature.
- A Server API Token (key / secret pair) or bearer token for authenticating SCIM requests
Base URL & authentication
Base URL
All SCIM API requests use the following base URL format:
https://{your-site-domain}/@api/deki/scim/v2/{serviceId}/
Where {serviceId} is your IdP's authentication service ID (a numeric value ≥ 2; service 1 is the built-in local provider and is not valid for SCIM). For example, if your Okta SSO connection is service 4, the base URL is:
https://your-site.example.com/@api/deki/scim/v2/4/
Authentication methods
The SCIM API supports two authentication methods:
| Method | Header Format | Description |
|---|---|---|
| HTTP Basic | Authorization: Basic <base64(key:secret)> |
Uses your Server API Token key and secret. Recommended for Okta. |
| Bearer Token (JWT) | Authorization: Bearer <jwt> |
Uses a long-lived JSON Web Token. Recommended for PingFederate and Azure AD. |
Test the connection
To verify SCIM is enabled and your credentials are valid, send a GET request to the ServiceProviderConfig endpoint:
GET https://your-site.example.com/@api/deki/scim/v2/{serviceId}/ServiceProviderConfig
Authorization: Basic <base64(key:secret)>
A 200 OK response confirms the connection is working. A 403 Forbidden means SCIM is not enabled on the site or the credentials are invalid.
Supported endpoints
| Endpoint | Methods | Description |
|---|---|---|
/Users |
GET, POST | List or search users; create a new user |
/Users/{id} |
GET, PUT, PATCH, DELETE | Read, replace, update, or deactivate a user |
/Groups |
GET, POST | List or search groups; create a new group |
/Groups/{id} |
GET, PUT, PATCH, DELETE | Read, replace, update, or delete a group |
/KnowledgeBaseRoles |
GET | List available knowledge base roles (read-only, NICE KM extension) |
/KnowledgeBaseRoles/{name} |
GET | Get a single role by name (read-only) |
/Schemas |
GET | Schema discovery — returns all supported attribute definitions |
/ServiceProviderConfig |
GET | Feature discovery — returns supported SCIM capabilities |
/ResourceTypes |
GET | Resource type discovery |
Not supported: /Bulk, /Me, root-level /.search
User schema reference
The User resource uses the standard SCIM Core schema: urn:ietf:params:scim:schemas:core:2.0:User
[VERIFY: confirm actual platform mutability behavior for these fields]
| Attribute | Type | Required | Mutability | Returned | Description |
|---|---|---|---|---|---|
id |
string (GUID) | — | readOnly | always | Server-assigned unique identifier |
userName |
string | Yes | readWrite | default | Unique username. Must be unique across the site. |
externalId |
string | No | readWrite | default | Identifier assigned by the provisioning client (IdP). Case-exact. |
active |
boolean | No | readWrite | default | User active/inactive status. Setting to false deactivates the user. |
name |
complex | No | readWrite | default | User's name. Sub-attributes: givenName, familyName, formatted (read-only, computed). |
emails |
multi-valued | No | readWrite | default | Email addresses. Sub-attributes: value (required), type (canonical: "work"), primary. Only one email per user is supported. |
knowledgeBaseRole |
string | No | readWrite | default | NICE KM extension. The user's role, as a single string (e.g. "Viewer", "Contributor"). See knowledgeBaseRole attribute (Detail) below. Default: Viewer. An unrecognized role name is rejected with 400 invalidValue. |
seated |
boolean | No | readWrite | always | NICE KM extension. Whether the user occupies a license seat. Default: false. |
groups |
multi-valued | No | readOnly | default | Group memberships. Managed via Group Push, not direct assignment. |
password |
string | No | writeOnly | never | Initial password. Write-only; never returned in responses. |
displayName |
string | — | readWrite | default | Computed from name.formatted. Only returned when explicitly requested. |
nickName |
string | No | readWrite | default | Casual name for the user. |
profileUrl |
reference | No | readWrite | default | URL to the user's profile. |
title |
string | No | readWrite | default | User's job title. |
userType |
string | No | readWrite | default | Relationship to the organization (e.g., Employee, Contractor). |
preferredLanguage |
string | No | readWrite | default | Preferred language (e.g., en_US). |
locale |
string | No | readWrite | default | Default locale for formatting. |
timezone |
string | No | readWrite | default | Time zone in Olson format (e.g., America/Los_Angeles). |
meta |
complex | — | readOnly | default | Resource metadata: created, lastModified, resourceType, location. |
knowledgeBaseRole attribute (Detail)
The knowledgeBaseRole attribute is a NICE KM extension — a single string naming the role to assign to the user. It is not a multi-valued array.
Earlier pre-release builds briefly used a non-standard singular role string and then an RFC 7643 multi-valued roles array. Neither shipped. The deployed attribute is knowledgeBaseRole (a single string). See the Role attribute history section below.
Available role values:
| Role Value | Description |
|---|---|
None |
No permissions |
Viewer |
Can view published content |
Contributor |
Can create and edit content |
Draft Contributor |
Can create drafts only |
Manager |
Can manage content and page-level permissions |
Admin |
Full administrative access |
Use the GET /KnowledgeBaseRoles endpoint to retrieve the current list of available roles for your site. Role names are case-insensitive.
Behavior:
- NICE KM supports exactly one role per user. The value is a single string, not an array.
- If
knowledgeBaseRoleis absent or empty, the user defaults to Viewer. - Role names are matched case-insensitively (e.g.
"viewer"resolves toViewer). - If the role name does not match any available role, the request is rejected with
400 invalidValueand a detail ofrole '<name>' does not exist. Validation applies on both create (POST) and update (PATCH/PUT).
Example: Create a user with a role
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "jdoe",
"name": { "givenName": "John", "familyName": "Doe" },
"emails": [{ "value": "jdoe@example.com", "type": "work", "primary": true }],
"knowledgeBaseRole": "Contributor",
"active": true
}
Example: Role in GET response (the role name is normalized to its canonical casing)
"knowledgeBaseRole": "Contributor"
Group schema reference
The Group resource uses the standard SCIM Core schema: urn:ietf:params:scim:schemas:core:2.0:Group
| Attribute | Type | Required | Mutability | Returned | Description |
|---|---|---|---|---|---|
id |
string (GUID) | — | readOnly | always | Server-assigned unique identifier |
displayName |
string | Yes | readWrite | always | Group name. Must be unique. |
members |
multi-valued | No | readWrite | default | Group members. Sub-attributes: value (user GUID), display, $ref (URI), type ("User"). |
role |
complex | No | readOnly | always | NICE KM extension. The role attached to this group. Read-only; configured in admin. |
meta |
complex | — | readOnly | default | Resource metadata. |
KnowledgeBaseRoles endpoint
The /KnowledgeBaseRoles endpoint is a NICE KM extension that provides a read-only list of available roles. Use this endpoint to discover valid values for the User knowledgeBaseRole attribute.
GET https://your-site.example.com/@api/deki/scim/v2/{serviceId}/KnowledgeBaseRoles
Example response:
Note: urn:ietf:params:scim:schemas:extension:nicekm:2.0:Role is a proprietary NICE KM extension schema, not an IETF core schema.
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 6,
"Resources": [
{ "id": "1", "name": "None", "schemas": ["urn:ietf:params:scim:schemas:extension:nicekm:2.0:Role"] },
{ "id": "2", "name": "Viewer", "schemas": ["urn:ietf:params:scim:schemas:extension:nicekm:2.0:Role"] },
{ "id": "3", "name": "Contributor", "schemas": ["urn:ietf:params:scim:schemas:extension:nicekm:2.0:Role"] },
{ "id": "4", "name": "Manager", "schemas": ["urn:ietf:params:scim:schemas:extension:nicekm:2.0:Role"] },
{ "id": "5", "name": "Admin", "schemas": ["urn:ietf:params:scim:schemas:extension:nicekm:2.0:Role"] },
{ "id": "6", "name": "Draft Contributor", "schemas": ["urn:ietf:params:scim:schemas:extension:nicekm:2.0:Role"] }
]
}
User operations
Create user
POST /Users Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "jdoe",
"externalId": "jdoe-okta-id",
"name": {
"givenName": "John",
"familyName": "Doe"
},
"emails": [{ "value": "jdoe@example.com", "type": "work", "primary": true }],
"knowledgeBaseRole": "Viewer",
"seated": false,
"active": true
}
Returns 201 Created with the full User resource including the server-assigned id.
Get user
GET /Users/{id}
Returns 200 OK with the full User resource.
Example response:
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6",
"userName": "jdoe",
"externalId": "jdoe-okta-id",
"active": true,
"name": {
"givenName": "John",
"familyName": "Doe",
"formatted": "John Doe"
},
"emails": [{ "value": "jdoe@example.com", "type": "work", "primary": true }],
"knowledgeBaseRole": "Viewer",
"seated": false,
"meta": {
"resourceType": "User",
"created": "2026-04-28T12:00:00Z",
"location": "https://your-site.example.com/@api/deki/scim/v2/4/Users/a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6"
}
}
List / search users
GET /Users?filter=userName eq "jdoe"&startIndex=1&count=10
Returns 200 OK with a ListResponse containing matching users. See Filter, sort, and paginate for details.
Update user (PATCH)
PATCH /Users/{id}
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "replace", "path": "name.givenName", "value": "Jonathan" },
{ "op": "replace", "path": "active", "value": false }
]
}
Returns 200 OK with the updated resource.
Replace user (PUT)
PUT /Users/{id}
Content-Type: application/scim+json
PUT replaces the entire resource. Any attributes not included in the request body may be cleared. Use PATCH for partial updates.
Deactivate user (DELETE)
DELETE /Users/{id}
Returns 204 No Content.
User deletion in NICE Knowledge Management is a soft delete. The DELETE operation sets the user's active flag to false. The user account, content history, and profile are preserved. To reactivate the user, send a PATCH or PUT with "active": true.
Group operations
Create group
POST /Groups Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Engineering",
"members": [
{ "value": "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6" }
]
}
Returns 201 Created. Group names must be unique; a duplicate returns 409 Conflict.
Add / remove group members (PATCH)
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "add",
"path": "members",
"value": [{ "value": "user-guid-here" }]
}
]
}
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "remove",
"path": "members[value eq \"user-guid-here\"]"
}
]
}
Delete group
DELETE /Groups/{id}
Group deletion is a hard delete. The group is permanently removed.
PATCH operations
PATCH requests use the urn:ietf:params:scim:api:messages:2.0:PatchOp schema and support three operation types:
| Operation | Path Required? | Multi-value Behavior | Description |
|---|---|---|---|
add |
No (value object accepted) | Appends to list | Adds a value. If the attribute already exists, it is replaced (single-valued) or appended (multi-valued). |
remove |
Yes | Removes matching items | Removes a value. Supports filter expressions on multi-valued attributes. |
replace |
No (value object accepted) | Replaces matching items | Replaces a value. If the target does not exist, returns an error. |
Path syntax examples:
- Simple attribute:
userName - Sub-attribute:
name.givenName - Multi-valued with filter:
emails[type eq "work"].value - Multi-valued remove:
groups[value eq "group-guid"]
Limitation: Filter expressions are not supported on PATCH Add operations. Use a simple path or no path with a value object instead.
Path-less add: When path is omitted, the value must be a JSON object where each key is an attribute name:
{
"op": "add",
"value": {
"nickName": "Johnny",
"emails": [{ "value": "john@example.com", "type": "work" }]
}
}
Filter, sort, and paginate
Filter operators
| Operator | Description | Example |
|---|---|---|
eq |
Equal | userName eq "jdoe" |
ne |
Not equal | active ne true |
co |
Contains | userName co "doe" |
sw |
Starts with | userName sw "j" |
ew |
Ends with | userName ew "doe" |
gt |
Greater than | meta.created gt "2026-01-01" |
ge |
Greater than or equal | meta.created ge "2026-01-01" |
lt |
Less than | meta.created lt "2026-01-01" |
le |
Less than or equal | meta.created le "2026-01-01" |
pr |
Present (non-null) | name.givenName pr |
Logical operators: and, or, not
Complex filter: emails[type eq "work" and value co "@example.com"]
Server-side filtering (Users)
For performance, the following User attributes are filtered at the database level:
userNameexternalIdactiveseated
Filters on other attributes are evaluated in memory after retrieval.
Sortable fields (Users)
id, userName, externalId, active, emails
GET /Users?sortBy=userName&sortOrder=descending
Pagination
| Parameter | Type | Default | Description |
|---|---|---|---|
startIndex |
integer | 1 | 1-indexed starting position |
count / itemsPerPage |
integer | 10 | Results per page (maximum 1000) [VERIFY: confirm no enforced minimum count per RFC 7644 §3.4.2.4] |
Response envelope:
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 42,
"startIndex": 1,
"itemsPerPage": 10,
"Resources": [ ... ]
}
Error responses
Error responses follow the SCIM error schema (urn:ietf:params:scim:api:messages:2.0:Error):
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"scimType": "uniqueness",
"detail": "User already exists",
"status": "409"
}
| HTTP Status | scimType | Meaning |
|---|---|---|
| 400 | invalidFilter |
Invalid filter syntax or unsupported filter field |
| 400 | invalidSyntax |
Malformed request body, missing required schema URI |
| 400 | invalidPath |
Invalid PATCH path expression |
| 400 | invalidValue |
Missing required attribute, invalid value format, or an unrecognized knowledgeBaseRole (detail: role '...' does not exist) |
| 400 | noTarget |
PATCH target does not exist (e.g., Remove without a path) |
| 403 | — | Not authorized, invalid credentials, or SCIM not enabled on the site |
| 404 | — | Resource not found, or invalid serviceId (e.g. 0, 1, or non-numeric) |
| 409 | uniqueness |
Duplicate resource (user or group already exists), or license seat limit exceeded |
| 500 | — | Internal server error |
User lifecycle
Understanding how NICE Knowledge Management manages user state through SCIM:
| Action | SCIM Operation | Result in |
|---|---|---|
| Provision new user | POST /Users | User account created. Status: active. Role: as specified (default Viewer). |
| Update user profile | PATCH /Users/{id} | Specified attributes updated. Other attributes unchanged. |
| Replace user profile | PUT /Users/{id} | Entire resource replaced. Missing attributes may be cleared. |
| Deactivate user | DELETE /Users/{id} | Soft delete. Sets active: false. User cannot sign in. Content and history preserved. |
| Deactivate user | PATCH with active: false |
Same as DELETE — user deactivated. |
| Reactivate user | PATCH or PUT with active: true |
User reactivated. Can sign in again. |
| Assign seat | PATCH with seated: true |
User occupies a license seat. Returns 409 if all seats are taken. |
| Remove seat | PATCH with seated: false |
License seat released. Seat is automatically removed when user is deactivated. |
NICE Knowledge Management does not hard-delete users through SCIM. User accounts are always preserved for content attribution and audit trail purposes. The DELETE operation is equivalent to setting active: false.
Role attribute history
The role attribute is the single string knowledgeBaseRole. If your identity provider mapping sends a non-standard singular role string or a multi-valued roles array, that value is silently ignored and the user defaults to Viewer. Map your role attribute to knowledgeBaseRole.
What to send now:
- Current:
"knowledgeBaseRole": "Viewer"— a single string, visible in all responses, validated against the available roles. - Obsolete:
"role": "viewer"(singular string) and"roles": [{"value": "Viewer"}](multi-valued array). Both were intermediate forms in pre-release builds and are not read by the deployed API.
Impact:
- Clients sending
roleorroleshave those fields ignored; affected users land on the defaultViewerrole. - The
/Schemasendpoint exposesknowledgeBaseRole(string). It does not contain aroleorrolesattribute. - An unrecognized
knowledgeBaseRolevalue is rejected with400 invalidValuerather than silently defaulting.
Action required: Map your identity provider's role attribute to knowledgeBaseRole. PingFederate's literal-expression role mapping must target knowledgeBaseRole (a bare roles array is ignored). Microsoft Entra ID maps a source attribute or constant to knowledgeBaseRole.
IdP setup guides
Okta
See User and group provisioning with Okta for step-by-step Okta configuration instructions.
PingFederate
- In PingFederate, configure an Outbound Provisioning connection.
- Set the SCIM Base URL to
https://{your-site-domain}/@api/deki/scim/v2/{serviceId}/ - Configure authentication using a Bearer Token (JWT) or HTTP Basic with your Server API Token.
- In the Attribute Mapping, map the role to the
knowledgeBaseRolestring attribute (e.g. via a literal expression such as"Viewer"or a source attribute). A barerolesarray is not read. - Test the connection and trigger an initial provisioning sync.
Microsoft Entra ID (Azure AD)
- In the Azure portal, go to Enterprise Applications > your application > Provisioning.
- Set Provisioning Mode to Automatic.
- Enter the Tenant URL:
https://{your-site-domain}/@api/deki/scim/v2/{serviceId}/ - Enter the Secret Token: your Server API Token key and secret in
key:secretformat (Base64-encoded) or as a Bearer JWT. - Click Test Connection to verify.
- Configure attribute mappings. Map a source attribute or constant to the
knowledgeBaseRolestring to assign user roles. - You may omit
metaandmeta.location— Entra's defaultmetablock (resourceType only) is accepted. - Enable provisioning and assign users/groups.
Other IdPs
For any SCIM 2.0-compliant identity provider:
- Set the SCIM base URL:
https://{your-site-domain}/@api/deki/scim/v2/{serviceId}/ - Configure authentication (HTTP Basic or Bearer Token)
- Use the
/Schemasendpoint for automatic attribute discovery - Map attributes according to the User Schema Reference above
Attribute mapping guide
Recommended attribute mappings for common identity providers:
| IdP Attribute | SCIM Attribute | Field | Notes |
|---|---|---|---|
user.login / userPrincipalName |
userName |
Username | Required. Must be unique. |
user.firstName / givenName |
name.givenName |
First name | |
user.lastName / surname |
name.familyName |
Last name | |
user.email / mail |
emails[type eq "work"].value |
Only one email supported | |
| (custom attribute or static value) | knowledgeBaseRole |
Role | Single string. Default: Viewer. Unknown value → 400. See available roles above. |
| (custom attribute) | seated |
License seat | Default: false. 409 if seats exhausted. |
| (IdP-assigned unique ID) | externalId |
External identity | Used for matching/correlation |
Troubleshooting
| Problem | Possible Cause | Resolution |
|---|---|---|
| 403 Forbidden on all requests | SCIM not enabled on the site | Contact NICE KM Support team to enable site/scim/enabled |
| 403 Forbidden on all requests | Invalid or expired API token | Generate a new Server API Token |
| 404 Not Found on all requests | Wrong serviceId in the base URL |
Verify the authentication service ID for your SSO connection |
| Users created without correct role | knowledgeBaseRole not mapped, or mapped to role/roles instead |
Map the role to the knowledgeBaseRole string attribute. role and roles are ignored. See Attribute mapping guide below. |
| 400 invalidValue — "role '...' does not exist" | Invalid role name in knowledgeBaseRole |
Check valid role names using GET /KnowledgeBaseRoles. Role names are case-insensitive. |
| 409 Conflict on user creation | User with same userName already exists |
Check for existing users. Use Import in your IdP to link existing users. |
| 409 Conflict on seated user creation | All license seats are occupied | Free up seats in the Control Panel or increase your license. [VERIFY: confirm correct location/wording, e.g. Control Panel name] |
| Users still active after deleting in IdP | Expected behavior — DELETE is a soft delete | By design. DELETE sets active: false. Account is preserved. |
| Groups not syncing | Group Push not configured in your IdP | Enable Group Push in your IdP's provisioning settings. |
| PATCH operations failing | Missing path on Remove operation |
Remove operations require a path. Use "path": "attributeName". |
role / roles not in /Schemas response |
Expected — the role attribute is knowledgeBaseRole |
Use knowledgeBaseRole (single string). See Role attribute history section. |
Known limitations
- One email per user — Only a single email address is supported per User resource.
- Soft delete only — User DELETE sets
active: false. Users are never hard-deleted via SCIM. - One role per user — The role is the single
knowledgeBaseRolestring. Multi-valuedrolesarrays are not supported. - No Bulk operations — The
/Bulkendpoint is not supported. - No ETags — Optimistic concurrency via ETags is not supported.
- Group role is read-only — The
roleattribute on Groups is set in admin, not through SCIM. - Resource IDs must be unique — IDs are globally unique GUIDs across all resource types.
- Seated defaults to false — New users are unseated by default. Setting
seated: truewhen all seats are taken returns 409 Conflict. - No rate limiting at API level — Rate limiting is governed by the API Gateway configuration.
FAQs
Does SCIM handle sign-in?
No. SCIM handles provisioning (creating and managing user accounts). Use SAML or OIDC for authentication (signing in). SCIM and SSO work together: SSO handles how users log in, and SCIM handles which users exist and what access they have.
Can I use SCIM without SSO?
No. SCIM requires an Identity Provider service with an authentication service ID. SSO must be configured before SCIM can be enabled.
How do I find my authentication service ID?
Check your authentication services in the admin panel, or contact the NICE KM Support team. The service ID is the numeric identifier in the SCIM base URL.
What happens to existing users when I enable SCIM?
Existing users are not affected. Use the Import feature in your identity provider to link existing users to their IdP identities.
Can I call the SCIM API directly without an identity provider?
Yes. The SCIM API is a standard REST API. You can call it directly using a Server API Token for authentication. This is useful for custom integrations or scripted user management.
How often does my identity provider sync?
This depends on your IdP configuration. Okta typically syncs every 40 minutes for incremental changes. Microsoft Entra ID syncs approximately every 40 minutes. [VERIFY: confirm current Entra ID provisioning sync interval against Microsoft's documentation] Consult your IdP's documentation for details.
What if a user exists in NICE Knowledge Management but not in my IdP?
SCIM does not delete users that are not in your IdP. Users must be explicitly deactivated or deleted through SCIM operations. Unmanaged users continue to exist in NICE Knowledge Management.
