Stitchflow
NICE CXone logo

NICE CXone User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 11, 2026

Summary and recommendation

NICE CXone exposes user lifecycle operations through its Admin API using OAuth 2.0 client credentials. A critical naming caveat applies immediately: agent-type users are managed under the `/agents` resource path, not `/users`-sending requests to a `/users` endpoint will not behave as expected.

The base URL encodes both a region code (e.g., `na1`, `eu1`) and an explicit API version number (e.g., `v28.0`); both must match your tenant's configuration or requests return 404 or auth errors.

For identity graph use cases-syncing user state across an IdP, HRIS, and CXone-SCIM 2.0 is the preferred integration surface, but it is gated to Enterprise tier and requires SSO (SAML or OIDC) to be fully active before the SCIM token can be generated.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 (client credentials or authorization code flow)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise

Authentication

Auth method: OAuth 2.0 (client credentials or authorization code flow)

Setup steps

  1. Log in to NICE CXone as an administrator and navigate to Admin > API Applications.
  2. Create a new API application to obtain a Client ID and Client Secret.
  3. Assign the application the required permission scopes for user management.
  4. POST to the token endpoint: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/token with grant_type=client_credentials, client_id, and client_secret.
  5. Receive an access_token (Bearer) and token_type in the response; use the Bearer token in the Authorization header for all subsequent API calls.
  6. Tokens expire; implement refresh logic using the returned expires_in value.

Required scopes

Scope Description Required for
AdminAPI Grants access to administrative operations including user create, read, update, and delete. All user management endpoints
ReadUsers Read-only access to user records and user lists. GET /users, GET /users/{userId}
WriteUsers Create and update user records. POST /users, PUT /users/{userId}, PATCH /users/{userId}

User object / data model

Field Type Description On create On update Notes
userId integer Unique internal identifier for the user. system-generated read-only Used as path parameter in user-specific endpoints
userName string Login username for the user. required optional Must be unique within the tenant
firstName string User's first name. required optional
lastName string User's last name. required optional
email string User's email address. required optional Used for notifications and SSO matching
password string User's password (write-only). required (if not SSO) optional Not returned in GET responses
isActive boolean Whether the user account is active. optional (default: true) optional Set to false to deactivate without deleting
teamId integer ID of the team the user belongs to. optional optional Teams are pre-configured in the tenant
profileId integer Security profile (role) assigned to the user. required optional Controls permissions within CXone
skillIds array[integer] List of skill IDs assigned to the user. optional optional Skills determine routing eligibility
reportToId integer userId of the user's manager. optional optional
location string Physical or logical location of the user. optional optional
timeZone string User's time zone (IANA format). optional optional
countryId integer Country identifier for the user. optional optional
phoneNumber string User's phone number. optional optional
ntLoginName string Windows/AD login name for SSO mapping. optional optional Required when using Active Directory SSO
federatedId string External identity provider subject identifier. optional optional Used for SAML/OIDC SSO federation
hireDate string (ISO 8601) User's hire date. optional optional
notes string Free-text notes about the user. optional optional
lastLogin string (ISO 8601) Timestamp of the user's last login. system-generated read-only

Core endpoints

List Users

  • Method: GET
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/agents
  • Watch out for: The endpoint path uses 'agents' not 'users' for agent-type users. Administrative users may be under a separate endpoint.

Request example

GET /incontactapi/services/v28.0/agents?top=50&skip=0
Authorization: Bearer {access_token}

Response example

{
  "resultSet": {
    "agents": [
      {"agentId": 1234, "userName": "jdoe", "firstName": "Jane", "lastName": "Doe", "isActive": true}
    ]
  },
  "totalRecords": 1
}

Get User by ID

  • Method: GET
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/agents/{agentId}
  • Watch out for: agentId is the internal integer ID, not the userName. Ensure you resolve the correct ID before calling.

Request example

GET /incontactapi/services/v28.0/agents/1234
Authorization: Bearer {access_token}

Response example

