# Assignment Skill API

Use the Assignment Skill APIs to manage the routing skills that Sprinklr's Unified Routing engine uses to match work to agents, and to record which skills each agent holds and at what proficiency.

A **skill** is a capability such as *Refunds* or *Chargebacks*. Skills live inside a **skill category** such as *Billing*. Once a skill exists, you grant it to agents through their **user assignment configuration**, together with a proficiency level. Unified Routing then uses those proficiencies when it decides who receives a piece of work.

These APIs are part of Sprinklr API 3.0.

## Before you start

You need:

- A registered application on the Sprinklr Developer Portal, with an **API key** and **secret**. See [API Key and Secret Generation](https://dev.sprinklr.com/api-key-and-secret-generation).
- A valid **access token**. See [Authorize](https://dev.sprinklr.com/authorize).
- The **environment identifier** for your Sprinklr workspace, which forms part of every request URL.
- A user account with permission to manage Unified Routing configuration. Without it, requests return `403`.


Credential lifetimes:

| Credential | Lifetime |
|  --- | --- |
| Authorization code | 10 minutes |
| API key | No expiry |
| Access token | 30 days |


Only one access token and refresh token pair is live per API key at a time. Generating a new pair invalidates the previous one.

## How skills, categories and agents fit together

### Categories are parents, skills are children

```
Skill category  ──1:N──▶  Skill  ──N:M──▶  Agent
   Billing                Refunds          proficiency 5
                          Chargebacks      proficiency 3
```

Three rules follow from this hierarchy, and all three affect how you write your integration:

1. **A skill must belong to a category.** Create the category before you create the skill.
2. **Deleting a category deletes every skill inside it.** This cascade is permanent and there is no confirmation step. Deleting a single skill, by contrast, removes only that skill and leaves the category intact.
3. **Updating a category replaces its skill list.** `PUT` on a skill category treats the `skills` array as the complete, authoritative set. Any skill you leave out of the array is deleted. Always fetch the category first, modify the array you receive, and send the whole array back.


### You can create skills two ways

Both produce the same result and both appear when you fetch the category:

- **Inline** — include skill objects in the `skills` array when you create the category.
- **Standalone** — call the skill endpoint and set `skillCategory` to the parent category.


### Assigning a skill to an agent

Creating a skill does not affect routing on its own. A skill influences routing only once an agent holds it. You grant skills through the user assignment configuration endpoints, using the `skillVsProficiency` map — the key is the skill, the value is the agent's proficiency level.

### Choosing between the configuration and settings endpoints

Two write paths exist for agent assignment data, and which one your workspace uses depends on the `ASSIGNMENT_SETTINGS_ENABLED` setting:

| `ASSIGNMENT_SETTINGS_ENABLED` | Behaviour |
|  --- | --- |
| **Off** | The `/userAssignmentConfig` endpoints work normally. |
| **On** | Writes to `/userAssignmentConfig` return an error directing you to the new API: *"Please use the new /userAssignmentSettings API"*. The `/userAssignmentSettings` endpoints work as expected. |


**Reads are the exception.** There is no `GET` on `/userAssignmentSettings`. Whichever way the setting is configured, always read an agent's assignment data with `GET /userAssignmentConfig`. When the setting is on, that endpoint returns the derived configuration.

| Operation | Setting off | Setting on |
|  --- | --- | --- |
| Read | `GET /userAssignmentConfig` | `GET /userAssignmentConfig` |
| Create | `POST /userAssignmentConfig` | `POST /userAssignmentSettings` |
| Replace | `PUT /userAssignmentConfig` | `PUT /userAssignmentSettings` |
| Partial update | `PATCH /userAssignmentConfig` | `PUT /userAssignmentSettings` |


If you are unsure how your workspace is configured, ask your Sprinklr administrator, or attempt the write against `/userAssignmentConfig` and fall back to `/userAssignmentSettings` when you receive the error message above.

## Base URL and environments

```
https://api3.sprinklr.com/{env}/api/v3/...
```

Replace `{env}` with the environment identifier for your workspace. Supported values:

`prod`, `prod0`, `prod2`, `prod3`, `prod4`, `prod5`, `prod6`, `prod8`, `prod11`, `prod12`, `prod15`, `prod16`, `prod17`, `prod18`, `prod19`, `prod21`, `prod25`

Calling a different environment from the one your credentials belong to returns `401`, so confirm the value before you start.

The four resource paths in this family:

```
https://api3.sprinklr.com/{env}/api/v3/unifiedRouting/skill
https://api3.sprinklr.com/{env}/api/v3/unifiedRouting/skillCategory
https://api3.sprinklr.com/{env}/api/v3/userAssignmentConfig
https://api3.sprinklr.com/{env}/api/v3/userAssignmentSettings
```

## Authentication

Every request must carry both authentication headers.

| Header | Value | Description |
|  --- | --- | --- |
| `Authorization` | `Bearer {{accessToken}}` | OAuth 2.0 bearer token. See [Authorize](https://dev.sprinklr.com/authorize). |
| `Key` | `{{apiKey}}` | Your application's API key. |
| `Content-Type` | `application/json` | Required on `POST`, `PUT` and `PATCH`. |


## Operations

Fourteen operations across four resources.

| Method | Path | Purpose |
|  --- | --- | --- |
| `GET` | `/unifiedRouting/skill` | Fetch assignment skill by id or name |
| `POST` | `/unifiedRouting/skill` | Create assignment skill |
| `PUT` | `/unifiedRouting/skill` | Update assignment skill |
| `DELETE` | `/unifiedRouting/skill` | Delete assignment skill by id |
| `GET` | `/unifiedRouting/skillCategory` | Fetch assignment skill category by id or name |
| `POST` | `/unifiedRouting/skillCategory` | Create assignment skill category |
| `PUT` | `/unifiedRouting/skillCategory` | Update assignment skill category |
| `DELETE` | `/unifiedRouting/skillCategory` | Delete assignment skill category by id |
| `GET` | `/userAssignmentConfig` | Fetch user assignment configuration |
| `POST` | `/userAssignmentConfig` | Create user assignment configuration |
| `PUT` | `/userAssignmentConfig` | Replace user assignment configuration |
| `PATCH` | `/userAssignmentConfig` | Partial update user assignment configuration |
| `POST` | `/userAssignmentSettings` | Create user assignment settings |
| `PUT` | `/userAssignmentSettings` | Update user assignment settings |


### Fetch assignment skill

```
GET /api/v3/unifiedRouting/skill
```

Query parameters:

| Name | Type | Description |
|  --- | --- | --- |
| `id` | string | Assignment skill id. |
| `name` | string | Assignment skill name. |


Supply either `id` or `name`. Both accept a single value; there is no comma-separated multi-lookup.

**The response is always an array, even when exactly one skill matches.** Read the first element rather than treating the payload as a single object.

### Create assignment skill

```
POST /api/v3/unifiedRouting/skill
```

Send an assignment skill object in the request body. Do not send `id` — the server assigns it. `skillCategory` must reference an existing skill category, so create the category first.

The response returns the created skill, including its `id` and populated `createdTime` and `modifiedTime`.

### Update assignment skill

```
PUT /api/v3/unifiedRouting/skill?id={id}
```

Targets a single skill by `id` and updates its fields. The skill's category mapping is preserved, and no other records are affected.

Send the complete skill object, including `skillCategory`, so that no field is unintentionally cleared.

### Delete assignment skill

```
DELETE /api/v3/unifiedRouting/skill?id={id}
```

Deletes the skill and removes it from its category. Nothing else is affected. Always supply `id`.

### Fetch assignment skill category

```
GET /api/v3/unifiedRouting/skillCategory
```

Query parameters:

| Name | Type | Description |
|  --- | --- | --- |
| `id` | string | Skill category id. |
| `name` | string | Skill category name. |


Fetching by either `id` or `name` returns the category together with **all** of its skills, whether those skills were created inline with the category or added separately afterwards.

As with skills, the response is an array.

### Create assignment skill category

```
POST /api/v3/unifiedRouting/skillCategory
```

Send a skill category object. You can create the category on its own, or create it together with one or more skills by populating the `skills` array.

Two things to expect in the response:

- `createdTime` and `modifiedTime` are returned as `0`. Fetch the category afterwards if you need timestamp values, and do not interpret `0` as a real date.
- `shareConfigs` is returned empty unless you supplied share configuration in the request.


### Update assignment skill category

```
PUT /api/v3/unifiedRouting/skillCategory?id={id}
```

A single call can add new skills, update existing skills and delete skills, because the `skills` array you send **replaces** the category's current skill list.

> **Skills omitted from the `skills` array are deleted.** Fetch the category first, modify the returned array, and send the full array back.


To update an existing skill through this call, include its `id` in the array element. To add a new skill, include the element without an `id`.

### Delete assignment skill category

```
DELETE /api/v3/unifiedRouting/skillCategory?id={id}
```

> **This is a cascade delete.** Deleting a skill category also deletes every skill inside it, and those skills become immediately unavailable to routing. There is no dry-run or undo. If you want to keep the skills, move them to another category with `PUT /unifiedRouting/skill` before deleting the category.


Always supply `id`.

### Fetch user assignment configuration

```
GET /api/v3/userAssignmentConfig?userId={userId}
```

Returns the agent's capacities, proficiencies, capacity configuration and time zone. Use this endpoint for reads regardless of how `ASSIGNMENT_SETTINGS_ENABLED` is configured.

The response is an array. If no configuration exists for the user, the request returns `404`.

### Create user assignment configuration

```
POST /api/v3/userAssignmentConfig
```

Creates a new configuration for the `userId` carried in the request body. There are no query parameters on this operation.

If a configuration already exists for that user, the request is rejected with a message of the form:

```json
{
  "message": "User assignment config already exists for userId: '1000000001'. Use PUT to update an existing config."
}
```

Use `PUT` or `PATCH` to change an existing configuration.

### Replace user assignment configuration

```
PUT /api/v3/userAssignmentConfig?userId={userId}
```

> **This is a full overwrite. Any field you omit is cleared.** Use `PATCH` unless you genuinely intend to reset the agent's entire assignment configuration.


### Partial update user assignment configuration

```
PATCH /api/v3/userAssignmentConfig?userId={userId}
```

The recommended way to change an agent's skills. Only the fields you send are updated; everything else is preserved.

The request body is an add-or-remove shape: send `proficiencies` and `capacities` to add or update entries, and `skillsToRemove`, `languagesToRemove`, `channelsToRemove` or `capacitiesToRemove` to delete them. Removal is explicit, so there is no risk of deleting an entry by leaving it out.

### Create user assignment settings

```
POST /api/v3/userAssignmentSettings
```

Available when `ASSIGNMENT_SETTINGS_ENABLED` is on. Creates the agent's assignment settings, which update the underlying user assignment configuration. The response returns the resulting user assignment configuration, and the same data is visible through `GET /userAssignmentConfig`.

### Update user assignment settings

```
PUT /api/v3/userAssignmentSettings?userId={userId}
```

A targeted update that supports explicit removal through `skillsToRemove`.

## Field reference

### Assignment skill

| Field | Type | Description |
|  --- | --- | --- |
| `id` | string | Unique id of the skill. A 24-character hexadecimal identifier assigned by Sprinklr. Omit on create. |
| `skill` | string | **Name of the skill.** Note that the skill's name is carried in `skill`, whereas a category's name is carried in `name`. |
| `description` | string | Description of the skill. |
| `skillCategory` | string | The parent skill category. Must reference an existing category. |
| `createdTime` | integer (int64) | Created time, in epoch milliseconds. |
| `modifiedTime` | integer (int64) | Last modified time, in epoch milliseconds. |


### Assignment skill category

| Field | Type | Description |
|  --- | --- | --- |
| `id` | string | Unique id of the skill category. Assigned by Sprinklr; omit on create. |
| `name` | string | Name of the skill category. |
| `description` | string | Description of the skill category. |
| `skills` | array of assignment skill | Skills associated with the category. On update, this array replaces the current skill list. |
| `shareConfigs` | array of asset share config | Share configurations for the category. |


### Asset share config

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `type` | string | Yes | The sharing scope, for example `USER`, `GLOBAL` or `CLIENT`. |
| `ids` | array of string | No | Identifiers appropriate to the chosen `type`. |


### User assignment configuration

| Field | Type | Description |
|  --- | --- | --- |
| `userId` | string | The agent's user id. |
| `capacities` | array of capacity | The agent's work capacities. |
| `proficiencies` | proficiencies | The agent's proficiencies across skill, channel and language. |
| `capacityConfigId` | string | The agent's capacity configuration id. |
| `capacityConfigName` | string | The agent's capacity configuration name. |
| `timeZone` | time zone | The agent's time zone. |


### Capacity

| Field | Type | Description |
|  --- | --- | --- |
| `id` | string | Capacity id. |
| `capacity` | integer (int32) | Work assignment capacity. |
| `activeConversationCapacity` | integer (int32) | Active work conversation capacity. |


### Proficiencies

Three maps. In each, the key names the skill, language or channel, and the value is an integer proficiency level.

| Field | Type | Description |
|  --- | --- | --- |
| `skillVsProficiency` | object of string to integer (int32) | Skill-level proficiencies for the agent. |
| `languageVsProficiency` | object of string to integer (int32) | Language proficiencies for the agent. |
| `channelVsProficiency` | object of string to integer (int32) | Channel-level proficiencies for the agent. |


Agree a single proficiency scale across your integration and apply it consistently, so that routing decisions remain comparable between agents.

### User assignment configuration update request

The body for `PATCH /userAssignmentConfig`.

| Field | Type | Description |
|  --- | --- | --- |
| `userId` | string | The agent's user id. |
| `capacities` | array of capacity | Capacities to add or update. |
| `capacitiesToRemove` | array of string | Capacities to remove. |
| `proficiencies` | proficiencies | Proficiencies to add or update. |
| `skillsToRemove` | array of string | Skill proficiencies to remove. |
| `languagesToRemove` | array of string | Language proficiencies to remove. |
| `channelsToRemove` | array of string | Channel proficiencies to remove. |


### User assignment settings update request

The body for `POST` and `PUT` on `/userAssignmentSettings`.

| Field | Type | Description |
|  --- | --- | --- |
| `userId` | string | The agent's user id. |
| `skillVsProficiency` | object of string to integer (int32) | Skill-level proficiencies to add or update. |
| `skillsToRemove` | array of string | Skill proficiencies to remove. |
| `capacityConfigId` | string | The agent's capacity configuration id. |
| `timeZone` | time zone | The agent's time zone. |


Note that skill proficiencies appear at the top level here, rather than nested inside a `proficiencies` object as they are in the configuration update request.

## Worked examples

The examples below use placeholder credentials and synthetic identifiers. Replace `{{accessToken}}`, `{{apiKey}}`, the environment and all identifiers with your own values.

### Rename a skill (cURL)

```bash
curl -X PUT \
  "https://api3.sprinklr.com/prod2/api/v3/unifiedRouting/skill?id=0000000000000000000000a1" \
  -H "Authorization: Bearer {{accessToken}}" \
  -H "Key: {{apiKey}}" \
  -H "Content-Type: application/json" \
  -d '{
        "skill": "Refunds and Credits",
        "description": "Processing customer refunds and account credits",
        "skillCategory": "Billing"
      }'
```

### Revoke a skill from an agent (cURL)

```bash
curl -X PATCH \
  "https://api3.sprinklr.com/prod2/api/v3/userAssignmentConfig?userId=1000000001" \
  -H "Authorization: Bearer {{accessToken}}" \
  -H "Key: {{apiKey}}" \
  -H "Content-Type: application/json" \
  -d '{
        "userId": "1000000001",
        "skillsToRemove": ["Chargebacks"]
      }'
```

When `ASSIGNMENT_SETTINGS_ENABLED` is on, send the same `skillsToRemove` array to `PUT /api/v3/userAssignmentSettings?userId=1000000001`.

## Response format and status codes

### Response envelope

Every API 3.0 response uses the same envelope:

```json
{
  "data": {},
  "errors": [],
  "metadata": {}
}
```

- `data` carries the result. For fetch operations across this family it is an **array**, even when a single record matches.
- `errors` carries zero or more error objects, each shaped `{ "id": "...", "code": "...", "message": "..." }`, where `id` is a 24-character hexadecimal identifier. Quote it when you contact Sprinklr Support.
- `metadata` carries any supplementary information the operation returns.


### Status codes

| Code | Meaning | What to do |
|  --- | --- | --- |
| `200` | Success, with a body. | Read `data`. |
| `204` | Success, with no body. Returned by several update and delete operations. | Treat as success and do not parse a body. |
| `400` | The request was malformed, failed field validation, or duplicated an existing record. | Read `errors[].message`. |
| `401` | Missing, malformed or expired credentials, or the wrong environment in the URL. | Refresh the access token and confirm the environment. |
| `403` | Authenticated, but the user lacks permission to manage Unified Routing configuration. | Ask your Sprinklr administrator for the relevant permission. |
| `404` | No record matches the supplied `id`, `name` or `userId`. | Verify the identifier. |


Write operations in this family may return either `200` or `204`. Build your client to treat any `2xx` as success and to parse a response body only when one is present:

```python
res = requests.delete(url, headers=HEADERS, params={"id": skill_id}, timeout=30)
res.raise_for_status()
payload = res.json() if res.content else None
```

## What is new in API 3.0

There is no API 2.0 equivalent of the Assignment Skill APIs — this family is new in API 3.0, so there is no migration to perform. If you are coming from API 2.0, the conventions below are the ones that differ most from what you are used to.

| Concern | API 2.0 | API 3.0, in this family |
|  --- | --- | --- |
| Path prefix | `/api/v2/...` | `/api/v3/...` |
| Response shape | Varies by endpoint | Always `{data, errors, metadata}` |
| Record selector | Often in the path, such as `/resource/{id}` | Always in the **query string**: `?id=`, `?name=`, `?userId=` |
| Single-record fetch | Frequently an object | Always an **array** — read `data[0]` |
| Partial update | Rare | `PATCH /userAssignmentConfig` is first-class and is the recommended way to change an agent's skills |
| Authentication | `Authorization` and `Key` headers | Unchanged — the same two headers |


Your existing API key, secret and OAuth flow work unchanged. See [API Overview](https://dev.sprinklr.com/api-overview).

## Common Use Cases

| Task | Call |
|  --- | --- |
| Create a skill category | `POST /unifiedRouting/skillCategory` with `name` |
| Create a category and its skills together | `POST /unifiedRouting/skillCategory` with a populated `skills` array |
| Add one skill to an existing category | `POST /unifiedRouting/skill` with `skillCategory` set |
| Look up a skill's id from its name | `GET /unifiedRouting/skill?name=Refunds` then read `data[0].id` |
| List every skill in a category | `GET /unifiedRouting/skillCategory?id={id}` then read `data[0].skills` |
| Rename a skill | `PUT /unifiedRouting/skill?id={id}` with the full skill object |
| Move a skill to another category | `PUT /unifiedRouting/skill?id={id}` with a new `skillCategory` |
| Delete one skill | `DELETE /unifiedRouting/skill?id={id}` |
| Delete a category and all its skills | `DELETE /unifiedRouting/skillCategory?id={id}` |
| Read an agent's skills and capacity | `GET /userAssignmentConfig?userId={userId}` then read `data[0]` |
| Grant an agent a skill | `PATCH /userAssignmentConfig?userId={userId}` with `proficiencies.skillVsProficiency` |
| Revoke an agent's skill | `PATCH /userAssignmentConfig?userId={userId}` with `skillsToRemove` |
| Reset an agent's whole configuration | `PUT /userAssignmentConfig?userId={userId}` |


## Best practices

**Create the category before the skill.** A skill cannot be created without a valid `skillCategory`. If you are provisioning skills in bulk, create all categories first.

**Read before you write on categories.** `PUT /unifiedRouting/skillCategory` replaces the skill list. Fetch the category, modify the `skills` array in place, and send the complete array.

**Prefer `PATCH` over `PUT` for agent configuration.** `PATCH` updates only what you send and removes only what you name in a `*ToRemove` array. `PUT` clears every field you omit.

**Always index into `data[0]` on fetch.** Fetch responses in this family are arrays even for a single match. Code that treats `data` as an object will break on the first call.

**Move skills before deleting a category.** Deleting a category cascades to its skills. If any of those skills are still granted to agents, reassign them to another category first.

**Build clean URLs.** Construct paths programmatically rather than by string concatenation, so that stray separators never appear in the request path.

**Cache skill ids, not names.** Names can be changed with `PUT`; ids cannot. Resolve a name to an id once, then work with the id.

**Store your proficiency scale in one place.** The proficiency value is a plain integer with no enforced range, so consistency is your responsibility. Define the scale once in your integration and reuse it.

**Handle empty response bodies.** Several write operations return `204 No Content`. Check for a body before parsing.

**Do not embed credentials in source control.** Load the access token and API key from environment variables or a secret store.

## Troubleshooting

| Symptom | Likely cause | Resolution |
|  --- | --- | --- |
| `401 Unauthorized` on every call | Expired access token, or the wrong `{env}` in the URL | Refresh the token, and confirm the environment identifier for your workspace |
| `403 Forbidden` | The authenticated user cannot manage Unified Routing configuration | Ask your Sprinklr administrator to grant the relevant permission |
| `400` when creating a skill | `skillCategory` does not reference an existing category | Create the category first, then use the value returned by the skill category API |
| `404` when fetching a skill by name | The name was renamed, or the case does not match | Fetch the parent category and read its `skills` array to find the current name |
| `404` on `GET /userAssignmentConfig` | No assignment configuration exists yet for that user | Create one with `POST /userAssignmentConfig` |
| `"User assignment config already exists for userId ... Use PUT to update an existing config."` | You sent `POST` for an agent who already has a configuration | Use `PATCH` for an incremental change, or `PUT` for a full replacement |
| `"Please use the new /userAssignmentSettings API"` | `ASSIGNMENT_SETTINGS_ENABLED` is on for your workspace | Send writes to `/userAssignmentSettings`. Continue to read from `/userAssignmentConfig` |
| Skills disappeared after a category update | The `skills` array you sent omitted them, so they were deleted | Always fetch the category first and send back the complete array |
| Skills disappeared after a category delete | Deleting a category cascades to its skills | Recreate the category and its skills. Move skills to another category before deleting in future |
| An agent's capacity or time zone was cleared | You used `PUT /userAssignmentConfig`, which is a full overwrite | Use `PATCH` for incremental changes |
| `createdTime` and `modifiedTime` are `0` on a newly created category | Timestamps are not populated in the create response for categories | Fetch the category to read its timestamps. Do not treat `0` as a date |
| `shareConfigs` is empty on a newly created category | No share configuration was supplied | Include `shareConfigs` in the request, with a `type` value |
| Client throws when parsing a delete or update response | The operation returned `204 No Content` | Parse a body only when one is present |
| Cannot find a `GET` for `/userAssignmentSettings` | There isn't one, by design | Read with `GET /userAssignmentConfig` in all cases |


If a problem persists, contact Sprinklr Support and quote the `id` from the `errors` array of the failing response.