# Keyword List API V3 — Developer Guide

- **Applies to:** Sprinklr Keyword List API V3 — `GET`, `POST`, `PATCH`, and `DELETE` on `/api/v3/listening/keywordList`


## 1. Overview

A **Keyword List** is a reusable, named collection of keywords or phrases that can be referenced from many Listening queries instead of being retyped into each one. Per the V2 reference: *"In Listening, Keyword Lists are a single list of words or phrases that can be used in multiple query builds. You can create these Keyword Lists if there are a group of words that you want to filter out or include for multiple queries."*

The Help Center describes where they are consumed: *"Once created, keywords lists can be used in — **Dashboards:** To include or exclude conversations based on a set of keywords. **Topics & Themes:** To quickly include or exclude a long list of keywords with OR or AND operator. **Rules:** To save time and reduce the possibility of manual entry errors."*

**Two behaviours worth knowing before you automate against this API:**

1. **Keyword Lists sync bidirectionally with Settings.** Per V2: *"The Keyword Lists you create in Listening Insights will automatically sync with Settings Keyword Lists… any Keyword Lists you create or edit in Listening Insights will update in Settings Keyword Lists and vice versa."* A write through this API is visible in both surfaces.
2. **Edits propagate into live queries.** Per V2: *"If any Listening Queries uses Keyword Lists, updates made by users who have permission to edit Keyword Lists from Admin Settings will reflect in Query using that Keyword List."* A `PATCH` here silently changes the behaviour of every Topic that references the list. Treat updates as a production change, not a metadata tweak.


### 1.1 Operations

V3 puts all four operations on **one path**, differentiated by HTTP method:

| Operation | Method | Path | operationId | Documented by |
|  --- | --- | --- | --- | --- |
| Fetch Keyword List(s) — supports bulk | `GET` | `/api/v3/listening/keywordList` | `ListeningKeywordListApiV3_getKeywordLists` | Spec + Jira only |
| Create a Keyword List | `POST` | `/api/v3/listening/keywordList` | `ListeningKeywordListApiV3_createKeywordList` | Spec + endpoint spec |
| Partially update a Keyword List | `PATCH` | `/api/v3/listening/keywordList?id=` | `ListeningKeywordListApiV3_patchKeywordList` | Spec + endpoint spec |
| Delete Keyword List(s) — supports bulk | `DELETE` | `/api/v3/listening/keywordList?id=` | `ListeningKeywordListApiV3_deleteKeywordLists` | Spec only |


This mirrors the shape of Listening Topic Group V3, Listening Topic V3, and Listening Theme V3.

### 1.2 The Keyword List object

`KeywordGroup` — *"Unified view of a Keyword List in Sprinklr"*. Note the schema name is **`KeywordGroup`**, not `KeywordList`: the underlying store is the `keywordGroup` collection. This one schema is used as **both** the `POST` request body and the `GET`/`POST` response.

| Field | Type | Required | Description (verbatim from `sprinklr-v3.yaml`) |
|  --- | --- | --- | --- |
| `id` | String | — | Unique identifier of the Keyword List in Listening |
| `name` | String | **Yes** | Keyword List name |
| `description` | String | — | Keyword List description |
| `conditions` | Array[`KeywordGroupCondition`] | **Yes** | Keyword List keyword conditions list |
| `tags` | Array[String] | — | Keyword List tags list |
| `shareConfigs` | Array[`AssetShareConfig`] | — | Share config to view Keyword List |
| `permissions` | Array[`AssetShareConfig`] | — | Permission config to edit or update Keyword List |
| `autoBackfillTopics` | Boolean | — | Auto backfill topics which refer this keyword list |


`required: [name, conditions]` — **two** required fields, the largest `required` array in the Listening V3 set.

**`KeywordGroupCondition`** — *"Keyword or phrase condition"*. This is the actual keyword payload.

| Field | Type | Description |
|  --- | --- | --- |
| `term` | String | Keyword or Phrase |
| `distance` | Integer (int32) | Distance for Proximity Keyword |
| `keywordType` | String | Type of Keyword, possible values : `KEYWORD`, `PHRASE`, `PROXIMITY_KEYWORD` |


`distance` is used to set the slop value for elastic search."* It is meaningful only when `keywordType` is `PROXIMITY_KEYWORD`. No source states the valid range, the default, or what happens if `distance` is sent with a plain `KEYWORD`.

