- Applies to: Sprinklr Listening Query API V3 —
POST /api/v3/listening/query/streamandPOST /api/v3/listening/query/widget - V2 API reference: Listening Streams | Sprinklr Developer Portal (
POST /api/v2/listening/query/stream)
Sprinklr Listening gives brands visibility into online conversations across channels, websites, and news sources. Listening data is organised into Topics (keyword queries that pull in conversations not sent directly to your brand), Topic Groups, Themes, and Keyword Lists.
The Listening Query API V3 lets you run two fundamentally different kinds of query against that data:
| You want | Endpoint | Returns |
|---|---|---|
| The individual messages that matched a Listening query | POST /api/v3/listening/query/stream | A paginated list of Message objects |
| An aggregated count, breakdown, or trend over those messages | POST /api/v3/listening/query/widget | Aggregated buckets (word / id / count) |
Both endpoints take the same request body schema (ApiWidgetRequestDTO in the specification). The details.widgetType field is what decides which shape of answer you get — and it is also what decides which of the two endpoints you must call.
Every Listening query, on either endpoint, is built from four parts:
| Part | Field | Purpose |
|---|---|---|
| Time range | sinceTime, untilTime, timeField, timezoneOffset | Which window of messages to consider |
| Scope | filters[] | Which Listening dimensions (Topic, Sentiment, Media Source, …) narrow the set |
| Shape | details | What kind of answer you want — stream of messages, distribution, trend, users, topic cluster |
| Measure | metric, trendAggregationPeriod | What is being counted, and at what granularity |
Learn this once and both endpoints become the same API with two output modes.
Listening is one of a small number of Sprinklr data sets that is not enabled by default. Per the Sprinklr Help Center, Listening API access requires an explicit request to the Support team when Listening is part of the use case listed in your License Order Form.
If Listening Stream is not enabled, the response body carries:
{
"message": "Streaming in listening is not enabled for you. Please contact support",
"data": {}
}All API calls are sent to the production endpoint:
https://api3.sprinklr.com/{env}/api/v3So the listening resource in production is:
https://api3.sprinklr.com/{env}/api/v3/listening/query/stream
https://api3.sprinklr.com/{env}/api/v3/listening/query/widgetSee the environment list at APIs | Sprinklr Developer Portal.
All Listening API calls are authenticated with OAuth 2.0. See API Overview for portal registration, API key and secret generation, and the Authorize flow.
| Key | Value | Description | Required on |
|---|---|---|---|
Authorization | Bearer {{accessToken}} | Credential used by the API to authenticate a user with the server. For generating the authorization token, refer to the Authorize section on the developer portal. | All requests |
Key | {{apiKey}} | API key that authenticates the application with the server. For generating an API key, refer to the Getting Started guide. | All requests |
Content-Type | application/json | Representation header that determines the type of data present in the request body. | All requests (both endpoints are POST with a required body) |
Accept | application/json | Determines the acceptable response type from the server. | All requests |
Governance. Sprinklr's API governance model is tied directly to the user's role and permissions — the API key inherits every permission of the user it was created for. A caller with no visibility of a Listening Topic will not receive its messages, regardless of the filterValues sent.
Credential hygiene. Never commit an access token or API key to source control, never paste one into a ticket or chat, and never log the
AuthorizationorKeyheader values. Every credential in this guide is a placeholder. If a real token or key has been exposed, revoke and regenerate it immediately.
Operation ID: ListeningApiV3_queryStream · Tag: Listening V3 · Request body: required
Returns the message stream associated with each matching message, containing the required information. It returns StreamWidgetResponse (ListeningStreamV3ResponseDTO in the V3 specification).
Use this endpoint when you need the messages themselves — text, author, permalink, workflow state, enrichments — rather than a count.
These are hard limits carried forward verbatim from the V2 reference and repeated in the supplied V3 specification:
- You cannot fetch more than 10,000 messages in a same timestamp.
- You cannot fetch more than 1,000 messages in one request.
Design your pagination around both numbers. The second caps a single call; the first caps how deep you can page within one timestamp before you must advance the time window (§9.2).
| Parameter | Sub-parameter | Required | Type | Description |
|---|---|---|---|---|
sinceTime | Required | Long | Start of the time range, in epoch milliseconds. | |
untilTime | Required | Long | End of the time range, in epoch milliseconds. | |
timeField | Optional | String | Which time the range applies to. SN_CREATED_TIME — time the message was created on the social network (default). SYSTEM_CREATED_TIME — time the message was created in Sprinklr. | |
timezoneOffset | Optional | Long | Client timezone UTC offset in milliseconds. Default 0 (UTC). For example, EST is UTC−5, so -(5*60*60*1000) = -18000000. | |
details | Required | Object | Widget configuration. See §4.3. | |
widgetType | Required | String | STREAM for this endpoint. | |
filters | Optional | Array of objects | Dimension filters applied to the query. Default: empty. See §4.4. | |
metric | Optional | String | Metric to aggregate. MENTIONS (default), REACH, RETWEETS, FAVORITES. | |
start | Optional | Integer | Pagination offset. Default 0. Applicable to the STREAM widget only. | |
rows | Optional | Integer | Maximum number of items in the page. Default 20. Applicable to the STREAM widget only. Bounded by the 1,000-messages-per-request limit in §4.1. | |
sortKey | Optional | String | Field used to sort the returned messages. Takes three values: SYSTEM_CREATED_TIME (system created time), CREATED_TIME (social network created time), MODIFIED_TIME (modified time). Default: CREATED_TIME. | |
sortOrder | Optional | String | Sort direction. Stream endpoint only. | |
messageFormatOptions | Optional | String | Comma-delimited formatting values: strip_html (strip HTML from message text), strip_url (strip URLs from message text), include_original (also return the original text in an originalText field). | |
trendAggregationPeriod | Optional | String | Trend bucket size — HOUR, DAY, WEEK, MONTH, QUARTER, YEAR. Applicable to TREND and GROUPED_TREND widgets, not to STREAM. | |
echoRequest | Optional | Boolean | When true, echoes the request back in the response object. | |
tag | Optional | String | A state parameter, usable as a version attached with the response. It is not modified by the API and is returned as-is. |
| Parameter | Required/Optional | Type | Description |
|---|---|---|---|
widgetType | Required | String | Refers to the type of the widget. STREAM on this endpoint. |
Shared by both endpoints.
| Parameter | Required/Optional | Type | Description |
|---|---|---|---|
dimension | Required | String | Filter dimension such as TOPIC, TOPIC_GROUP, SENTIMENT, or MEDIA_SOURCE. |
filterValues | Required | Array of String | List of IDs for the given dimension. For the TOPIC dimension, filterValues is the list of Topic IDs. |
exclude | Optional | Boolean | Excludes matching values when set to true. Default false. |
customFieldName | Conditional | String | Required when filtering on custom field dimensions. |
To resolve a Topic ID, use the Listening Topic APIs — for example Read Topic 2.0 (GET /api/v2/listening-topic/{topicId}), or the Listening Topic V3 endpoints (/listening/topic) in the V3 specification. filterValues takes IDs, never names.
curl --location 'https://api3.sprinklr.com/api/v3/listening/query/stream' \
--header 'Authorization: Bearer {{accessToken}}' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"sinceTime": 1488034511000,
"untilTime": 1786537500000,
"details": {
"widgetType": "STREAM"
},
"filters": [
{
"dimension": "TOPIC",
"filterValues": ["6a7ae25c298255388c56550a"]
}
],
"metric": "MENTIONS",
"rows": 10,
"start": 0
}'Illustrative example, reproduced from the supplied specification. Not real customer data and not a guaranteed production response.
{
"data": {
"result": [
{
"sourceType": "ACCOUNT",
"sourceId": 600049002,
"content": {
"text": "",
"isRichText": false
},
"channelMessageId": "p234uqy",
"channelType": "REDDIT",
"accountType": "SUBREDDIT",
"channelCreatedTime": 1786033040000,
"senderProfile": {
"channelType": "REDDIT",
"followers": -1,
"following": -1,
"unSubscribed": false,
"deleted": false,
"snCreatedTime": 0,
"snModifiedTime": 0,
"statusCount": -1,
"accountSpecificInfos": []
},
"permalink": "https://www.reddit.com/r/holup/comments/1vh6sg3/natasha/p234uqy",
"language": "en",
"messageId": "ACCOUNT_600049002_1786033040000_REDDIT_273_p234uqy",
"brandPost": false,
"createdTime": 1786033605300,
"modifiedTime": 1786348560798,
"textEntities": {},
"insights": {},
"workflow": {
"modifiedTime": 1786348560798,
"customProperties": {},
"queues": [],
"spaceWorkflows": []
},
"enrichments": {},
"autoImported": false,
"autoResponse": false,
"apiStatus": "Removed fields because of resyndication policy"
}
],
"hasMore": true
},
"errors": []
}| Parameter | Type | Description |
|---|---|---|
data | Object | Contains the API response data. |
data.result | Array | List of messages/posts matching the query criteria. |
data.hasMore | Boolean | Indicates whether additional records are available for retrieval through pagination. |
errors | Array | Contains any errors returned by the API. An empty array indicates a successful request. |
This matches ListeningStreamV3ResponseDTO in the specification, which defines exactly two properties — result (array of Message) and hasMore (boolean).
| Parameter | Sub-parameter | Type | Description |
|---|---|---|---|
sourceType | - | String | Type of source from which the message was collected (for example, ACCOUNT). |
sourceId | - | Long | Unique identifier of the source account. |
content | - | Object | Contains the content of the message. |
content | text | String | Text content of the message. May be empty due to platform resyndication policies. |
content | isRichText | Boolean | Indicates whether the content contains rich text formatting. |
channelMessageId | - | String | Unique identifier of the message on the native channel. |
channelType | - | String | Social channel from which the message originated, such as REDDIT or TWITTER. |
subType | - | String | Specifies the subtype of the message within the social channel, such as a post, comment, reply, mention, or repost. |
accountType | - | String | Type of account associated with the message, such as SUBREDDIT or TWITTER. |
channelCreatedTime | - | Long | Timestamp (in milliseconds) when the message was originally created on the source channel. |
senderProfile | - | Object | Metadata associated with the message author. |
senderProfile | channelType | String | Social channel associated with the sender profile. |
senderProfile | followers | Integer | Number of followers for the sender profile. A value of -1 indicates unavailable data. |
senderProfile | following | Integer | Number of accounts followed by the sender profile. A value of -1 indicates unavailable data. |
senderProfile | unSubscribed | Boolean | Indicates whether the profile is unsubscribed. |
senderProfile | deleted | Boolean | Indicates whether the profile has been deleted. |
senderProfile | snCreatedTime | Long | Timestamp when the sender profile was created on the social network. |
senderProfile | snModifiedTime | Long | Timestamp when the sender profile was last updated on the social network. |
senderProfile | statusCount | Integer | Total number of posts/messages by the sender. A value of -1 indicates unavailable data. |
senderProfile | accountSpecificInfos | Array | Channel-specific metadata for the sender profile. |
permalink | - | String | Direct link to the original message or post on the social platform. |
language | - | String | Detected language of the message content. |
messageId | - | String | Unique Sprinklr message identifier. |
brandPost | - | Boolean | Indicates whether the message was published by a brand-owned account. |
createdTime | - | Long | Timestamp (in milliseconds) when the message was ingested into Sprinklr. |
modifiedTime | - | Long | Timestamp (in milliseconds) when the message was last updated in Sprinklr. |
textEntities | - | Object | Contains extracted entities such as people, locations, organizations, hashtags, URLs, and mentions from the message content. |
insights | - | Object | Stores analytics, classifications, and insights generated for the message. |
workflow | - | Object | Workflow information associated with the message. |
workflow | modifiedTime | Long | Timestamp of the most recent workflow update. |
workflow | customProperties | Object | Custom properties and user-defined fields applied to the message. |
workflow | queues | Array | Lists queues to which the message has been assigned. |
workflow.queues[] | queueId | Long | Unique identifier of the assigned queue. |
workflow.queues[] | assignmentTime | Long | Timestamp when the message was assigned to the queue. |
workflow | spaceWorkflows | Array | Contains workflow information associated with Spaces. |
enrichments | - | Object | Additional enrichment data applied to the message. |
autoImported | - | Boolean | Indicates whether the message was automatically imported into the platform. |
autoResponse | - | Boolean | Indicates whether an automatic response was sent for the message. |
apiStatus | - | String | Provides status or informational messages related to the API response, such as content restrictions due to platform resyndication policies. |
The V3 Message schema in sprinklr-v3.yaml additionally defines id, draftId, receiverProfile, mentionedProfiles, postId, assetId, and authorId. These are part of the Message type but do not appear in the supplied Listening Stream examples — treat their presence in a Listening stream response as unconfirmed.
In the supplied example every message returns "content": {"text": ""} alongside "apiStatus": "Removed fields because of resyndication policy". This is expected behaviour, not a defect. Channel resyndication policies (notably Twitter/X) restrict which fields Sprinklr may return over the API. Enabling full Twitter syndication requires an explicit request to Sprinklr Support, per the Sprinklr Help Center.
Always read apiStatus before treating an empty content.text as "no text".
Operation ID: ListeningApiV3_queryWidget · Tag: Listening V3 · Request body: required
Queries Listening widget data — distribution, grouped distribution, trend, users, and topic cluster. Use this endpoint for aggregates, never for raw messages.
| Field | Type | Required | Description |
|---|---|---|---|
sinceTime | long | Yes | Start of time range (epoch milliseconds). |
untilTime | long | Yes | End of time range (epoch milliseconds). |
timezoneOffset | long | No | Client timezone offset in milliseconds. |
details | object | Yes | Widget configuration. See §5.2. |
filters | array of objects | No | Dimension filters (default empty). See §4.4. |
metric | string | No | Metric to aggregate (MENTIONS, REACH, RETWEETS, FAVORITES). Default MENTIONS. |
trendAggregationPeriod | string | No | Bucket size for trend widgets (HOUR, DAY, WEEK, MONTH, QUARTER, YEAR). Required for trend types. |
messageFormatOptions | string | No | Message formatting options passed to the widget engine. |
start | integer | No | Pagination offset (default 0). |
rows | integer | No | Page size (default 20). Max depends on widget type (distribution ≤ 100, grouped distribution ≤ 20). |
sortKey | string | No | Not used on widget endpoint (stream only). |
sortOrder | string | No | Not used on widget endpoint (stream only). |
timeField | string | No | Time field for filtering (SN_CREATED_TIME, SYSTEM_CREATED_TIME). Default SN_CREATED_TIME. |
echoRequest | boolean | No | When true, echoes the request in the response metadata. |
tag | string | No | Client-side request version tag (not modified by API). |
| Parameter | Required/Optional | Type | Description |
|---|---|---|---|
widgetType | Required | String | Widget type. Supported values include DISTRIBUTION, GROUPED_DISTRIBUTION, TREND, GROUPED_TREND, USERS, and TOPIC_CLUSTER. |
subType | Conditional | String | Required for the USERS widget type. |
dimension | Conditional | String | Primary dimension for the widget. For example, SENTIMENT, TOPIC, or MEDIA_SOURCE. |
otherDimension | Conditional | String | Secondary dimension. Required for GROUPED_DISTRIBUTION. |
otherDimensionRows | Optional | Integer | Maximum number of rows for the secondary dimension. Default is 20. |
customFieldName | Optional | String | Custom field name when the selected dimension references custom fields. |
widgetType | dimension | otherDimension | subType | trendAggregationPeriod | rows ceiling |
|---|---|---|---|---|---|
DISTRIBUTION | Required | — | — | — | ≤ 100 |
GROUPED_DISTRIBUTION | Required | Required | — | — | ≤ 20 |
TREND | Required | — | — | Required | Not specified |
GROUPED_TREND | Required | Required | — | Required | Not specified |
USERS | Conditional | — | Required | — | Not specified |
TOPIC_CLUSTER | Conditional | — | — | — | Not specified |
STREAM | Not supported here — use /listening/query/stream |
Derived from the conditionality notes in the supplied widget specification. The rows ceilings for TREND, GROUPED_TREND, USERS, and TOPIC_CLUSTER are not stated in any supplied source — confirm before relying on large page sizes.
curl -X POST 'https://api3.sprinklr.com/api/v3/listening/query/widget' \
-H 'Authorization: Bearer {{accessToken}}' \
-H 'Key: {{apiKey}}' \
-H 'Content-Type: application/json' \
-d '{
"sinceTime": 1488034511000,
"untilTime": 1490972111000,
"details": {
"widgetType": "DISTRIBUTION",
"dimension": "SENTIMENT"
},
"filters": [
{
"dimension": "TOPIC",
"filterValues": ["595c50dbe4b064e21f85d074"]
}
],
"metric": "MENTIONS"
}'Illustrative example, reproduced from the supplied specification.
{
"data": [
{
"word": "Twitter",
"id": "TWITTER",
"count": 21,
"values": {},
"additional": {}
},
{
"word": "Blogs/Websites",
"id": "BLOGS",
"count": 9,
"values": {},
"additional": {}
}
]
}| Parameter | Type | Description |
|---|---|---|
data | Array | Widget data returned by the API. |
data[].word | String | Display label of the result bucket. |
data[].id | String | Unique identifier for the bucket. |
data[].count | Long | Aggregated metric count. |
data[].values | Object | Additional metric breakdown values. |
data[].additional | Object | Additional metadata associated with the bucket. |
| Endpoint | Envelope | Result location | More-pages flag |
|---|---|---|---|
/listening/query/stream | { "data": { "result": [], "hasMore": bool }, "errors": [] } | data.result | data.hasMore |
/listening/query/widget | { "data": [ … ] } per example; APIResponse per specification | data | Not documented |
sprinklr-v3.yaml defines each Error with three required properties:
| Field | Type | Description |
|---|---|---|
id | String | 24-character hex ObjectId |
code | Integer | Error code |
message | String | Dotted error key (for example, account.not.found) |
Because message is a dotted error key rather than prose, do not surface it directly to end users. Map codes to your own copy.
Both operations declare the same responses in sprinklr-v3.yaml:
| HTTP Code | Scenario | Description |
|---|---|---|
200 OK | Success | Query executed; results returned in the envelope. |
400 Bad Request | Invalid request | Malformed body, missing required field, or an invalid widgetType / dimension combination. |
401 Unauthorized | Authentication failed | Invalid or missing Authorization token. |
403 Forbidden | Insufficient permissions | The API key's user lacks permission on the requested Listening data. |
404 Not Found | Not found | Referenced resource not found. |
500 Internal Server Error is not declared on these two operations in the supplied specification. Still handle it — but note the specification omission (§12).
Always inspect the errors array even on a 200.
This section is for developers already running against POST /api/v2/listening/query/stream.
POST /api/v2/listening/query/stream— path simplified- Request body fields (
sinceTime,untilTime,filters,rows,start, etc.) remain unchanged- Response wrapped in
{ "data": { "result": [...] }, "errors": [] }envelope — already V3 compliant, no change needed
So for the stream endpoint the migration is, in the common case, a base-URL change and nothing else. Your existing V2 request bodies and your existing V2 response-parsing code both continue to work.
| V2 | V3 |
|---|---|
POST /api/v2/listening/query/stream | POST /api/v3/listening/query/stream |
| No documented V2 equivalent in the supplied sources | POST /api/v3/listening/query/widget |
The widget endpoint is the new capability in this release. The V2 Listening Streams page documents widgetType values for TREND / GROUPED_TREND in trendAggregationPeriod
Values below are only those attested in the supplied sources. These lists are not exhaustive; the widget specification says "Supported values include".
details.widgetType — STREAM (stream endpoint only), DISTRIBUTION, GROUPED_DISTRIBUTION, TREND, GROUPED_TREND, USERS, TOPIC_CLUSTER
metric — MENTIONS (default), REACH, RETWEETS, FAVORITES
filters[].dimension — TOPIC, TOPIC_GROUP, SENTIMENT, MEDIA_SOURCE
details.dimension — SENTIMENT, TOPIC, MEDIA_SOURCE
timeField — SN_CREATED_TIME (default), SYSTEM_CREATED_TIME
sortKey (stream only) — CREATED_TIME (default), SYSTEM_CREATED_TIME, MODIFIED_TIME
trendAggregationPeriod — HOUR, DAY, WEEK, MONTH, QUARTER, YEAR
messageFormatOptions — strip_html, strip_url, include_original (comma-delimited)
channelType values seen in responses — REDDIT, TWITTER, INSTAGRAM; accountType — SUBREDDIT, TWITTER; sourceType — ACCOUNT, LISTENING
Scenario: you currently page the whole stream for a Topic just to count mentions by sentiment.
Stop. Call the widget endpoint once:
{
"sinceTime": 1488034511000,
"untilTime": 1490972111000,
"details": { "widgetType": "DISTRIBUTION", "dimension": "SENTIMENT" },
"filters": [{ "dimension": "TOPIC", "filterValues": ["595c50dbe4b064e21f85d074"] }],
"metric": "MENTIONS"
}One request replaces an unbounded pagination loop, and it is unaffected by the 1,000-per-request stream cap.
Scenario: nightly export of every mention on a Topic.
The two limits in §4.1 interact. A single request returns at most 1,000 messages, and you cannot fetch more than 10,000 messages in a same timestamp. So:
- Split the day into windows using
sinceTime/untilTime. - Within a window, page with
startandrows(rows≤ 1,000). - Continue while
data.hasMoreistrue. - If a window approaches 10,000 messages, narrow the window rather than paging deeper.
- Pin
timeFieldexplicitly —SN_CREATED_TIMEfor "when it was posted",SYSTEM_CREATED_TIMEfor "when Sprinklr saw it". A backfill will scatter across the two very differently.
async function fetchWindow(sinceTime, untilTime, topicId) {
const rows = 1000; // per-request maximum
let start = 0;
const all = [];
while (true) {
const res = await post('/api/v3/listening/query/stream', {
sinceTime, untilTime,
timeField: 'SN_CREATED_TIME',
details: { widgetType: 'STREAM' },
filters: [{ dimension: 'TOPIC', filterValues: [topicId] }],
metric: 'MENTIONS',
sortKey: 'CREATED_TIME',
rows, start
});
if (res.errors && res.errors.length) {
handleErrors(res.errors); // dotted keys, e.g. account.not.found
break;
}
all.push(...res.data.result);
if (!res.data.hasMore) break; // note: nested under data, not at root
start += rows;
if (start >= 10000) { // same-timestamp ceiling — narrow the window
throw new Error('Window too dense; split the time range');
}
}
return all;
}Scenario: poll every 15 minutes for new mentions.
Use timeField: "SYSTEM_CREATED_TIME" and window on Sprinklr's ingestion time, not the social network's. A message posted three days ago but ingested five minutes ago will be missed entirely by an SN_CREATED_TIME window — this is the single most common cause of "the API is dropping messages" reports.
Use tag to stamp each poll with your own cursor version; the API returns it unchanged, which makes correlating a response to the request that produced it trivial in logs.
Scenario: a dashboard cell showing sentiment split within each media source.
{
"sinceTime": 1488034511000,
"untilTime": 1490972111000,
"details": {
"widgetType": "GROUPED_DISTRIBUTION",
"dimension": "MEDIA_SOURCE",
"otherDimension": "SENTIMENT",
"otherDimensionRows": 5
},
"filters": [{ "dimension": "TOPIC", "filterValues": ["595c50dbe4b064e21f85d074"] }],
"metric": "MENTIONS",
"rows": 20
}GROUPED_DISTRIBUTION caps rows at 20. Do not request more.
Scenario: daily mention volume over a quarter.
Set widgetType: "TREND" and — this is mandatory for trend types — trendAggregationPeriod: "DAY". Omitting it is a 400.
{
"sinceTime": 1488034511000,
"untilTime": 1490972111000,
"details": { "widgetType": "TREND", "dimension": "TOPIC" },
"trendAggregationPeriod": "DAY",
"filters": [{ "dimension": "TOPIC", "filterValues": ["595c50dbe4b064e21f85d074"] }],
"metric": "MENTIONS",
"timezoneOffset": -18000000
}Set timezoneOffset deliberately on any trend query. It defaults to 0 (UTC), so a "daily" trend for a US brand will otherwise bucket on UTC midnight and shift every peak by five hours.
Scenario: a Topic is polluted by one recurring source.
Add a second filter with exclude: true:
"filters": [
{ "dimension": "TOPIC", "filterValues": ["595c50dbe4b064e21f85d074"] },
{ "dimension": "MEDIA_SOURCE", "filterValues": ["BLOGS"], "exclude": true }
]Scenario: you are pushing message text into a search index that chokes on HTML and URLs.
Set messageFormatOptions: "strip_html,strip_url,include_original". You get clean text for indexing plus the untouched original in originalText for display and audit.
Scenario: support reports blank message bodies.
Check apiStatus on the affected messages first (§4.8). "Removed fields because of resyndication policy" means the channel — not Sprinklr, and not your code — withheld the field. Resolution is a Sprinklr Support request to enable the relevant syndication (for example, Twitter Syndication), not a code change.
Choosing the endpoint
- Messages →
/listening/query/stream. Aggregates →/listening/query/widget. STREAMis not a validwidgetTypeon the widget endpoint.- Both endpoints share one request schema. Build one request-builder, parameterise
details.
Volume and pagination
- Max 1,000 messages per request. Max 10,000 messages in a same timestamp.
startandrowsapply toSTREAMonly.- Page while
data.hasMoreistrue— note it is nested underdata, unlike other V3 APIs. DISTRIBUTIONcapsrowsat 100;GROUPED_DISTRIBUTIONcaps at 20.
Time handling
sinceTimeanduntilTimeare epoch milliseconds, not seconds and not ISO-8601.timeFielddefaults toSN_CREATED_TIME. Choose it explicitly.timezoneOffsetdefaults to0(UTC) and is expressed in milliseconds — EST is-18000000.
Filters
filterValuestakes IDs, not names. Resolve Topic IDs through the Listening Topic APIs.exclude: trueinverts a filter; default isfalse.customFieldNameis required when filtering on custom-field dimensions.- Filter values you cannot see under governance return nothing rather than an error.
Trends
trendAggregationPeriodis required forTRENDandGROUPED_TREND, and ignored elsewhere.
Entitlement and content
- Listening is not enabled by default — it requires an explicit Support request.
- Empty
content.textwith anapiStatusnote is a resyndication restriction, not a bug. -1insenderProfile.followers,following, orstatusCountmeans unavailable, not zero. Do not sum it.
Error handling
- Inspect
errorson every response, including200. errors[].messageis a dotted key (account.not.found), not user-facing prose. Map it.500is not declared on these operations in the specification, but handle it anyway.
Operational
taground-trips unchanged — use it as a request correlation ID.echoRequest: truereturns your request alongside the response; useful in debugging, wasteful in production.- Rate limits for these two endpoints are not documented in any supplied source. Implement retry with exponential backoff regardless, and confirm the actual limits with the API owner.
All JSON payloads in this guide are illustrative examples derived from the supplied specifications and published references. They are not real customer data and are not guaranteed production responses. All credentials are placeholders ({{accessToken}}, {{apiKey}}) and must never be committed or logged. No API call was executed and no linting or validation tool was run in the course of producing this guide.