- Applies to: Sprinklr Listening Theme API, version 3 (
POST /api/v3/listening/theme), OpenAPI tagListening Theme V3 - V2 API reference: Create Theme 2.0 — part of the Listening 2.0 suite (Create Theme · Read Theme · Update Theme · Delete Theme)
A registered API application with a service account — see Getting Started on the developer portal.
An OAuth access token and an API key.
The Create Theme permission. Per How to access Listening Themes?, Theme permissions sit under permission category Conversations, permission type Listening Settings:
Permission Allows Create Theme Create new Listening Themes Edit Theme Edit existing Listening Themes Delete Theme Delete existing Themes View Theme View Themes Server routing records the server type and backing store for each Listening V3 entity:
V3 API Module / Entity (UI) Permission (UI name) Server type Collection / store Listening Topic Listening Settings View LISTENINGlisteningTopicListening Topic Group Listening Settings View LISTENINGlisteningGroupListening Theme Listening Settings Theme View LISTENINGlisteningThemeListening Backfill Listening Settings View (or Topic Backfill) LISTENINGhistoricBackfillKeyword List Listening Settings Keyword Group View DEFAULTkeywordGroupAlert Alert Manager View or Admin DEFAULTalert
A Listening Theme is a set of keywords and filters that can be used to sort Listening Insights data across a pre-built area of focus. Consider Themes like a sub-topic or a lens that can be associated to slice and dice your topics around different aspects and attributes
The critical property, and the reason Themes exist as a separate entity from Topics:
Listening Themes helps to visualize data without changing what a Topic pulls into the Sprinklr platform.
A Topic controls ingestion — it determines which conversations enter Sprinklr at all. A Theme is a read-time lens over data a Topic has already collected. Creating, changing, or deleting a Theme therefore never changes your ingested volume or your data bill; it changes only how existing mentions are segmented for analysis. Typical Themes are segments such as Product Quality, Customer Service, Pricing, or Delivery.
For more information, refer to Introduction to Listening Themes
Keyword List ──┐
├──> Topic ──> ingests mentions ──> Theme ──> segments them for analysis
Boolean query ─┘ │
└──> applied to dashboards, widgets,
alerts, and rules (via Theme Tags)Themes are step 5 — applied after Topics exist and are collecting.
The UI offers two creation routes, per Create Listening Themes: the Theme builder, and the Theme Library, which contains "5000+ readily available Themes based on various categories and different industries." There is also Bulk Import Themes and AI+ automatic Theme framework creation.
Reach for the API when you need to:
- Provision programmatically — create the same Theme taxonomy across many environments or client accounts.
- Sync from an external source — mirror a product taxonomy, a CRM category tree, or a support-ticket schema into Themes.
- Version-control your taxonomy — keep Theme definitions in Git and apply them via CI.
- Generate Themes — create one Theme per SKU, region, or campaign from a data source, at a volume that makes manual creation impractical.
The UI is better when a human needs the Theme Editor's live preview, which the API has no equivalent of: "the Theme Editor UI has preview support, meaning social posts, conversations, smart clusters, etc., can be previewed immediately while creating the Themes." There is no API dry-run.
{base}stands for the host and environment prefix resolved.- Credentials always appear as
{{accessToken}}and{{apiKey}}placeholders. Never paste a real key into a shared document or a ticket. - Fields are shown exactly as they appear in
sprinklr-v3.yaml; casing is significant.
{base} = https://{host}/{env}| Segment | Value |
|---|---|
{host} | Issued with your application registration. The V2 Create Theme page documents api3.sprinklr.com. |
{env} | Your environment prefix. |
Full create URL:
POST https://api3.sprinklr.com/{env}/api/v3/listening/themeAll API calls are authenticated with OAuth 2.0. See Developer Tools in Sprinklr for API key and secret generation, and the Authorize flow.
| Header | Value | Purpose | Required on |
|---|---|---|---|
Authorization | Bearer {{accessToken}} | Authenticates the user with the server | All requests |
Key | {{apiKey}} | The API key acts as both a unique identifier and a secret token for authentication to a set of access rights | All requests |
Content-Type | application/json | Request format should be JSON, as the endpoint expects a JSON body | POST, PUT |
Accept | application/json | Declares the acceptable response type | All requests |
Summary. Create a Listening Theme. operationId. ListeningThemeApiV3_createTheme Request body. ListeningTheme, required. Response. 200 with a ListeningTheme. Declared errors. 400, 401, 403, 404. V2 reference. Create Theme 2.0
The V2 page describes the contract precisely, and it holds in V3:
"You can create a Listening Theme via this API call and you will get the complete Listening Theme object along with unique Theme Id as response after making the request."
So the response is the full object, not just an id — read id from it and store that as your handle for later GET, PATCH, and DELETE calls.
None. The create operation declares no path, query, header, or parameters. Everything travels in the body.
This differs from the other three methods on this path, all of which take an id query parameter.
ListeningTheme declares exactly two required properties:
required:
- name
- filtersEverything else is optional. A minimum viable create body is:
{
"name": "customer_service",
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{
"advanceQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")",
"textQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")"
}
]
}
]
}curl -X POST \
'https://api3.sprinklr.com/{env}/api/v3/listening/theme' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"name": "ListeningThemeAPITest",
"displayName": "Customer Service",
"color": "#4CAF50",
"iconUrl": "https://cdn.example.com/icons/customer-service.png",
"description": "Customer service related conversations and inquiries",
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{
"advanceQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")",
"textQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")"
}
]
}
],
"tags": ["cs", "support", "priority"],
"shareConfigs": [
{ "type": "USER", "ids": ["600000000"] }
],
"permissions": [
{ "type": "USER", "ids": ["600000000"] }
]
}'Illustrative example. Values are placeholders; substitute your own ids, keyword-list ids, and credentials.
{
"id": "60486cef06ebe67ed55c4140",
"name": "ListeningThemeAPITest",
"displayName": "Customer Service",
"color": "#4CAF50",
"iconUrl": "https://cdn.example.com/icons/customer-service.png",
"description": "Customer service related conversations and inquiries",
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{
"advanceQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")",
"textQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")"
}
],
"details": {}
}
],
"tags": ["cs", "support", "priority"],
"shareConfigs": [
{ "type": "USER", "ids": ["600000000"] }
],
"permissions": [
{ "type": "USER", "ids": ["600000000"] }
]
}Note what the V2 response echoed back that the V3 schema does not model: V2 returned filter sub-fields userFilter, allValuesAllowed, favourite, mandatory, locked, and details populated with server defaults. Filter_shifu models only filterType, field, values, details, and filters. If the server still returns those extra keys, your JSON parser must tolerate unmodelled properties.
This is the create request body and the response body. Unusually for the V3 contract, every property carries a description in the spec.
| Field | Type | Required | Description (from sprinklr-v3.yaml) |
|---|---|---|---|
id | string | — | Unique identifier of the Listening Theme in Sprinklr. Server-assigned; omit on create. |
name | string | Required | Listening Theme name. |
displayName | string | Optional | Listening Theme display name. |
iconUrl | string | Optional | Listening Theme icon url. |
imageUrl | string | Optional | Listening Theme image url. |
color | string | Optional | Listening Theme identification color. |
filters | array of Filter_shifu | Required | Filter list to filter out required data. |
description | string | Optional | Listening Theme description. |
tags | array of string | Optional | Tags to group Listening Theme based on use case. |
shareConfigs | array of AssetShareConfig | Optional | Share config to view Listening Theme. |
permissions | array of AssetShareConfig | Optional | Permission config to edit or update Listening Theme. |
Schema description: "Unified view of a Listening Theme in Sprinklr."
The spec distinguishes them but does not say how they differ in behaviour. The V2 example is instructive: "name": "ListeningThemeAPITest" alongside "displayName": "sampleCreateThemeDisplayName1" — a machine-ish identifier and a human label.Read Theme example follows the same pattern: "name": "customer_service", "displayName": "Customer Service".
Recommended convention: use name as a stable, lower-case, underscore-separated key you control, and displayName as the label analysts see. Whether name must be unique per environment is unspecified.
Plain array of strings on the wire. In the product these become Theme Tags, which are considerably more powerful than the flat type suggests. Per Using Themes:
"Theme Tags can be used across the Listening module to group and use multiple Themes at once. They can be used as — Filters in dashboards, Dimensions in widgets, Filters in alerts, Conditions in rules."
Tag deliberately. A tag applied at create time is what later lets a dashboard filter, a widget dimension, an alert, or a rule address a whole family of Themes at once, without enumerating ids.
Presentation metadata surfaced in the Themes record manager and in dashboards. color is documented as the "identification color"; the V2 example uses "#FFFFF" — five hex digits, which is not a valid CSS hex colour. Read example uses a valid six-digit "#4CAF50". This guide uses six digits. Whether the field is validated is unknown. See §18, Q9.
filters is one of the two required fields and the one most likely to cause a 400. It is an array of Filter_shifu.
Schema description: "Describes the schema for filters in Sprinklr."
| Field | Type | Description |
|---|---|---|
filterType | string | Filter type. |
field | string | Specifies field on which filter is applied. |
values | array of object | Specifies values for this filter. |
details | object (string → object) | Additional details for filter. |
filters | array of Filter_shifu | Nested filters — the schema is recursive. |
Specification gap — no enums anywhere.
filterTypeandfieldare declared as barestringwith no enum, andvaluesis an array of untypedobject. The V3 contract will accept any string for either. The only known-good combination in any source is the one from the V2 Create Theme example, reproduced below.
The V2 page's working example:
{
"filterType": "IN",
"field": "QUERY",
"values": [
{
"advanceQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")",
"textQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")"
}
]
}Reading that: field: "QUERY" says filter on the query expression; filterType: "IN" says match against the supplied values; and each value object carries a paired advanceQuery and textQuery, both set to the same expression. The expression keyword_list_or("<keywordListId>") matches a mention if any keyword in that Keyword List matches — which is how a Theme reuses a Keyword List rather than restating its keywords.
Note the pairing of advanceQuery and textQuery. The V2 example sets both to the identical string, and this guide does the same. Their intended difference is undocumented. See §18, Q10.
The PATCH request schema uses a different filter type, Filter_request, whose filterType does carry an enum — FilterType_Filter:
FILTER · LIMIT · SEARCH · MATCH_PHRASE_PREFIX · ADHOC_SEARCH ·
EXPRESSION · GEO_DISTANCE · ADVANCED_QUERY · MATCH_NONE · MATCH_ALLFilter_request also carries fifteen properties Filter_shifu lacks — displayName, isCompoundFilter, negativeFilter, accessibleValues, userFilter, allValuesAllowed, lockedWithValues, hidden, favourite, mandatory, locked, ignoreAddingToDimensionFilter, disabled, and advancedFilters. Several of those (userFilter, allValuesAllowed, favourite, mandatory, locked) are exactly the keys the V2 create response echoed back, which suggests Filter_request is closer to the real internal model and Filter_shifu is a reduced projection.
Both filter schemas are recursive via their own filters property, so compound logic is expressible by nesting. No source supplies a worked nested example, and Filter_shifu has no negativeFilter or isCompoundFilter flag to declare how children combine — Filter_request has both. How nested Filter_shifu children are combined (AND, OR) is unspecified. Prefer a single advanceQuery expression with Boolean operators over nesting until this is confirmed.
The Help Center documents Creating location-based Themes:
"In Listening Themes, you have the ability to filter data on the basis of the location of a message. Messages can be filtered out for a specific location by selecting the latitude, longitude, and radius of the search (in kilometers or miles). Note: To learn more about getting this capability enabled…"
FilterType_Filter includes GEO_DISTANCE, which is plainly the mechanism. But no source documents the field name or the values shape (latitude, longitude, radius, unit) for a geo filter, and the capability requires enablement. Build geo Themes in the UI and read them back with GET to learn the exact shape.
Two optional arrays control who can see and who can edit a Theme. Both use the same AssetShareConfig schema.
| Field | Purpose (from the spec) |
|---|---|
shareConfigs | "Share config to view Listening Theme" |
permissions | "Permission config to edit or update Listening Theme" |
Schema description: "Describes the schema for Asset Share config."
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Required | Type e.g. USER, GLOBAL, CLIENT. |
ids | array of string | Optional | IDs based on type. |
type is required whenever you supply an entry. The description gives three examples — USER, GLOBAL, CLIENT — introduced with *"e.g.", so the list is illustrative, not exhaustive, and there is no enum. The V2 model additionally distinguished user groups and client groups; whether V3 expresses those as further type values (USER_GROUP, CLIENT_GROUP) is not stated anywhere. See §18, Q14.
"shareConfigs": [
{ "type": "USER", "ids": ["600000000", "600037831"] },
{ "type": "CLIENT", "ids": ["66000002"] }
]V2 had an explicit boolean, shareConfig.shareWithEveryOne. AssetShareConfig has no boolean at all. The likely V3 equivalent is {"type": "GLOBAL"} — possibly with ids omitted, since ids is optional and a global share has no specific target. This is inference from the type name, not documented behaviour.
In V2, user and client ids were List<Long> — JSON numbers. In V3, AssetShareConfig.ids is an array of string. Quote your ids:
- "userIds": [600000000]
+ "ids": ["600000000"]A client that forwards V2 numeric ids into the V3 array will send numbers where strings are expected. Whether the server coerces them is unverified — quote them and avoid the question.
Note also the errors array. V2 returned "errors": [] on success, which implies a partial-success mode where a 200 carries errors. Always inspect errors even on 200. Its element shape is undocumented. See §18, Q17.
| Code | Meaning | Declared? |
|---|---|---|
200 | Success — theme created, full object returned. | Yes |
400 | Bad Request — malformed body, missing name or filters, invalid filter. | Yes |
401 | Unauthorized — missing, expired, or invalid token. | Yes |
403 | Forbidden — authenticated but lacking the Create Theme permission. | Yes |
404 | Not Found — declared on create, though its meaning there is unclear. | Yes |
429 | Rate limited. | Not declared |
500 | Server error. | Not declared |
All four operations return the same error schema for 400, 401, 403, and 404 — the shared ErrorResponse component.
| Response | Description (from sprinklr-v3.yaml) | Schema |
|---|---|---|
BadRequest (400) | Bad request | ErrorResponse |
Unauthorized (401) | Missing or invalid authentication | ErrorResponse |
Forbidden (403) | Insufficient permissions | ErrorResponse |
NotFound (404) | Resource not found | ErrorResponse |
ErrorResponse:
| Field | Type | Description |
|---|---|---|
data | object, nullable | Null or empty on an error. |
errors | array of Error | The failures. |
metadata | object | Undescribed in the spec. |
Error — all three properties are required:
| Field | Type | Description (from sprinklr-v3.yaml) |
|---|---|---|
id | string | 24-character hex ObjectId |
code | integer | — (no description) |
message | string | Dotted error key (e.g. account.not.found) |
{
"data": null,
"errors": [
{
"id": "66badc8a6df5bf43f6c8f374",
"code": 400,
"message": "listening.theme.name.required"
}
],
"metadata": {}
}Illustrative — the shape is from the schema, the literal values are invented. No source publishes the code values or the message keys for Listening Theme.
Specification gap — no error catalogue. No source publishes the
codevalues ormessagekeys this API emits, so you cannot write exhaustive error handling in advance. Log the fullerrorsarray on every failure and build your catalogue from observed traffic. See §16, Q33.
Summary. Fetch Listening Theme(s) by id. Supports bulk fetch. operationId. ListeningThemeApiV3_getThemes Request body. None. Response. 200 with an array of ListeningTheme. Declared errors. 400, 401, 403, 404. V2 reference. Read Theme 2.0, part of the Listening 2.0 suite.
This is the only Theme operation with a Jira description, a worked example, and recorded production verification. It is also, paradoxically, the operation whose documented response least resembles the OpenAPI schema.
| Parameter | In | Type | Required (spec) | Description (from sprinklr-v3.yaml) |
|---|---|---|---|---|
id | query | string | false | Comma-separated list of Listening Theme id |
The parameter description — "Comma-separated list of Listening Theme id" — is what makes this operation bulk-capable, and the response is typed as an array even for a single id. Always iterate the result; never index [0] blindly.
curl -X GET \
'https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=66badc8a6df5bf43f6c8f374,60486cef06ebe67ed55c4140' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Accept: application/json'No source states an upper bound on how many ids one call accepts, whether the ids must all resolve, or what happens when one id in the list is invalid — does the whole call 404, or does it return the ones that resolved and report the rest in errors?
Nor is there any pagination, sorting, or filtering mechanism on this operation: no page, limit, offset, sort, or name-search parameter is declared. If you do not already know a Theme's id, the V3 API as specified gives you no documented way to discover it.
Per the OpenAPI document, the 200 body is an array of ListeningTheme objects:
[
{
"id": "66badc8a6df5bf43f6c8f374",
"name": "customer_service",
"displayName": "Customer Service",
"iconUrl": "https://cdn.example.com/icons/customer-service.png",
"color": "#4CAF50",
"description": "Customer service related conversations and inquiries",
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{ "advanceQuery": "support OR help OR issue", "textQuery": "support OR help OR issue" }
],
"details": {}
}
],
"tags": ["cs", "support", "priority"],
"shareConfigs": [ { "type": "USER", "ids": ["600000000"] } ],
"permissions": [ { "type": "USER", "ids": ["600000000"] } ]
}
]Illustrative, constructed from the OpenAPI schema.
This deserves its own subsection, because it is the sharpest source disagreement in this guide and it affects anyone writing a response parser.
| Field in the ticket example | In ListeningTheme? | Notes |
|---|---|---|
appliedToTopics | No | Array of topic ids. Would be the Theme→Topic association — a genuinely useful field with no schema counterpart. |
workflow | No | A whole nested object, described below. |
workflow.assignment | No | {assigneeId, assigneeType, assignedById, assignmentTime}. |
workflow.customProperties | No | Map of string → array of string. |
workflow.permissions | No | {type, id, role} — singular id, plus a role. |
workflow.tags | Top-level only | The ticket nests tags inside workflow; the schema has it at the top level. |
workflow.shareConfig | No | {sharedWithTeams, visibility}. |
createdBy, modifiedBy | No | Audit metadata. |
createdTime, modifiedTime | No | Epoch-millisecond timestamps. |
active | No | Boolean. |
deleted | No | Boolean — the same field the V2 create example carried. |
And three fields that exist but in a different shape:
filtersis an object, not an array. The ticket shows"filters": {"keywords": [...], "sentiment": [...], "priority": "HIGH"}. The schema says array ofFilter_shifu. The V2 page shows an array of{filterType, field, values}. That is three mutually incompatible shapes for the single most important field on the entity.- The id field is called
themeId. The ticket's response-fields table liststhemeIdas "The unique identifier of the Listening Theme", while the ticket's own JSON example usesidand the schema usesid. shareConfigis singular and differently shaped — a fourth variant,{sharedWithTeams, visibility}, alongside the create model (shareConfigsarray of{type, ids}), the patch model (shareConfigobject of id lists), and the V2 model.
How to read this. The ticket's example JSON is also syntactically malformed — the id line reads id": "66badc8a… with the opening quote missing — which indicates it was hand-written into the ticket rather than captured from a live response. Combined with the invented workflow envelope and the themeId/id mismatch inside a single section, the example should be treated as illustrative prose, not observed behaviour.
Per this programme's precedence rule, the OpenAPI document outranks Jira description text, so this guide documents the schema shape. But the risk cuts both ways: if any part of the ticket example reflects reality, a strict parser bound to ListeningTheme will break. Parse permissively — tolerate unknown properties, and do not fail on a filters value that arrives as an object.
The following request and response scenarios supplement the GET contract with tested single-ID, multiple-ID, partial-success, and request-limit examples.
Request Parameters
| Parameter | Sub-parameter | Required | Type | Description |
|---|---|---|---|---|
| id | N/A | Yes | String | Unique identifier of the Listening Theme to retrieve. Pass the theme ID as a query parameter in the request URL. |
curl --location '<{{baseUrl}}/api/v3/listening/theme?id=69957998530c7a6ee53206eb>' \\
--header 'Accept: application/json' \\
--header 'Authorization: Bearer {{accessToken}}' \\
--header 'Key: {{apiKey}}' \\{
"data": \[
{
"id": "69957998530c7a6ee53206eb",
"name": "Theme_Search_1771403672289",
"filters": \[
{
"filterType": "IN",
"field": "QUERY",
"values": \[
{
"advanceQuery": "Google AND Facebook",
"textQuery": "(\\Google\\ AND \\Facebook\\)",
"themesInQuery": \[\]
}
\],
"details": {
"raw_search": false,
"type": "criteria"
},
"filters": \[\]
}
\],
"tags": \[
"ALERT_TAG_DND"
\],
"shareConfigs": \[
{
"type": "GLOBAL"
}
\]
}
\],
"errors": \[\]
}| Parameter | Sub-parameter | Type | Description |
|---|---|---|---|
| data | N/A | Array | List of Listening Theme objects returned by the API. |
| data | id | String | Unique identifier of the theme. |
| data | name | String | Name of the theme. |
| data | filters | Array | List of filters associated with the theme. |
| data.filters | filterType | String | Filter operator applied to the field. Example: IN. |
| data.filters | field | String | Dimension or field on which the filter is applied. |
| data.filters | values | Array | List of values used for filtering. |
| data.filters.values | advanceQuery | String | Advanced query definition used by the theme. |
| data.filters.values | textQuery | String | Parsed text representation of the query. |
| data.filters.values | themesInQuery | Array | List of referenced themes used within the query. |
| data.filters | details | Object | Additional filter configuration details. |
| data.filters.details | raw_search | Boolean | Indicates whether raw search is enabled. |
| data.filters.details | type | String | Type of filter criteria configured. |
| data.filters | filters | Array | Nested filters applied within the current filter. Returns an empty array when no nested filters exist. |
| data | tags | Array | List of tags associated with the theme. |
| data | shareConfigs | Array | Sharing configuration for the theme. |
| data.shareConfigs | type | String | Sharing scope for the theme. Example: GLOBAL. |
| errors | N/A | Array | List of errors encountered during request processing. Returns an empty array when the request is successful. |
curl --location '<{{baseUrl}}/api/v3/listening/theme?id=69957998530c7a6ee53206eb>' \\
--header 'Accept: application/json' \\
--header 'Authorization: Bearer {{accessToken}}' \\
--header 'Key: {{apiKey}}' \\| Parameter | Sub-parameter | Required | Type | Description |
|---|---|---|---|---|
| id | N/A | Yes | String | Unique identifier of the Listening Theme to retrieve. Pass the Theme ID as a query parameter in the request URL. |
{
"data": \[
{
"id": "69957998530c7a6ee53206eb",
"name": "Theme_Search_1771403672289",
"filters": \[
{
"filterType": "IN",
"field": "QUERY",
"values": \[
{
"advanceQuery": "Google AND Facebook",
"textQuery": "(\\Google\\ AND \\Facebook\\)",
"themesInQuery": \[\]
}
\],
"details": {
"raw_search": false,
"type": "criteria"
},
"filters": \[\]
}
\],
"tags": \[
"ALERT_TAG_DND"
\],
"shareConfigs": \[
{
"type": "GLOBAL"
}
\]
}
\],
"errors": \[\]
}| Parameter | Sub-parameter | Type | Description |
|---|---|---|---|
| data | N/A | Array | List of Listening Theme objects returned by the API. |
| data | id | String | Unique identifier of the theme. |
| data | name | String | Name of the theme. |
| data | filters | Array | List of filters associated with the theme. |
| data.filters | filterType | String | Filter operator applied to the field. Example: IN. |
| data.filters | field | String | Dimension or field on which the filter is applied. |
| data.filters | values | Array | List of values used for filtering. |
| data.filters.values | advanceQuery | String | Advanced query expression used in the theme filter. |
| data.filters.values | textQuery | String | Text representation of the advanced query. |
| data.filters.values | themesInQuery | Array | List of referenced themes used within the query. |
| data.filters | details | Object | Additional filter configuration details. |
| data.filters.details | raw_search | Boolean | Indicates whether raw search mode is enabled. |
| data.filters.details | type | String | Type of filter configuration. Example: criteria. |
| data.filters | filters | Array | Nested filters defined within the current filter. Returns an empty array when no nested filters exist. |
| data | tags | Array | List of tags associated with the theme. |
| data | shareConfigs | Array | Sharing configuration for the theme. |
| data.shareConfigs | type | String | Sharing scope of the theme. Example: GLOBAL. |
| errors | N/A | Array | List of errors encountered during request processing. Returns an empty array when the request succeeds. |
curl --location --globoff '{{baseUrl}}/api/v3/listening/theme?id=6995af98d7890350f0d74510' \\
--header 'Accept: application/json' \\
--header 'Authorization: Bearer {{accessToken}}' \\
--header 'Key: {{apiKey}}'
**Request Parameters**
| **Parameter** | **Sub-parameter** | **Required** | **Type** | **Description** |
|----|----|----|----|----|
| id | N/A | Yes | String | Unique identifier of the Listening Theme to retrieve. Pass the Theme ID as a query parameter in the request URL |{
"data": \[
{
"id": "6995af98d7890350f0d74510",
"name": "Test-Theme-with-API",
"displayName": "Test-Theme-with-API",
"color": "#ca6969",
"filters": \[
{
"filterType": "IN",
"field": "QUERY",
"values": \[
{
"orConditions": \[
{
"topicKeywords": \[\],
"operator": "AND",
"keywordGroupsRef": \[
{
"keywordGroupId": "67e657633d78d4090467b7e0",
"operator": "AND"
}
\],
"ordered": false,
"nearDistance": 0
}
\],
"andConditions": \[
{
"topicKeywords": \[\],
"operator": "OR",
"keywordGroupsRef": \[
{
"keywordGroupId": "6983038bdc0d4e0888a19de6",
"operator": "OR"
}
\],
"ordered": false,
"nearDistance": 0
}
\],
"excludeConditions": \[
{
"topicKeywords": \[
{
"term": "black",
"keywordType": "EXCLUDE_KEYWORD",
"distance": 0
}
\],
"operator": "OR",
"keywordGroupsRef": \[\],
"ordered": false,
"nearDistance": 0
}
\],
"textQuery": "(\\Rolex\\ AND (\\handcrafted clothing\\ OR \\artisan fashion\\ OR \\unique garments\\ OR \\fashion craftsmanship\\) AND NOT \\black\\)",
"themesInQuery": \[\]
}
\],
"details": {
"type": "criteria"
},
"filters": \[\]
},
{
"filterType": "IN",
"field": "POINT_RADIUS_LOCATION",
"values": \[
{
"type": "POINT_RADIUS",
"locationName": "G33W+946 Ambience Island, DLF Phase 3, Sector 24, Gurugram, Haryana, India",
"latitude": 28.5034,
"longitude": 77.0953,
"radius": 10,
"unit": "mi",
"id": "28.5034_77.0953"
}
\],
"details": {},
"filters": \[\]
}
\],
"tags": \[
"Air Travel Preferences",
"Credit Products - Retail Bank"
\]
}
\],
"errors": \[\]
}| Parameter | Sub-parameter | Type | Description |
|---|---|---|---|
| data | N/A | Array | List of Listening Theme objects returned by the API. |
| data | id | String | Unique identifier of the theme. |
| data | name | String | Internal name of the theme. |
| data | displayName | String | Display name of the theme shown in the user interface. |
| data | color | String | Hex color code associated with the theme. |
| data | filters | Array | List of filters associated with the theme. |
| data.filters | filterType | String | Filter operator applied to the field. Example: IN. |
| data.filters | field | String | Dimension or field on which the filter is applied. |
| data.filters | values | Array | List of values used for filtering. |
| data.filters.values | orConditions | Array | Collection of OR conditions used in the query definition. |
| data.filters.values.orConditions | topicKeywords | Array | List of topic keywords included in the condition. |
| data.filters.values.orConditions | operator | String | Logical operator applied to the condition. |
| data.filters.values.orConditions | keywordGroupsRef | Array | References to keyword groups used in the condition. |
| data.filters.values.orConditions.keywordGroupsRef | keywordGroupId | String | Unique identifier of the referenced keyword group. |
| data.filters.values.orConditions.keywordGroupsRef | operator | String | Logical operator associated with the keyword group. |
| data.filters.values.orConditions | ordered | Boolean | Indicates whether keyword ordering is enforced. |
| data.filters.values.orConditions | nearDistance | Integer | Distance value used with proximity-based matching. |
| data.filters.values | andConditions | Array | Collection of AND conditions used in the query definition. |
| data.filters.values | excludeConditions | Array | Collection of exclusion conditions used in the query definition. |
| data.filters.values.excludeConditions.topicKeywords | term | String | Excluded keyword term. |
| data.filters.values.excludeConditions.topicKeywords | keywordType | String | Excluded keyword type. |
| data.filters.values.excludeConditions.topicKeywords | distance | Integer | Distance value for the excluded keyword. |
| data.filters.values | textQuery | String | Human-readable representation of the complete query. |
| data.filters.values | themesInQuery | Array | Referenced themes used within the query. |
| data.filters | details | Object | Additional filter configuration details. |
| data.filters.details | type | String | Filter configuration type. |
| data.filters | filters | Array | Nested filters associated with the current filter. |
| data.filters | field | String | Can also represent location-based fields such as POINT_RADIUS_LOCATION. |
| data.filters.values | type | String | Location filter type. Example: POINT_RADIUS. |
| data.filters.values | locationName | String | Name of the configured location. |
| data.filters.values | latitude | Double | Latitude coordinate of the location. |
| data.filters.values | longitude | Double | Longitude coordinate of the location. |
| data.filters.values | radius | Integer | Radius around the location. |
| data.filters.values | unit | String | Unit used for the radius (for example, mi). |
| data.filters.values | id | String | Unique identifier of the location filter. |
| data | tags | Array | List of tags associated with the theme. |
| errors | N/A | Array | List of errors encountered during request processing. Returns an empty array when the request succeeds |
Request Parameters
| Parameter | Sub-parameter | Required | Type | Description |
|---|---|---|---|---|
| id | N/A | Yes | String | Comma-separated list of Listening Theme IDs to retrieve. The API returns details for each valid Theme identifier provided. |
curl --location --globoff '{{baseUrl}}/api/v3/listening/theme?id=69957998530c7a6ee53206eb%2C6995af98d7890350f0d74510' \\
--header 'Accept: application/json' \\
--header 'Authorization: Bearer {{accessToken}}' \\
--header 'Key: {{apiKey}}'{
"data": \[
{
"id": "69957998530c7a6ee53206eb",
"name": "Theme_Search_1771403672289",
"filters": \[
{
"filterType": "IN",
"field": "QUERY",
"values": \[
{
"advanceQuery": "Google AND Facebook",
"textQuery": "(\\Google\\ AND \\Facebook\\)",
"themesInQuery": \[\]
}
\],
"details": {
"raw_search": false,
"type": "criteria"
},
"filters": \[\]
}
\],
"tags": \[
"ALERT_TAG_DND"
\],
"shareConfigs": \[
{
"type": "GLOBAL"
}
\]
},
{
"id": "6995af98d7890350f0d74510",
"name": "Test-Theme-with-API",
"displayName": "Test-Theme-with-API",
"color": "#ca6969",
"filters": \[
{
"filterType": "IN",
"field": "QUERY",
"values": \[
{
"orConditions": \[
{
"topicKeywords": \[\],
"operator": "AND",
"keywordGroupsRef": \[
{
"keywordGroupId": "67e657633d78d4090467b7e0",
"operator": "AND"
}
\],
"ordered": false,
"nearDistance": 0
}
\],
"andConditions": \[
{
"topicKeywords": \[\],
"operator": "OR",
"keywordGroupsRef": \[
{
"keywordGroupId": "6983038bdc0d4e0888a19de6",
"operator": "OR"
}
\],
"ordered": false,
"nearDistance": 0
}
\],
"excludeConditions": \[
{
"topicKeywords": \[
{
"term": "black",
"keywordType": "EXCLUDE_KEYWORD",
"distance": 0
}
\],
"operator": "OR",
"keywordGroupsRef": \[\],
"ordered": false,
"nearDistance": 0
}
\],
"textQuery": "(\\Rolex\\ AND (\\handcrafted clothing\\ OR \\artisan fashion\\ OR \\unique garments\\ OR \\fashion craftsmanship\\) AND NOT \\black\\)",
"themesInQuery": \[\]
}
\],
"details": {
"type": "criteria"
},
"filters": \[\]
},
{
"filterType": "IN",
"field": "POINT_RADIUS_LOCATION",
"values": \[
{
"type": "POINT_RADIUS",
"locationName": "G33W+946 Ambience Island, DLF Phase 3, Sector 24, Gurugram, Haryana, India",
"latitude": 28.5034,
"longitude": 77.0953,
"radius": 10,
"unit": "mi",
"id": "28.5034_77.0953"
}
\],
"details": {},
"filters": \[\]
}
\],
"tags": \[
"Air Travel Preferences",
"Credit Products - Retail Bank"
\]
}
\],
"errors": \[\]
}| Parameter | Sub-parameter | Type | Description |
|---|---|---|---|
| data | N/A | Array | List of Listening Theme objects returned by the API. |
| data | id | String | Unique identifier of the theme. |
| data | name | String | Name of the theme. |
| data | displayName | String | Display name of the theme shown in the user interface. |
| data | color | String | Hex color code associated with the theme. |
| data | filters | Array | List of filters associated with the theme. |
| data.filters | filterType | String | Filter operator applied to the field. Example: IN. |
| data.filters | field | String | Dimension or field on which the filter is applied. Examples: QUERY, POINT_RADIUS_LOCATION. |
| data.filters | values | Array | List of values used for filtering. |
| data.filters.values | advanceQuery | String | Advanced query expression used in the theme filter. |
| data.filters.values | textQuery | String | Text representation of the query. |
| data.filters.values | themesInQuery | Array | List of referenced themes used in the query. |
| data.filters.values | orConditions | Array | Collection of OR conditions configured in the query. |
| data.filters.values | andConditions | Array | Collection of AND conditions configured in the query. |
| data.filters.values | excludeConditions | Array | Collection of exclusion conditions configured in the query. |
| data.filters.values.orConditions | topicKeywords | Array | Keywords used in the OR condition. |
| data.filters.values.orConditions | operator | String | Logical operator applied to the condition. |
| data.filters.values.orConditions | keywordGroupsRef | Array | References to keyword groups used in the condition. |
| data.filters.values.orConditions.keywordGroupsRef | keywordGroupId | String | Unique identifier of the referenced keyword group. |
| data.filters.values.orConditions.keywordGroupsRef | operator | String | Logical operator applied to the referenced keyword group. |
| data.filters.values.excludeConditions.topicKeywords | term | String | Excluded keyword term. |
| data.filters.values.excludeConditions.topicKeywords | keywordType | String | Type of excluded keyword. |
| data.filters.values.excludeConditions.topicKeywords | distance | Integer | Distance value for the keyword. |
| data.filters | details | Object | Additional filter configuration details. |
| data.filters.details | raw_search | Boolean | Indicates whether raw search mode is enabled. |
| data.filters.details | type | String | Filter configuration type. |
| data.filters | filters | Array | Nested filters associated with the current filter. |
| data.filters.values | type | String | Location filter type. Example: POINT_RADIUS. |
| data.filters.values | locationName | String | Name of the configured location. |
| data.filters.values | latitude | Double | Latitude coordinate of the location. |
| data.filters.values | longitude | Double | Longitude coordinate of the location. |
| data.filters.values | radius | Integer | Radius around the location. |
| data.filters.values | unit | String | Unit used for the radius. |
| data.filters.values | id | String | Unique identifier of the location filter. |
| data | tags | Array | List of tags associated with the theme. |
| data | shareConfigs | Array | Sharing configuration for the theme. |
| data.shareConfigs | type | String | Sharing scope for the theme. Example: GLOBAL. |
| errors | N/A | Array | List of errors encountered during request processing. Returns an empty array when the request succeeds. |
Request Parameters
| Parameter | Sub-parameter | Required | Type | Description |
|---|---|---|---|---|
| id | N/A | Yes | String | Comma-separated list of Listening Theme IDs to retrieve. The request can include valid IDs, invalid IDs, non-existent IDs, and empty values. The API attempts to retrieve all valid themes and returns errors for invalid entries. |
curl --location --globoff '{{baseUrl}}/api/v3/listening/theme?id=69957998530c7a6ee53206eb%2C6995af98d7890350f0d74510%2CINVALID%2Cabcd%2C%2Ctest%2C6995af98d7890350f0d74511' \\
--header 'Accept: application/json' \\
--header 'Authorization: Bearer {{accessToken}}' \\
--header 'Key: {{apiKey}}'{
"data": \[
{
"id": "69957998530c7a6ee53206eb",
"name": "Theme_Search_1771403672289",
"filters": \[
{
"filterType": "IN",
"field": "QUERY",
"values": \[
{
"advanceQuery": "Google AND Facebook",
"textQuery": "(\\Google\\ AND \\Facebook\\)",
"themesInQuery": \[\]
}
\],
"details": {
"raw_search": false,
"type": "criteria"
},
"filters": \[\]
}
\],
"tags": \[
"ALERT_TAG_DND"
\],
"shareConfigs": \[
{
"type": "GLOBAL"
}
\]
},
{
"id": "6995af98d7890350f0d74510",
"name": "Test-Theme-with-API",
"displayName": "Test-Theme-with-API",
"color": "#ca6969",
"filters": \[
{
"filterType": "IN",
"field": "QUERY",
"values": \[
{
"orConditions": \[
{
"topicKeywords": \[\],
"operator": "AND",
"keywordGroupsRef": \[
{
"keywordGroupId": "67e657633d78d4090467b7e0",
"operator": "AND"
}
\],
"ordered": false,
"nearDistance": 0
}
\],
"andConditions": \[
{
"topicKeywords": \[\],
"operator": "OR",
"keywordGroupsRef": \[
{
"keywordGroupId": "6983038bdc0d4e0888a19de6",
"operator": "OR"
}
\],
"ordered": false,
"nearDistance": 0
}
\],
"excludeConditions": \[
{
"topicKeywords": \[
{
"term": "black",
"keywordType": "EXCLUDE_KEYWORD",
"distance": 0
}
\],
"operator": "OR",
"keywordGroupsRef": \[\],
"ordered": false,
"nearDistance": 0
}
\],
"textQuery": "(\\Rolex\\ AND (\\handcrafted clothing\\ OR \\artisan fashion\\ OR \\unique garments\\ OR \\fashion craftsmanship\\) AND NOT \\black\\)",
"themesInQuery": \[\]
}
\],
"details": {
"type": "criteria"
},
"filters": \[\]
},
{
"filterType": "IN",
"field": "POINT_RADIUS_LOCATION",
"values": \[
{
"type": "POINT_RADIUS",
"locationName": "G33W+946 Ambience Island, DLF Phase 3, Sector 24, Gurugram, Haryana, India",
"latitude": 28.5034,
"longitude": 77.0953,
"radius": 10,
"unit": "mi",
"id": "28.5034_77.0953"
}
\],
"details": {},
"filters": \[\]
}
\],
"tags": \[
"Air Travel Preferences",
"Credit Products - Retail Bank"
\]
}
\],
"errors": \[
{
"id": "6995b00af58d8b601be9ed3e",
"code": 404,
"message": "Listening_theme not found for id: 'INVALID'. Verify the listening_theme exists and you have access permissions."
},
{
"id": "6995b00af58d8b601be9ed3f",
"code": 404,
"message": "Listening_theme not found for id: 'abcd'. Verify the listening_theme exists and you have access permissions."
},
{
"id": "6995b00af58d8b601be9ed3d",
"code": 400,
"message": "Invalid id format: ''. Value cannot be empty or blank."
},
{
"id": "6995b00af58d8b601be9ed40",
"code": 404,
"message": "Listening_theme not found for id: 'test'. Verify the listening_theme exists and you have access permissions."
},
{
"id": "6995b00af58d8b601be9ed41",
"code": 404,
"message": "Listening_theme not found for id: '6995af98d7890350f0d74511'. Verify the listening_theme exists and you have access permissions."
}
\]
}
**Response Parameters**
| **Parameter** | **Sub-parameter** | **Type** | **Description** |
|----|----|----|----|
| data | N/A | Array | List of Listening Theme objects successfully retrieved by the API. |
| data | id | String | Unique identifier of the theme. |
| data | name | String | Name of the theme. |
| data | displayName | String | Display name of the theme shown in the user interface. |
| data | color | String | Hex color code associated with the theme. |
| data | filters | Array | List of filters associated with the theme. |
| data.filters | filterType | String | Filter operator applied to the field. Example: IN. |
| data.filters | field | String | Dimension or field on which the filter is applied. Examples: QUERY, POINT_RADIUS_LOCATION. |
| data.filters | values | Array | List of values used for filtering. |
| data.filters.values | advanceQuery | String | Advanced query expression used in the theme filter. |
| data.filters.values | textQuery | String | Text representation of the query. |
| data.filters.values | themesInQuery | Array | List of referenced themes used within the query. |
| data.filters.values | orConditions | Array | Collection of OR conditions configured in the query. |
| data.filters.values | andConditions | Array | Collection of AND conditions configured in the query. |
| data.filters.values | excludeConditions | Array | Collection of exclusion conditions configured in the query. |
| data.filters | details | Object | Additional filter configuration details. |
| data.filters.details | raw_search | Boolean | Indicates whether raw search mode is enabled. |
| data.filters.details | type | String | Type of filter configuration. |
| data.filters | filters | Array | Nested filters associated with the current filter. |
| data | tags | Array | List of tags associated with the theme. |
| data | shareConfigs | Array | Sharing configuration for the theme. |
| data.shareConfigs | type | String | Sharing scope for the theme (for example, GLOBAL). |
| errors | N/A | Array | List of errors encountered while processing the request. |
| errors | id | String | Unique identifier associated with the error record. |
| errors | code | Integer | Error code indicating the type of validation or lookup failure. |
| errors | message | String | Detailed error message describing the issue. |
### **Error Parameters**
| **Parameter** | **Sub-parameter** | **Type** | **Description** |
|----|----|----|----|
| errors | id | String | Identifier associated with the error entry. |
| errors | code | Integer | HTTP-style error code returned by the API (400, 404). |
| errors | message | String | Human-readable error message describing the validation or lookup failure. |
#### 9.10 Retrieve More Than 50 Themes
**Request Parameters**
| **Parameter** | **Sub-parameter** | **Required** | **Type** | **Description** |
|----|----|----|----|----|
| id | N/A | Yes | String | Comma-separated list of Listening Theme IDs to retrieve. A maximum of **50 theme identifiers** can be provided in a single request. Requests exceeding this limit return a validation error. |
**Example Request**
curl --location --globoff '{{baseUrl}}/api/v3/listening/theme?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**
{
"errors": \[
{
"id": "6995b066f58d8b601be9ed44",
"code": 400,
"message": "Maximum of 50 listening_theme identifiers supported per request. Provided: 51. Consider splitting you request in batches of 50 identifiers per request"
}
\]
}
**Response Parameters**
| **Parameter** | **Sub-parameter** | **Type** | **Description** |
|----|----|----|----|
| errors | N/A | Array | List of errors encountered while processing the request. |
| errors | id | String | Unique identifier associated with the error record. |
| errors | code | Integer | Error code indicating the type of validation failure. |
| errors | message | String | Detailed error message describing the validation error and recommended resolution. |
#### 9.11 Retrieve a Theme with Complete Sharing Configuration
**Request Parameters**
| **Parameter** | **Sub-parameter** | **Required** | **Type** | **Description** |
|----|----|----|----|----|
| id | N/A | Yes | String | Unique identifier of the Listening Theme to retrieve. Pass the Theme ID as a query parameter in the request URL |
#### 9.12 **Example Request**
```bash
curl --location '<{{baseUrl}}/api/v3/listening/theme?id=6995af98d7890350f0d74510>' \\
--header 'Accept: application/json' \\
--header 'Authorization: Bearer {{accessToken}}' \\
--header 'Key: {{apiKey}}' \\{
"data": [
{
"id": "6995af98d7890350f0d74510",
"name": "Test-Theme-with-API",
"displayName": "Test-Theme-with-API",
"color": "#ca6969",
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{
"orConditions": [
{
"topicKeywords": [],
"operator": "AND",
"keywordGroupsRef": [
{
"keywordGroupId": "67e657633d78d4090467b7e0",
"operator": "AND"
}
],
"ordered": false,
"nearDistance": 0
}
],
"andConditions": [
{
"topicKeywords": [],
"operator": "OR",
"keywordGroupsRef": [
{
"keywordGroupId": "6983038bdc0d4e0888a19de6",
"operator": "OR"
}
],
"ordered": false,
"nearDistance": 0
}
],
"excludeConditions": [
{
"topicKeywords": [
{
"term": "black",
"keywordType": "EXCLUDE_KEYWORD",
"distance": 0
}
],
"operator": "OR",
"keywordGroupsRef": [],
"ordered": false,
"nearDistance": 0
}
],
"textQuery": "(\\Rolex\\ AND (\\handcrafted clothing\\ OR \\artisan fashion\\ OR \\unique garments\\ OR \\fashion craftsmanship\\) AND NOT \\black\\)",
"themesInQuery": \[\]
}
\],
"details": {
"type": "criteria"
},
"filters": \[\]
},
{
"filterType": "IN",
"field": "POINT_RADIUS_LOCATION",
"values": \[
{
"type": "POINT_RADIUS",
"locationName": "G33W+946 Ambience Island, DLF Phase 3, Sector 24, Gurugram, Haryana, India",
"latitude": 28.5034,
"longitude": 77.0953,
"radius": 10,
"unit": "mi",
"id": "28.5034_77.0953"
}
\],
"details": {},
"filters": \[\]
}
\],
"tags": \[
"Air Travel Preferences",
"Credit Products - Retail Bank"
\],
"shareConfigs": \[
{
"type": "CLIENT",
"ids": \[
"66000002"
\]
},
{
"type": "CLIENT_GROUP",
"ids": \[
"69956ee7bd0cf95d4a5b43a5"
\]
},
{
"type": "USER",
"ids": \[
"66006626",
"66044670",
"66044665",
"66007863",
"66044664",
"66062939",
"66044660"
\]
},
{
"type": "USER_GROUP",
"ids": \[\]
}
\]
}
\],
"errors": \[\]
}
| Parameter | Sub-parameter | Type | Description |
|---|---|---|---|
| data | N/A | Array | List of Listening Theme objects returned by the API. |
| data | id | String | Unique identifier of the theme. |
| data | name | String | Name of the theme. |
| data | displayName | String | Display name of the theme. |
| data | color | String | Hex color code associated with the theme. |
| data | filters | Array | List of filters associated with the theme. |
| data.filters | filterType | String | Filter operator applied to the field. Example: IN. |
| data.filters | field | String | Dimension or field on which the filter is applied. Examples include QUERY and POINT_RADIUS_LOCATION. |
| data.filters | values | Array | List of values used for filtering. |
| data.filters.values | orConditions | Array | Collection of OR conditions configured in the query. |
| data.filters.values | andConditions | Array | Collection of AND conditions configured in the query. |
| data.filters.values | excludeConditions | Array | Collection of exclusion conditions configured in the query. |
| data.filters.values | advanceQuery | String | Advanced query expression used in the theme filter. |
| data.filters.values | textQuery | String | Human-readable representation of the query. |
| data.filters.values | themesInQuery | Array | List of referenced themes used within the query. |
| data.filters.values.orConditions | topicKeywords | Array | Topic keywords included in the condition. |
| data.filters.values.orConditions | operator | String | Logical operator applied to the condition. |
| data.filters.values.orConditions | keywordGroupsRef | Array | Referenced keyword groups used in the condition. |
| data.filters.values.orConditions.keywordGroupsRef | keywordGroupId | String | Unique identifier of the referenced keyword group. |
| data.filters.values.orConditions.keywordGroupsRef | operator | String | Logical operator associated with the keyword group. |
| data.filters.values.excludeConditions.topicKeywords | term | String | Excluded keyword term. |
| data.filters.values.excludeConditions.topicKeywords | keywordType | String | Type of excluded keyword. |
| data.filters.values.excludeConditions.topicKeywords | distance | Integer | Distance value associated with the excluded keyword. |
| data.filters | details | Object | Additional filter configuration details. |
| data.filters.details | type | String | Filter configuration type. |
| data.filters.details | raw_search | Boolean | Indicates whether raw search mode is enabled. |
| data.filters | filters | Array | Nested filters associated with the current filter. |
| data.filters.values | type | String | Location filter type. Example: POINT_RADIUS. |
| data.filters.values | locationName | String | Name of the configured location. |
| data.filters.values | latitude | Double | Latitude coordinate of the location. |
| data.filters.values | longitude | Double | Longitude coordinate of the location. |
| data.filters.values | radius | Integer | Radius around the location. |
| data.filters.values | unit | String | Unit used for the radius. |
| data.filters.values | id | String | Unique identifier of the location filter. |
| data | tags | Array | List of tags associated with the theme. |
| data | shareConfigs | Array | Sharing configuration for the theme. |
| data.shareConfigs | type | String | Sharing scope (CLIENT, CLIENT_GROUP, USER, USER_GROUP, GLOBAL). |
| data.shareConfigs | ids | Array | Identifiers of entities granted access to the theme. |
| errors | N/A | Array | List of errors encountered during request processing. Returns an empty array when the request succeeds. |
Summary. Partially update a Listening Theme. operationId. ListeningThemeApiV3_patchTheme Request body. ListeningThemePatchRequestDTO, required. Response. 200 with type: string. Declared errors. 400, 401, 403, 404. V2 reference. Update Theme 2.0, part of the Listening 2.0 suite. Ticket coverage. **None.**Read/Fetch-scoped. Permission. Conversations → Listening Settings → Edit Theme.
| Parameter | In | Type | Required (spec) | Description |
|---|---|---|---|---|
id | query | string | required | Listening theme id |
Note the description is singular — "Listening theme id" — with no mention of comma separation. Unlike GET and DELETE, PATCH is single-target: you can bulk-fetch and bulk-delete, but you must update Themes one at a time.
Schema description: "Partial update for a Listening Theme."
| Field | Type | Required | Description (from sprinklr-v3.yaml) |
|---|---|---|---|
name | string | — | Listening Theme name |
displayName | string | — | Listening Theme display name |
iconUrl | string | — | Listening Theme icon url |
imageUrl | string | — | Listening Theme image url |
color | string | — | Listening Theme identification color |
filters | array of Filter_request | — | Filter list |
description | string | — | Description |
tags | array of string | — | Tags |
shareConfig | ShareConfig (single object) | — | Share configuration |
permissionEntity | PermissionEntity (single object) | — | Permission configuration |
The schema declares no required array at all — every field is optional, which is consistent with partial-update semantics. It also means an empty body {} satisfies the schema, and id is required: false, so PATCH /listening/theme with an empty body is a spec-valid request with entirely undefined behaviour.
Note that id is absent from the body schema — the target travels only in the query string.
Both are the V2-era shapes, and in V3 they have identical property sets — the two schemas differ only in name and description.
| Field | Type | Description |
|---|---|---|
userIds | array of integer (int64) | List of User IDs, which is unique identifier for each User |
userGroupIds | array of string | List of User Group IDs, which is unique identifier for each User Group |
clientIds | array of integer (int64) | List of Client IDs, which is unique identifier for Client |
clientGroupIds | array of string | List of Client Group IDs, which is unique identifier for Client Group |
shareWithEveryOne | boolean | Set this true, in order to share with every User |
ShareConfig is described as "Describes the schema for Share Config"; PermissionEntity as "Describes the schema for Permission".
Two things follow:
- Ids are numbers here, strings in create.
ShareConfig.userIdsis an array ofint64;AssetShareConfig.idsis an array of string. The same user id must be serialised as600000000in aPATCHand"600000000"in aPOST. - The V2 documentation understated
permissionEntity. The V2 Create Theme page documentedpermissionEntitywith onlyuserIdsanduserGroupIds. The V3PermissionEntityschema carries all five properties, includingclientIds,clientGroupIds, andshareWithEveryOne. Whether the extra three are honoured on a permission entity, or simply inherited from a shared base class, is unknown.
Unlike create, PATCH retains a direct equivalent of V2's shareWithEveryOne
PATCH filters use Filter_request, which is substantially richer than the Filter_shifu used on create:
| Field | Type | Notes |
|---|---|---|
filterType | FilterType_Filter | Enumerated — see below. |
field | string | Field the filter applies to. |
values | array of object | Filter values. |
displayName | string | Absent from Filter_shifu. |
isCompoundFilter | boolean | Absent from Filter_shifu. |
negativeFilter | boolean | Negation. Absent from Filter_shifu. |
accessibleValues | array of object | Absent from Filter_shifu. |
userFilter | boolean | Echoed by the V2 create response. |
allValuesAllowed | boolean | Echoed by the V2 create response. |
lockedWithValues | boolean | Absent from Filter_shifu. |
hidden | boolean | Absent from Filter_shifu. |
favourite | boolean | Echoed by the V2 create response. |
mandatory | boolean | Echoed by the V2 create response. |
locked | boolean | Echoed by the V2 create response. |
ignoreAddingToDimensionFilter | boolean | Absent from Filter_shifu. |
disabled | boolean | Absent from Filter_shifu. |
details | object (string → object) | Also in Filter_shifu. |
filters | array of Filter_request | Recursive nesting. |
advancedFilters | array of AdvancedFilterRequest | Absent from Filter_shifu. |
filterType here is constrained, by the FilterType_Filter enum:
FILTER · LIMIT · SEARCH · MATCH_PHRASE_PREFIX · ADHOC_SEARCH ·
EXPRESSION · GEO_DISTANCE · ADVANCED_QUERY · MATCH_NONE · MATCH_ALLIN — the only filter type evidenced anywhere for Themes — is not in this list. So a filter that is valid on create may be rejected on patch. Unlike Filter_shifu, Filter_request has no description on any property, so the meaning of the sixteen flags is undocumented.
Because five of Filter_request's exclusive fields (userFilter, allValuesAllowed, favourite, mandatory, locked) are exactly the keys the V2 create response echoed back, Filter_request is very likely the true internal filter model, and Filter_shifu a reduced projection of it.
The operation is named "partial update", but no source states how omitted or supplied collections are handled:
- Omitted field — left unchanged (the normal
PATCHreading), or reset to null? - Supplied array (
filters,tags) — does it replace the existing array wholesale, or merge with it? - Empty array
[]— clears the collection, or is it a no-op? shareConfig— does supplying it replace the whole share configuration, or merge id lists?
There is no If-Match, ETag, or version field on the entity, so concurrent patches are last-write-wins with no optimistic-concurrency mechanism. The safest pattern is a serialised read-modify-write per Theme — but §10 opening callout shows you cannot mechanically round-trip a GET body into a PATCH body, so you must translate the three divergent structures yourself.
curl -X PATCH \
'https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=66badc8a6df5bf43f6c8f374' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Content-Type: application/json' \
-d '{
"displayName": "Customer Service & Support",
"description": "Customer service conversations, inquiries, and escalations",
"color": "#2E7D32",
"tags": ["cs", "support", "priority", "escalations"],
"shareConfig": {
"userIds": [600000000, 600037831],
"userGroupIds": ["ug-support"],
"shareWithEveryOne": false
},
"permissionEntity": {
"userIds": [600000000]
}
}'The 200 response is declared as type: string — a bare JSON string, not an object. No source states what it contains: the updated Theme's id, a status word such as SUCCESS, or a human-readable message.
Consequences for your client:
- You cannot read the updated entity back from the response. Issue a follow-up
GETif you need to confirm the result. - Do not parse the response as JSON into a model. Treat a
200as success and the body as opaque. - If the envelope described applies, the body may actually be
{"data": "…", "errors": []}— in which case checkingerrorsremains essential.
Summary. Delete Listening Theme(s) by id. Supports bulk delete. V2 reference. Delete Theme 2.0, part of the Listening 2.0 suite. Permission. Conversations → Listening Settings → Delete Theme.
| Parameter | In | Type | Required (spec) | Description |
|---|---|---|---|---|
id | query | string | false | Comma-separated listening theme ids |
# Single
curl -X DELETE \
'https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=66badc8a6df5bf43f6c8f374' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}'
# Bulk — comma-separated, no spaces
curl -X DELETE \
'https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=66badc8a6df5bf43f6c8f374,60486cef06ebe67ed55c4140' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}'Do not put spaces after the commas; no source shows whitespace being tolerated, and an unencoded space is not valid in a query string.
Partial failure is unspecified. If one id in a bulk delete does not exist, or the caller lacks permission on one of them, no source states whether the call is atomic (all-or-nothing), best-effort (deletes what it can), or fails outright. With a type: string response body there is also no per-id result structure to report outcomes. Prefer deleting in small batches, or one at a time, when you need to know exactly what happened.
As with PATCH, the 200 body is declared type: string with no described content. You cannot determine from the response how many Themes were actually deleted. Confirm with a follow-up GET on the same ids and check that they no longer resolve.
Both the V2 create example and read example carry a deleted boolean on the Theme object, which strongly suggests the platform soft-deletes Themes rather than removing the record. But deleted is absent from the V3 ListeningTheme schema, so a V3 client has no way to observe the flag.
Open questions this raises:
- After
DELETE, does a subsequentGETon that id return404, or return the object withdeleted: true(a field your model does not have)? - Can a deleted Theme be restored, and if so, by what call?
- Does the
namebecome reusable for a new Theme after deletion?
None is answerable from the available sources.
A Theme is referenced from several places in the product — dashboard filters, widget dimensions, alert conditions, and rule conditions, all of which can target Themes via Theme Tags. Read example also shows an appliedToTopics array associating a Theme with Topics.
No source documents what deleting a Theme does to those references: whether the delete is blocked while references exist, whether references are silently dropped, or whether dashboards break. Because a Theme is a read-time lens rather than an ingestion rule, deleting one cannot cause data loss in your mention store — but it can break saved dashboards and reporting that segment by it.
Recommended practice: GET the Theme and record its full definition before deleting, so it can be recreated if a dependency surfaces. There is no undo documented.
| Operation | V2 | V3 | Change |
|---|---|---|---|
| Create Theme (V2) | POST /api/v2/listening-theme | POST /api/v3/listening/theme | Breaking. Hyphenated listening-theme becomes the nested path listening/theme. |
| Read Theme | GET /api/v2/listening-theme/{id} | GET /api/v3/listening/theme?id={id} | Breaking. Id moves path → query; gains bulk support. |
| Update Theme | PUT /api/v2/listening-theme/{id} | PATCH /api/v3/listening/theme?id={id} | Breaking. Method changes PUT → PATCH; id moves path → query. |
| Delete Theme | DELETE /api/v2/listening-theme/{id} | DELETE /api/v3/listening/theme?id={id} | Breaking. Id moves path → query; gains bulk support. |
V2 read/update/delete path forms are inferred from the V2 suite's structure; only the create path is quoted verbatim from the V2 page.
This follows the V3 programme's consistent rewrite rule, seen across every entity documented so far: identifiers move from the path into query parameters, and hyphenated resource names become nested path segments. A v2 → v3 string replacement will not work.
| V2 field | V3 field | Change |
|---|---|---|
name | name | Unchanged. Required in both. |
displayName | displayName | Unchanged. |
iconUrl | iconUrl | Unchanged. |
imageUrl | imageUrl | Unchanged. |
color | color | Unchanged. |
description | description | Unchanged. |
filters | filters | Name unchanged. Type documentation changed — V2 documented it as List<String>, which its own example contradicts by sending objects. V3 correctly types it as an array of Filter_shifu. |
tags | tags | Unchanged. |
shareConfig (object) | shareConfigs (array) | Breaking. |
permissionEntity (object) | permissions (array) | Breaking. |
deleted (in V2 example) | — | Removed. Not in ListeningTheme. Drop it. |
The V2 page documented filters as List<String> — "The Filter list to filter out required data. List<String>" — while its own example sends an array of objects. V3's typing is the correct one; if you built against the V2 documentation's stated type rather than its example, your code was already wrong.
This is the largest breaking change and the easiest to get subtly wrong, because the V3 name permissions is close enough to V2's permissionEntity to look like a simple rename. It is not.
V2 — two objects, four id lists each, keyed by id type:
"shareConfig": {
"userIds": [600000000],
"userGroupIds": ["ug-1"],
"clientIds": [66000002],
"clientGroupIds": ["cg-1"],
"shareWithEveryOne": false
},
"permissionEntity": {
"userIds": [600000000],
"userGroupIds": ["ug-1"]
}V3 — two arrays of {type, ids} pairs:
"shareConfigs": [
{ "type": "USER", "ids": ["600000000"] },
{ "type": "CLIENT", "ids": ["66000002"] }
],
"permissions": [
{ "type": "USER", "ids": ["600000000"] }
]The model inverts: V2 keyed id lists by field name, V3 keys them by a type discriminator. Migration steps:
- Rename
shareConfig→shareConfigsandpermissionEntity→permissions, and change both from object to array. - Convert each V2 id list into an array element with the matching
type:userIds→{"type": "USER", …},clientIds→{"type": "CLIENT", …}. - Stringify all ids. V2
userIdsandclientIdswereList<Long>; V3idsis an array of string. - Map
shareWithEveryOne: trueto — most likely —{"type": "GLOBAL"}. Unconfirmed; - Find the V3
typevalues foruserGroupIdsandclientGroupIds. Not documented;
| Area | V2 | V3 | Action |
|---|---|---|---|
| Response envelope | {"data": {…}, "errors": []} | Spec says bare object | Unwrap defensively. |
| Update method | PUT | PATCH | Change the verb, and send partial bodies. |
| Bulk operations | One id per call | GET/DELETE accept comma-separated ids | Batch reads and deletes. |
| Filter type value | IN | Not in the patch enum | Verify. |
deleted field | In the V2 example body | Not in ListeningTheme | Remove from your payload. |
| Host / env | api3.sprinklr.com/{env}/… | {env}.api.sprinklr.com/… per | Confirm with your account team. |
All examples are illustrative and reconstructed. Verify against your environment.
curl -X POST 'https://api3.sprinklr.com/{env}/api/v3/listening/theme' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "pricing_mentions",
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{ "advanceQuery": "pricing OR price OR cost", "textQuery": "pricing OR price OR cost" }
]
}
]
}'The pattern from the V2 page — reference a Keyword List by id rather than restating its keywords, so that updating the list updates every Theme that uses it.
curl -X POST 'https://api3.sprinklr.com/{env}/api/v3/listening/theme' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "competitor_mentions",
"displayName": "Competitor Mentions",
"description": "Mentions matching the maintained competitor keyword list",
"color": "#E53935",
"tags": ["competitive-intel"],
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{
"advanceQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")",
"textQuery": "keyword_list_or(\"5f601c2728cf4e53142af770\")"
}
]
}
]
}'curl -X POST 'https://api3.sprinklr.com/{env}/api/v3/listening/theme' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "customer_service",
"displayName": "Customer Service",
"color": "#4CAF50",
"tags": ["cs", "support"],
"filters": [
{
"filterType": "IN",
"field": "QUERY",
"values": [
{ "advanceQuery": "support OR help OR issue OR problem", "textQuery": "support OR help OR issue OR problem" }
]
}
],
"shareConfigs": [
{ "type": "CLIENT", "ids": ["66000002"] }
],
"permissions": [
{ "type": "USER", "ids": ["600000000", "600037831"] }
]
}'# 1. Create, capturing the id
THEME_ID=$(curl -s -X POST 'https://api3.sprinklr.com/{env}/api/v3/listening/theme' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Content-Type: application/json' \
-d @theme.json | python3 -c 'import sys,json; r=json.load(sys.stdin); d=r.get("data", r); d=d[0] if isinstance(d,list) else d; print(d["id"])')
# 2. Read it back
curl -s -X GET "https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=${THEME_ID}" \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' | python3 -m json.toolThe id extraction above handles all three candidate response shapes from.
# Read several Themes in one call
curl -X GET 'https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=60486cef06ebe67ed55c4140,66badc8a6df5bf43f6c8f374' \
-H 'Authorization: Bearer {{accessToken}}' -H 'Key: {{apiKey}}'
# Delete several — always with an explicit id list
curl -X DELETE 'https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=60486cef06ebe67ed55c4140,66badc8a6df5bf43f6c8f374' \
-H 'Authorization: Bearer {{accessToken}}' -H 'Key: {{apiKey}}'Four patterns that combine the four operations. All are illustrative.
The most common reason to reach for this API. Keep Theme definitions in version control, then apply them per environment.
- Store one JSON file per Theme, each a valid
ListeningThemecreate body, withnameas the stable key. - For each file,
POSTit and record the returnedidin an environment-scoped map (name→id). - On a later run, look the
nameup in the map: if present,PATCHby itsid; if absent,POST.
Because there is no documented list-all or name-search on GET , your name → id map is the only index you have. Persist it as a build artefact; if you lose it, you cannot reliably rediscover which Themes you own. This is the strongest practical argument for treating id storage as part of the deployment, not a cache.
Remember that the create and patch bodies are not interchangeable — keep a translation function between the two shapes rather than reusing one payload.
Sync Themes from a product catalogue, CRM category tree, or support-ticket schema.
- Read the external taxonomy.
GETyour known Theme ids in one bulk call — comma-separate them rather than looping.- Diff on
name: create the additions, patch the changes, and collect the removals. - Delete the removals in a single bulk
DELETE, having firstGET-ed and archived their full definitions.
Tag every Theme created by the sync with a common tag — "tags": ["src:crm"] — so automation-owned Themes are distinguishable from hand-built ones in the UI.
Bulk GET makes this cheap, and it is the safest operation in the set.
curl -s -X GET "https://api3.sprinklr.com/{env}/api/v3/listening/theme?id=${IDS}" \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' > themes-$(date +%Y%m%d).jsonBecause PATCH and DELETE return only an opaque string and there is no version history on the entity, a periodic snapshot is your only rollback mechanism. Run it before any bulk change.
Create one Theme per product attribute, region, or campaign, then apply it consistently.
- Build the filter once in the UI Theme Editor, using its live preview to validate that the query returns what you expect — there is no API dry-run.
GETthat Theme and copy its exactfiltersblock.- Generate the remaining Themes programmatically, substituting only the keyword or keyword-list id.
- Give them all a shared tag so dashboards, widgets, alerts, and rules can target the whole family at once.
This is the recommended way to work around the filter-vocabulary uncertainty in: let the UI produce a known-good filter, then replicate its shape rather than inventing one.
POST, PATCH, and DELETE have no ticket coverage and no recorded production verification in any available source. Only GET is signed off. Before running writes at volume:
- Exercise each operation once in a non-production environment and record the actual request and response.
- Diff the created object against what you sent to learn the server's defaulting behaviour.
- Keep that transcript — it is better evidence than this guide.
Restating the most dangerous item on the page: DELETE /listening/theme declares its only targeting parameter as optional, and it is a bulk operation (§11.1). Validate a non-empty id list client-side before the URL is built. Do not rely on the server to reject an empty target.
The fetch response, the create body, and the patch body use three different structures for filters, sharing, and permissions (§0.1). Write an explicit translation layer with tests. A naive read-modify-write will either fail validation or, worse, silently drop the fields it does not recognise.
Watch the id types especially: strings in AssetShareConfig.ids on create, numbers in ShareConfig.userIds on patch.
Given the schema/example divergence in , configure your JSON deserialiser to ignore unknown properties, and do not fail if filters arrives as an object rather than an array. Unwrap a data envelope if present, and read the errors array even on 200.
Filter_shifu has no enum on filterType or field, and the only evidenced values come from a V2 example whose filterType: "IN" is absent from the enum the patch schema uses. Building filter JSON from first principles is guesswork. Build in the Theme Editor, GET, and copy.
GET and DELETE accept comma-separated ids; PATCH does not. Batching cuts call volume, but no source states a maximum id count or how partial failures are reported. Start with modest batches — tens, not thousands — and reduce them if you see 400s. When you need to know exactly which ids succeeded, delete one at a time.
Neither 429 nor 500 is declared on any operation in this tag. That is a documentation gap, not a guarantee of unlimited throughput. Implement exponential backoff with jitter, honour Retry-After if present, and throttle bulk provisioning rather than firing it in parallel.
Worth stating plainly, because it makes Themes far safer to automate than Topics. A Theme is a read-time lens over already-ingested data , so creating, changing, or deleting one never changes ingestion volume or your data bill. The blast radius of a mistake is broken dashboards and reporting — recoverable — not lost mentions.
The one caveat: whether a new Theme applies retroactively to already-collected mentions or only forward from creation is undocumented.
Theme Tags are how dashboards, widgets, alerts, and rules address groups of Themes. Assigning them at create time costs nothing; retrofitting them means a PATCH per Theme, since patch is single-target. Decide your tag vocabulary before you provision.
There is no documented list-all, name search, or pagination on GET. The idreturned fromPOST` may be the only handle you ever get. Persist it at creation time.