**`AssetShareConfig`** — used by both `shareConfigs` and `permissions`:

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `type` | String | **Yes** | Type e.g. `USER`, `GLOBAL`, `CLIENT` |
| `ids` | Array[String] | — | IDs based on type. |


> **Specification gap.** `AssetShareConfig.type` has no `enum` — `USER`, `GLOBAL`, `CLIENT` appear only in an "e.g." description, so the list may be incomplete.


### 1.3 Sharing and permissions — read one shape, write another

Keyword List V3 has **the same read/write asymmetry** documented in the Listening Topic Group V3 guide, with one important improvement.

|  | `GET` / `POST` (`KeywordGroup`) | `PATCH` (`ListeningKeywordListPatchRequestDTO`) |
|  --- | --- | --- |
| View access | `shareConfigs` — **array** of `AssetShareConfig` `{type, ids[]}` | `shareConfig` — **single** `ShareConfig` `{userIds[], userGroupIds[], clientIds[], clientGroupIds[], shareWithEveryOne}` |
| Edit access | **`permissions`** — array of `AssetShareConfig` | **`permissionEntity`** — single `PermissionEntity` (same five fields as `ShareConfig`) |


The semantic distinction between the two objects is stable across every source and comes from V2:

- **share / `shareConfigs`** — *"share configurations which authorise users to **view** Keyword List"*
- **permissions / `permissionEntity`** — *"permission configuration to authorise users to **edit or update** Keyword List"*


### 1.4 Prerequisites

| V3 API | Module/Entity (UI) | Permission (UI name) | Server type | Collection / store |
|  --- | --- | --- | --- | --- |
| **Keyword List** | Listening Settings | **Keyword Group View** | **`DEFAULT`** | `keywordGroup` |


> Note the server type is **`DEFAULT`**, not `LISTENING` — Keyword List differs from Listening Topic, Topic Group, Theme, and Backfill, which all use `LISTENING`. Only Keyword List and Alert use `DEFAULT`. If you are routing V3 calls per entity, Keyword List does not follow the Listening pattern.


**Platform-level prerequisite**: *"As Keyword Lists are governed at Customer-level and not for specific workspaces, in addition to having the below permissions, **users must be Global Admins or Global Users** in order to create or edit Keyword Lists."* A workspace-scoped service account will not be sufficient.

The UI permissions that govern the entity:

| Permission Category | Permission Type | Permission | Description |
|  --- | --- | --- | --- |
| Setup | Keyword List | Create Keyword List | Allows users to create new Keyword Lists in Settings |
| Setup | Keyword List | Delete Keyword List | Allows users to delete the Keyword Lists in Settings |
| Conversations | Keyword List | Create Keyword List | Allows users to create new Keyword Lists |
| Conversations | Keyword List | Delete Keyword List | Allows users to delete Keyword Lists |
| Conversations | Keyword List | View Keyword List | Allows users to view Keyword Lists |
| Conversations | Keyword List | Keyword List Edit | Allows users to edit Keyword Lists |


## 2. Base URLs and environments

All API calls are sent to the production endpoint: `https://api3.sprinklr.com/{env}/api/v3/keyword-list`

For the `{env}` identifier itself (`prod0`, `prod2`, `prod15`, and so on), see [APIs | Sprinklr Developer Portal](https://legacy-dev.sprinklr.com/apis).

## 3. Authentication and common headers

All Keyword List V3 calls are authenticated with OAuth 2.0. See [API Overview](https://legacy-dev.sprinklr.com/api-overview) for portal registration, API key and secret generation, and the Authorize flow.

| Header | Value | Purpose | Required on |
|  --- | --- | --- | --- |
| `Authorization` | `Bearer {{accessToken}}` | Credential used by the API to authenticate a user with the server. For generating an authorization token, refer to the **Authorize** section on the developer portal. | All requests |
| `Key` | `{{apiKey}}` | API key helps authenticate the application with the server. For generating an API key, refer to the **Getting Started** guide. | All requests |
| `Content-Type` | `application/json` | Determines the type of data present in the request body. | `POST`, `PATCH` |
| `Accept` | `application/json` | Determines the acceptable response type from the server. | All requests |


## 4. GET: Fetch Keyword Lists

**Summary (spec):** *"Fetch Keyword List(s) by id. Supports bulk fetch."*
**Response (spec):** `200` → `type: array`, `items: $ref KeywordGroup`

### 4.1 Query parameters

| Parameter | In | Type | Required/Optional | Description |
|  --- | --- | --- | --- | --- |
| `id` | query | String | Required | Comma-separated list of Keyword List id |


### 4.2 Example request — reconstructed

```bash
curl -X GET 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList?id=6a86fd5d670de61b6833e4e9' \
  -H 'Authorization: Bearer {{accessToken}}' \
  -H 'Key: {{apiKey}}' \
  -H 'Accept: application/json'
```

Bulk fetch:

```bash
curl -X GET 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList?id=6a86fd5d670de61b6833e4e9,6a900e0fbd04dae8694504f4' \
  -H 'Authorization: Bearer {{accessToken}}' \
  -H 'Key: {{apiKey}}' \
  -H 'Accept: application/json'
```

### 4.3 Example response

```json
{
  "data": [
    {
      "id": "6a86fd5d670de61b6833e4e9",
      "name": "Competitor Keywords",
      "description": "List of competitor brand names and product terms",
      "conditions": [
        { "term": "rival-brand", "distance": 0, "keywordType": "KEYWORD" },
        { "term": "budget smartphone", "distance": 5, "keywordType": "PROXIMITY_KEYWORD" }
      ],
      "tags": ["competitive-intel", "monitoring"],
      "autoBackfillTopics": false
    }
  ],
  "errors": []
}
```

### 4.4 Response parameters

| Parameter | Sub-parameter | Type | Description |
|  --- | --- | --- | --- |
| `data` | — | Array | List of Keyword List objects returned by the API. |
| `data` | `id` | String | Unique identifier of the Keyword List in Listening. |
| `data` | `name` | String | Keyword List name. |
| `data` | `description` | String | Keyword List description. |
| `data` | `conditions` | Array | Keyword List keyword conditions list. |
| `data.conditions` | `term` | String | Keyword or Phrase. |
| `data.conditions` | `distance` | Integer | Distance for Proximity Keyword. Sets the slop value for Elasticsearch. |
| `data.conditions` | `keywordType` | String | Type of Keyword. Possible values: `KEYWORD`, `PHRASE`, `PROXIMITY_KEYWORD`. |
| `data` | `tags` | Array[String] | Keyword List tags list. |
| `data` | `shareConfigs` | Array | Share config to view Keyword List. |
| `data` | `permissions` | Array | Permission config to edit or update Keyword List. |
| `data` | `autoBackfillTopics` | Boolean | Auto backfill topics which refer this keyword list. |
| `errors` | — | Array | List of errors encountered during request processing. Empty array on success. |


## 5. POST: Create Keyword List

You can create Listening Keyword List via this API call and in response you will get the Keyword List Id and other related objects after making the request.

**Summary (spec):** *"Create a Keyword List."*
**Request body (spec):** `$ref KeywordGroup`, `required: true`
**Response (spec):** `200` → `$ref KeywordGroup`

### 5.1 Request body

The endpoint specification documents four rows; the schema accepts more. Both are shown, with the source of each marked.

| Parameter | Sub-parameter | Required/Optional | Type | Description | Source |
|  --- | --- | --- | --- | --- | --- |
| `name` | N/A | **Required** | String | Name of the Keyword List. | Endpoint spec + schema |
| `conditions` | N/A | **Required** | Array | List of keyword conditions to be included in the Keyword List. | Endpoint spec + schema |
| `conditions` | `term` | **Required** | String | Keyword or phrase to be added to the list. | Endpoint spec |
| `conditions` | `keywordType` | **Required** | String | Type of keyword being added. For example, `KEYWORD`. | Endpoint spec |
| `conditions` | `distance` | Optional | Integer | Distance for Proximity Keyword. Sets the Elasticsearch slop value. Meaningful only with `PROXIMITY_KEYWORD`. | Schema + V2 |
| `description` | N/A | Optional | String | Keyword List description. | Schema + V2 |
| `tags` | N/A | Optional | Array[String] | Keyword List tags list. | Schema + V2 |
| `shareConfigs` | N/A | Optional | Array | Share config to view Keyword List. | Schema |
| `shareConfigs[]` | `type` | Required within object | String | Type e.g. `USER`, `GLOBAL`, `CLIENT`. | Schema |
| `shareConfigs[]` | `ids` | Optional | Array[String] | IDs based on type. | Schema |
| `permissions` | N/A | Optional | Array | Permission config to edit or update Keyword List. Same `AssetShareConfig` shape. | Schema |
| `autoBackfillTopics` | N/A | Optional | Boolean | Auto backfill topics which refer this keyword list. | Schema |


### 5.2 Example request

```bash
curl -X POST 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList' \
  -H 'Authorization: Bearer {{accessToken}}' \
  -H 'Key: {{apiKey}}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{
    "name": "New Keyword List",
    "conditions": [
      {
        "term": "hello",
        "keywordType": "KEYWORD"
      }
    ]
  }'
```

A fuller create, using the optional fields from the schema and the V2 baseline:

```bash
curl -X POST 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList' \
  -H 'Authorization: Bearer {{accessToken}}' \
  -H 'Key: {{apiKey}}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{
    "name": "Competitor Keywords",
    "description": "List of competitor brand names and product terms",
    "conditions": [
      { "term": "rival-brand",       "keywordType": "KEYWORD" },
      { "term": "budget smartphone", "keywordType": "PROXIMITY_KEYWORD", "distance": 5 },
      { "term": "next day delivery", "keywordType": "PHRASE" }
    ],
    "tags": ["competitive-intel", "monitoring"],
    "autoBackfillTopics": false
  }'
```

### 5.3 Example response

```json
{
  "data": {
    "id": "6a86fd5d670de61b6833e4e9",
    "name": "New Keyword List",
    "conditions": [
      {
        "term": "hello",
        "keywordType": "KEYWORD"
      }
    ],
    "tags": [],
    "autoBackfillTopics": false
  },
  "errors": []
}
```

### 5.4 Response parameters

| Parameter | Sub-parameter | Type | Description |
|  --- | --- | --- | --- |
| `data` | `id` | String | Unique identifier of the Keyword List. |
| `data` | `name` | String | Name of the Keyword List. |
| `data` | `conditions` | Array | List of keywords configured in the Keyword List. |
| `data.conditions` | `term` | String | Keyword or phrase included in the list. |
| `data.conditions` | `keywordType` | String | Type of keyword being tracked (for example, `KEYWORD`). |
| `data` | `tags` | Array | List of tags associated with the Keyword List. Empty if no tags are configured. |
| `data` | `autoBackfillTopics` | Boolean | Indicates whether topics associated with the Keyword List are automatically backfilled. |
| `errors` | N/A | Array | Contains any errors encountered during the request. Empty when the request is successful. |


## 6. Keyword types

`keywordType` accepts three values, consistent across the V3 schema and the V2 reference:

| Value | Meaning | Uses `distance`? |
|  --- | --- | --- |
| `KEYWORD` | A single word or token. | No |
| `PHRASE` | An exact multi-word phrase. | No |
| `PROXIMITY_KEYWORD` | Terms matched within a distance of one another. `distance` sets the Elasticsearch slop value. | **Yes** |


## 7. PATCH: Partially Update Keyword List

**Summary (spec):** *"Partially update a Keyword List."*
**Request body (spec):** `$ref ListeningKeywordListPatchRequestDTO`, `required: true`
**Response (spec):** `200` → `type: string`

V3 uses **`PATCH`**; V2 used **`PUT`**. This is an improvement — you no longer send the whole object to change one field.

### 7.1 Query parameters

| Parameter | In | Type | Required (spec) | Description |
|  --- | --- | --- | --- | --- |
| `id` | query | String | Required | Keyword list id |


### 7.2 Request body: Listening Keyword List Patch Request

*"Partial update for a Keyword List"*

| Parameter | Sub-parameter | Required (endpoint spec) | Type | Description |
|  --- | --- | --- | --- | --- |
| `name` | — | No | String | Keyword List name. |
| `description` | — | Not documented | String | Keyword List description. |
| `tags` | — | Not documented | Array[String] | Tags. |
| `conditionsUpdateType` | — | **Yes** | String | Conditions update type: **`UPDATE`** or **`APPEND`**. |
| `conditions` | — | **Yes** | Array[`Condition_KeywordGroupApiEntity`] | Keyword conditions. |
| `conditions` | `term` | **Yes** | String | Keyword or Phrase. |
| `conditions` | `distance` | Not documented | Integer (int32) | Distance for Proximity Keyword. |
| `conditions` | `keywordType` | **Yes** | String | Type of Keyword: `KEYWORD`, `PHRASE`, `PROXIMITY_KEYWORD`. |
| `shareConfig` | — | Not documented | Object (`ShareConfig`) | Share configuration — authorizes users to **view** the Keyword List. |
| `shareConfig` | `userIds` | — | Array[Integer int64] | List of User IDs. |
| `shareConfig` | `userGroupIds` | — | Array[String] | List of User Group IDs. |
| `shareConfig` | `clientIds` | — | Array[Integer int64] | List of Client IDs. |
| `shareConfig` | `clientGroupIds` | — | Array[String] | List of Client Group IDs. |
| `shareConfig` | `shareWithEveryOne` | — | Boolean | Set this true, in order to share with every User. |
| `permissionEntity` | — | Not documented | Object (`PermissionEntity`) | Permission configuration — authorizes users to **edit or update** the Keyword List. Same five sub-fields as `shareConfig`. |


`ListeningKeywordListPatchRequestDTO` declares **no `required` array** — per the specification every field is optional, which is correct for a partial update.

**`conditionsUpdateType` is the most important field on this endpoint.** It is the one V3 concept with no V2 equivalent, and it determines whether your keywords are added to or substituted for the existing set:

| Value | Behaviour |
|  --- | --- |
| `UPDATE` | Per the field name and the endpoint spec's example — the supplied `conditions` **replace** the existing set. |
| `APPEND` | Per the field name — the supplied `conditions` are **added** to the existing set. |


### 7.3 Example request

```bash
curl --location --request PATCH 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList?id=6a900e0fbd04dae8694504f4' \
  --header 'Authorization: Bearer {{accessToken}}' \
  --header 'Key: {{apiKey}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Updated Keyword List",
    "conditionsUpdateType": "UPDATE",
    "conditions": [
      {
        "term": "world",
        "keywordType": "KEYWORD"
      }
    ]
  }'
```

Appending keywords without disturbing the existing set:

```bash
curl -X PATCH 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList?id=6a900e0fbd04dae8694504f4' \
  -H 'Authorization: Bearer {{accessToken}}' \
  -H 'Key: {{apiKey}}' \
  -H 'Content-Type: application/json' \
  --data '{
    "conditionsUpdateType": "APPEND",
    "conditions": [
      { "term": "new-competitor", "keywordType": "KEYWORD" }
    ]
  }'
```

### 7.4 Example response

| Source | Declared response |
|  --- | --- |
| `sprinklr-v3.yaml` | `200 Success`, `application/json`, schema `type: string` |
| Endpoint specification — "Examples Response" | `HTTP/1.1 204 (No Content)` |


Because `PATCH` returns nothing useful, **follow every update with a `GET` if you need to confirm the resulting state** — particularly given the unresolved `conditionsUpdateType` semantics.

## 8. READ Keyword List: Verified GET Scenarios

### 8.1 Retrieve a Keyword List by ID

Retrieves a single Keyword List using its unique identifier.

#### Request Parameters

| Parameter | Sub-parameter | In | Required | Type | Description |
|  --- | --- | --- | --- | --- | --- |
| `id` | N/A | Query | Yes | String | Unique identifier of the Keyword List to retrieve. |


#### Example Request

```bash
curl --location --globoff '{{baseUrl}}/api/v3/listening/keywordList?id=6983038bdc0d4e0888a19de6' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{accessToken}}' \
  --header 'Key: {{apiKey}}'
```

#### Example Response

```json
{
  "data": [
    {
      "id": "6983038bdc0d4e0888a19de6",
      "name": "Dinesh-Test-Keyword-List",
      "conditions": [
        {
          "term": "handcrafted clothing",
          "keywordType": "PHRASE"
        },
        {
          "term": "artisan fashion",
          "keywordType": "PHRASE"
        },
        {
          "term": "unique garments",
          "keywordType": "PHRASE"
        },
        {
          "term": "fashion craftsmanship",
          "keywordType": "PHRASE"
        }
      ],
      "tags": ["Handmade"],
      "shareConfigs": [
        {
          "type": "CLIENT",
          "ids": ["66000002", "66000594", "66000050", "66000437"]
        },
        {
          "type": "CLIENT_GROUP",
          "ids": ["651e76bf7e9c044783e63b81"]
        },
        {
          "type": "USER",
          "ids": ["66070330", "66005588"]
        },
        {
          "type": "USER_GROUP",
          "ids": ["68f9fc3692025a0f44dbf884", "68f9fc2e92025a0f44dbf4a1"]
        }
      ],
      "permissions": [
        {
          "type": "USER",
          "ids": ["66070330", "66005588"]
        },
        {
          "type": "USER_GROUP",
          "ids": []
        },
        {
          "type": "CLIENT",
          "ids": []
        },
        {
          "type": "CLIENT_GROUP",
          "ids": []
        }
      ],
      "autoBackfillTopics": false
    }
  ],
  "errors": []
}
```

### 8.2 Retrieve Multiple Keyword Lists by ID

Retrieves multiple Keyword Lists in one request. Separate identifiers with commas. In a URL-encoded query, `%2C` represents a comma.

#### Request Parameters

| Parameter | Sub-parameter | In | Required | Type | Description |
|  --- | --- | --- | --- | --- | --- |
| `id` | N/A | Query | Yes | String | Comma-separated list of Keyword List IDs. The API returns details for every valid identifier. |


#### Example Request

```bash
curl --location --globoff '{{baseUrl}}/api/v3/listening/keywordList?id=6983038bdc0d4e0888a19de6%2C682afcbcf711cc0bbed19599' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{accessToken}}' \
  --header 'Key: {{apiKey}}'
```

#### Example Response

```json
{
  "data": [
    {
      "id": "6983038bdc0d4e0888a19de6",
      "name": "Dinesh-Test-Keyword-List",
      "conditions": [
        { "term": "handcrafted clothing", "keywordType": "PHRASE" },
        { "term": "artisan fashion", "keywordType": "PHRASE" },
        { "term": "unique garments", "keywordType": "PHRASE" },
        { "term": "fashion craftsmanship", "keywordType": "PHRASE" }
      ],
      "tags": ["Handmade"],
      "shareConfigs": [
        { "type": "CLIENT", "ids": ["66000002", "66000594", "66000050", "66000437"] },
        { "type": "CLIENT_GROUP", "ids": ["651e76bf7e9c044783e63b81"] },
        { "type": "USER", "ids": ["66070330", "66005588"] },
        { "type": "USER_GROUP", "ids": ["68f9fc3692025a0f44dbf884", "68f9fc2e92025a0f44dbf4a1"] }
      ],
      "permissions": [
        { "type": "USER", "ids": ["66070330", "66005588"] },
        { "type": "USER_GROUP", "ids": [] },
        { "type": "CLIENT", "ids": [] },
        { "type": "CLIENT_GROUP", "ids": [] }
      ],
      "autoBackfillTopics": false
    },
    {
      "id": "682afcbcf711cc0bbed19599",
      "name": "Test KW EDI",
      "conditions": [
        { "term": "\"quality\"", "keywordType": "PHRASE" }
      ],
      "tags": [],
      "shareConfigs": [
        { "type": "GLOBAL" }
      ],
      "permissions": [
        { "type": "GLOBAL" }
      ],
      "autoBackfillTopics": false
    }
  ],
  "errors": []
}
```

### 8.3 Retrieve Multiple Keyword Lists with Partial Success

When the query contains valid IDs together with empty, blank, invalid, or unavailable values, the API returns valid Keyword Lists in `data` and item-level failures in `errors`.

#### Request Parameters

| Parameter | Sub-parameter | In | Required | Type | Description |
|  --- | --- | --- | --- | --- | --- |
| `id` | N/A | Query | Yes | String | Comma-separated list that can contain valid IDs, invalid IDs, and empty values. |


#### Example Request

```bash
curl --location --globoff '{{baseUrl}}/api/v3/listening/keywordList?id=6983038bdc0d4e0888a19de6%2C682afcbcf711cc0bbed19599%2C%2C%20%2Ctest%2Cinvalid%2C%20%2C' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{accessToken}}' \
  --header 'Key: {{apiKey}}'
```

#### Example Response

```json
{
  "data": [
    {
      "id": "6983038bdc0d4e0888a19de6",
      "name": "Dinesh-Test-Keyword-List"
    },
    {
      "id": "682afcbcf711cc0bbed19599",
      "name": "Test KW EDI"
    }
  ],
  "errors": [
    {
      "id": "6995bdb9f58d8b601be9edec",
      "code": 400,
      "message": "Invalid id format: ''. Value cannot be empty or blank."
    },
    {
      "id": "6995bdb9f58d8b601be9eded",
      "code": 400,
      "message": "Invalid id format: ' '. Value cannot be empty or blank."
    },
    {
      "id": "6995bdb9f58d8b601be9edee",
      "code": 404,
      "message": "Keyword_list not found for id: 'test'. Verify the keyword_list exists and you have access permissions."
    },
    {
      "id": "6995bdb9f58d8b601be9edef",
      "code": 404,
      "message": "Keyword_list not found for id: 'invalid'. Verify the keyword_list exists and you have access permissions."
    }
  ]
}
```

### 8.4 Retrieve More Than 50 Keyword Lists

A single request supports a maximum of 50 Keyword List identifiers. Split larger sets into batches of no more than 50 identifiers.

#### Request Parameters

| Parameter | Sub-parameter | In | Required | Type | Description |
|  --- | --- | --- | --- | --- | --- |
| `id` | N/A | Query | Yes | String | Comma-separated list of Keyword List IDs. Maximum: 50 identifiers per request. |


#### Example Request

```bash
curl --location --globoff '{{baseUrl}}/api/v3/listening/keywordList?id=id1%2Cid2%2Cid3%2Cid4%2Cid5%2Cid6%2Cid7%2Cid8%2Cid9%2Cid10%2Cid11%2Cid12%2Cid13%2Cid14%2Cid15%2Cid16%2Cid17%2Cid18%2Cid19%2Cid20%2Cid21%2Cid22%2Cid23%2Cid24%2Cid25%2Cid26%2Cid27%2Cid28%2Cid29%2Cid30%2Cid31%2Cid32%2Cid33%2Cid34%2Cid35%2Cid36%2Cid37%2Cid38%2Cid39%2Cid40%2Cid41%2Cid42%2Cid43%2Cid44%2Cid45%2Cid46%2Cid47%2Cid48%2Cid49%2Cid50%2Cid51' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{accessToken}}' \
  --header 'Key: {{apiKey}}'
```

#### Example Response

```json
{
  "errors": [
    {
      "id": "6995bdc9f58d8b601be9edf2",
      "code": 400,
      "message": "Maximum of 50 keyword_list identifiers supported per request. Provided: 51. Consider splitting you request in batches of 50 identifiers per request"
    }
  ]
}
```

### 8.5 READ Response Parameters

| Parameter | Sub-parameter | Type | Description |
|  --- | --- | --- | --- |
| `data` | N/A | Array | Keyword Lists successfully returned by the API. |
| `data[]` | `id` | String | Unique identifier of the Keyword List. |
| `data[]` | `name` | String | Name of the Keyword List. |
| `data[]` | `conditions` | Array | Keyword conditions configured in the list. |
| `data[].conditions[]` | `term` | String | Keyword or phrase included in the list. |
| `data[].conditions[]` | `distance` | Integer | Proximity distance for a `PROXIMITY_KEYWORD`, when returned. |
| `data[].conditions[]` | `keywordType` | String | Keyword condition type, such as `KEYWORD`, `PHRASE`, or `PROXIMITY_KEYWORD`. |
| `data[]` | `tags` | Array | Tags associated with the Keyword List. |
| `data[]` | `shareConfigs` | Array | Configuration defining which entities can view the Keyword List. |
| `data[].shareConfigs[]` | `type` | String | Sharing scope. Observed values include `CLIENT`, `CLIENT_GROUP`, `USER`, `USER_GROUP`, and `GLOBAL`. |
| `data[].shareConfigs[]` | `ids` | Array | IDs of entities granted access. Can be omitted for `GLOBAL`. |
| `data[]` | `permissions` | Array | Configuration defining which entities can edit or manage the Keyword List. |
| `data[].permissions[]` | `type` | String | Permission scope. Observed values include `CLIENT`, `CLIENT_GROUP`, `USER`, `USER_GROUP`, and `GLOBAL`. |
| `data[].permissions[]` | `ids` | Array | IDs of entities granted edit permission. Can be omitted for `GLOBAL`. |
| `data[]` | `autoBackfillTopics` | Boolean | Indicates whether topics referencing the Keyword List are automatically backfilled. |
| `errors` | N/A | Array | Item-level errors. Empty when no errors occur. |
| `errors[]` | `id` | String | Unique identifier associated with the error record. |
| `errors[]` | `code` | Integer | Error code indicating the failure type. |
| `errors[]` | `message` | String | Detailed error message describing the failure. |


### 8.6 READ Error Codes

| Code | Description |
|  --- | --- |
| `400` | Invalid request, empty or blank ID, malformed value, or more than 50 identifiers. |
| `401` | Authentication failed. |
| `403` | The caller does not have sufficient permission. |
| `404` | The Keyword List does not exist or is not accessible to the caller. |


## 9. DELETE: Delete Keyword Lists

**Summary (spec):** *"Delete Keyword List(s) by id. Supports bulk delete."*
**Response (spec):** `200` → `type: string`

### 11.1 Query parameters

| Parameter | In | Type | Required (spec) | Description |
|  --- | --- | --- | --- | --- |
| `id` | query | String | `required: false` | Comma-separated keyword list ids |


Bulk delete is an explicit, documented capability — the operation summary says so directly.

### 10.2 Example request — reconstructed

```bash
curl -X DELETE 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList?id=6a86fd5d670de61b6833e4e9' \
  -H 'Authorization: Bearer {{accessToken}}' \
  -H 'Key: {{apiKey}}' \
  -H 'Accept: application/json'
```

Bulk delete:

```bash
curl -X DELETE 'https://api3.sprinklr.com/{env}/api/v3/listening/keywordList?id=6a86fd5d670de61b6833e4e9,6a900e0fbd04dae8694504f4' \
  -H 'Authorization: Bearer {{accessToken}}' \
  -H 'Key: {{apiKey}}' \
  -H 'Accept: application/json'
```

> Both cURLs are **constructed from the specification** and have not been executed.


### 10.3 Example response

The specification declares `200 Success` with schema `type: string`. By analogy with `PATCH` and with the Listening Topic Group `DELETE`, a `204 No Content` is also plausible. **No verified response is available.** Treat any `2xx` as success.

> **Partial success is unrepresentable.** On a bulk delete, a bare string cannot report which of several IDs failed. See [§12, Q25](#12-questions-for-the-api-owner).


## 10. Response format and status codes

### 11.1 Envelopes at a glance

| Operation | Spec-declared `200` schema | Observed body |
|  --- | --- | --- |
| `GET` | `array` of `KeywordGroup` | *(unverified)* `{"data": [ … ], "errors": []}` expected |
| `POST` | `KeywordGroup` | `{"data": { … }, "errors": []}` — **verified** |
| `PATCH` | `string` | `HTTP/1.1 204 (No Content)` |
| `DELETE` | `string` | *(unverified)* |


Only the `POST` row has a verified body, and it **does not match** its declared schema — the specification declares a bare `KeywordGroup`, the server returns an envelope.

### 10.2 The `errors` array

`errors` carries the standard `Error` objects used across Sprinklr V3 and is an **empty array on success**. Always inspect it before assuming a `200` meant complete success — particularly on bulk `GET` and bulk `DELETE`.

### 10.3 Response codes

Declared in `sprinklr-v3.yaml` for all four operations:

| Code | Meaning | Typical cause |
|  --- | --- | --- |
| `200` | Success | The request was processed. Inspect `errors` before assuming complete success. |
| `400` | Bad Request | Malformed JSON; a missing `name` or `conditions` on create; a malformed `id` list; an invalid `keywordType` or `conditionsUpdateType`. |
| `401` | Unauthorized | Missing, expired, or invalid `Authorization` token. |
| `403` | Forbidden | The caller lacks **Keyword Group View** (or the write permission), or is not a Global Admin / Global User — see [§1.4](#14-prerequisites). |
| `404` | Not Found | No Keyword List exists for the supplied `id`. |


## 11. V2 → V3 migration

### 11.1 Endpoint mapping

| V2 operation | V2 endpoint | V3 equivalent |
|  --- | --- | --- |
| Create Keyword List | `POST /api/v2/keyword-list` | `POST /api/v3/listening/keywordList` |
| Read Keyword List | `GET /api/v2/keyword-list/{Id}` | `GET /api/v3/listening/keywordList?id=` |
| Fetch All Keyword Lists | `GET /api/v2/keyword-list` (see the V2 *Fetch All Keyword Lists* page) | `GET /api/v3/listening/keywordList` (omit `id` — **unconfirmed**, see [Q9](#12-questions-for-the-api-owner)) |
| Update Keyword List | `PUT /api/v2/keyword-list/{Id}` | `PATCH /api/v3/listening/keywordList?id=` |
| Delete Keyword List | `DELETE /api/v2/keyword-list/{Id}` | `DELETE /api/v3/listening/keywordList?id=` |