{
  "resultSet": {
    "agents": [
      {"agentId": 1234, "userName": "jdoe", "email": "jdoe@example.com", "profileId": 5, "teamId": 10, "isActive": true}
    ]
  }
}

Create User

  • Method: POST
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/agents
  • Watch out for: profileId (security profile) is required. Creating a user without a valid profileId returns a 400 error.

Request example

POST /incontactapi/services/v28.0/agents
Authorization: Bearer {access_token}
Content-Type: application/json

{"firstName":"Jane","lastName":"Doe","userName":"jdoe","email":"jdoe@example.com","profileId":5,"teamId":10}

Response example

{
  "resultSet": {
    "agentId": 1234
  }
}

Update User

  • Method: PUT
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/agents/{agentId}
  • Watch out for: PUT replaces the full user object. Omitting optional fields may reset them to defaults. Use with caution.

Request example

PUT /incontactapi/services/v28.0/agents/1234
Authorization: Bearer {access_token}
Content-Type: application/json

{"firstName":"Jane","lastName":"Smith","isActive":true}

Response example

{
  "resultSet": {
    "agentId": 1234
  }
}

Deactivate User

  • Method: DELETE
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/agents/{agentId}
  • Watch out for: DELETE typically deactivates (sets isActive=false) rather than permanently deleting the user record. Permanent deletion may require a separate admin action.

Request example

DELETE /incontactapi/services/v28.0/agents/1234
Authorization: Bearer {access_token}

Response example

HTTP 200 OK
{}

Assign Skills to User

  • Method: POST
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/agents/{agentId}/skills
  • Watch out for: Skills must exist in the tenant before assignment. Proficiency is typically 1–20 depending on tenant configuration.

Request example

POST /incontactapi/services/v28.0/agents/1234/skills
Authorization: Bearer {access_token}
Content-Type: application/json

{"skills":[{"skillId":101,"proficiency":5}]}

Response example

HTTP 200 OK
{}

Get User Teams

  • Method: GET
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/teams
  • Watch out for: Retrieve teamId values here before creating or updating users; teamId is required for team assignment.

Request example

GET /incontactapi/services/v28.0/teams
Authorization: Bearer {access_token}

Response example

{
  "resultSet": {
    "teams": [
      {"teamId": 10, "teamName": "Support Team A", "isActive": true}
    ]
  }
}

Get Security Profiles

  • Method: GET
  • URL: https://api-{region}.niceincontact.com/incontactapi/services/v{version}/security-profiles
  • Watch out for: profileId is required when creating users. Fetch this list to map role names to IDs before provisioning.

Request example

GET /incontactapi/services/v28.0/security-profiles
Authorization: Bearer {access_token}

Response example

{
  "resultSet": {
    "securityProfiles": [
      {"profileId": 5, "profileName": "Agent", "isActive": true}
    ]
  }
}

Rate limits, pagination, and events

  • Rate limits: NICE CXone enforces API rate limits per tenant. Exact published limits are not publicly documented; limits are enforced at the platform level and vary by tenant configuration.
  • Rate-limit headers: Yes
  • Retry-After header: No
  • Rate-limit notes: HTTP 429 is returned when limits are exceeded. Retry-After header presence is not confirmed in official docs. Implement exponential backoff.
  • Pagination method: offset
  • Default page size: 50
  • Max page size: 100
  • Pagination pointer: skip / top
Plan Limit Concurrent
All plans Not publicly specified; contact NICE support for tenant-specific limits 0
  • Webhooks available: No
  • Webhook notes: NICE CXone does not expose a native outbound webhook system for user lifecycle events (create, update, deactivate) via the public Admin API. Event-driven integrations typically rely on polling or the CXone Studio/Flow automation engine.
  • Alternative event strategy: Use scheduled polling of GET /agents to detect changes, or leverage SCIM provisioning push from an IdP (Okta, Entra ID) for event-driven user lifecycle management.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise

  • Endpoint: https://api-{region}.niceincontact.com/incontactapi/scim/v2

  • Supported operations: GET /Users, GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, POST /Groups, PATCH /Groups/{id}

Limitations:

  • Requires SSO (SAML or OIDC) to be configured before SCIM can be enabled.
  • Only available on Enterprise pricing tier.
  • SCIM Groups map to CXone Teams; not all team attributes are writable via SCIM.
  • Custom CXone attributes (e.g., skillIds, profileId) may require supplemental Admin API calls after SCIM provisioning.
  • SCIM token is a long-lived bearer token generated in the CXone admin UI; OAuth 2.0 client credentials are not used for SCIM.

Common scenarios

Provisioning a new agent requires three pre-flight lookups before the creation POST: resolve a valid profileId from GET /security-profiles, resolve a valid teamId from GET /teams, and confirm target skills exist in the tenant.

The creation call (POST /agents) accepts name strings for display fields but requires integer IDs for profileId and teamId-passing role or team names directly returns a 400. Skill assignment is a separate call (POST /agents/{agentId}/skills) and cannot be bundled into the creation payload.

For deactivation, DELETE /agents/{agentId} sets isActive=false rather than permanently removing the record; permanent deletion is not available via API and requires a manual admin action in the UI.

When syncing from Okta or Entra ID via SCIM, SCIM Groups map to CXone Teams, but attributes outside the SCIM schema-specifically skillIds and profileId-must be written via supplemental Admin API calls after the SCIM provisioning event completes.

Provision a new agent via Admin API

  1. Authenticate: POST to token endpoint with client_credentials to obtain Bearer token.
  2. Fetch valid profileId: GET /security-profiles and identify the correct agent profile.
  3. Fetch valid teamId: GET /teams and identify the target team.
  4. Create user: POST /agents with firstName, lastName, userName, email, profileId, teamId.
  5. Assign skills: POST /agents/{agentId}/skills with required skillId and proficiency values.
  6. Verify: GET /agents/{agentId} to confirm all fields are set correctly.

Watch out for: profileId and teamId must be resolved before creation; the API does not accept name strings for these fields.

Deactivate a departing employee

  1. Authenticate: obtain a fresh Bearer token.
  2. Resolve agentId: GET /agents?userName=jdoe to find the internal agentId.
  3. Deactivate: DELETE /agents/{agentId} (sets isActive=false).
  4. If using SCIM: PATCH /scim/v2/Users/{scimId} with {"active": false} to sync deactivation from IdP.

Watch out for: DELETE deactivates rather than permanently removes the user. Historical reporting data is retained. Permanent deletion requires manual admin action in the CXone UI.

Sync users from Okta via SCIM

  1. Confirm Enterprise plan and SSO (SAML/OIDC) are active on the CXone tenant.
  2. In CXone Admin UI, navigate to Security > SCIM and generate a SCIM bearer token.
  3. In Okta, add the NICE CXone SCIM application and configure the SCIM base URL and bearer token.
  4. Map Okta profile attributes to SCIM User attributes (userName → email, given_name, family_name).
  5. Assign the Okta application to users/groups; Okta will POST /scim/v2/Users for each assigned user.
  6. For attributes not covered by SCIM (e.g., skillIds), use a supplemental Admin API call triggered post-provisioning.

Watch out for: SCIM Groups map to CXone Teams but not all team properties are writable via SCIM. Skill assignments must be handled separately via the Admin API.

Why building this yourself is a trap

The most common integration failure is using PUT /agents/{agentId} for partial updates: PUT is a full object replacement, so omitting any optional field resets it to its default value. Always fetch the current user object and merge your changes before issuing a PUT.

A second trap is token lifecycle: OAuth 2.0 access tokens are short-lived, and expired tokens return 401 with no automatic retry signal-implement proactive refresh keyed to the expires_in value rather than reacting to 401s.

Rate limits are not publicly documented; the API returns HTTP 429 when limits are exceeded, but no Retry-After header is confirmed in official documentation, so exponential backoff is the only safe retry strategy.

Finally, SCIM uses a separate long-lived bearer token generated in the CXone Admin UI-it does not use the OAuth 2.0 client credentials flow, so your SCIM and Admin API auth paths must be managed independently.

Automate NICE CXone workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 11, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen