Skip to content

Search API V3 — Developer Guide


1. Overview

Search helps you quickly find and access Sprinklr entities — assets, campaigns, dashboards, cases, macros, rules, and tasks — saving time locating the data you want to view. The Search API exposes that capability programmatically: you post a filter expression against an entity type and receive a page of matching records plus a cursor for the next page.

Search V3 is one path parameterized by entity type, with three operations:

OperationMethodPathoperationId
Search entities by entity typePOST/api/v3/search/{apiEntityName}SearchApiV3_searchEntities
Fetch the next page using a cursorGET/api/v3/search/{apiEntityName}?cursor={cursorId}SearchApiV3_searchEntitiesByCursor
Search entities using query parametersGET/api/v3/search/{apiEntityName}/querySearchApiV3_searchEntitiesByQuery

1.1 How a search works

  1. POST the filter to /api/v3/search/{apiEntityName}. The body carries filter, and optionally timeFilter, sorts, page, and field projection.
  2. Sprinklr returns data.results (the page of records) and data.cursor (an opaque token, for example id=6a062c9faffcb59a7b0a9e30).
  3. GET /api/v3/search/{apiEntityName}?cursor={cursorId} to fetch the next page. Repeat until results are exhausted.

The cursor is only valid for five minutes. If it expires, regenerate one with a fresh POST search. Do not persist cursors across jobs or store them in a queue that may be drained slowly.

1.2 The filter model

Every search is driven by a single root filter object, which is recursive:

filter
├── type      → the operator (AND, OR, NOT, IN, EQUALS, GT, LT, EXISTS, …)
├── filters[] → nested Filter objects (used by the boolean operators)
├── key       → the field being filtered (used by the leaf operators)
└── values[]  → the values to match against key

Boolean operators (AND, OR, NOT) carry filters[]. Leaf operators (IN, EQUALS, GT, and so on) carry key and values.

timeFilter is a separate, sibling object to filter, not a filter type. It bounds the result set by a single time field with since and until.


2. Base URLs and environments

All API calls are sent to the production endpoint:

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

So the search resource is:

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

Replace {env} with your assigned environment identifier (prod0, prod2, prod11, and so on — see APIs | Sprinklr Developer Portal for the environment list).


3. Authentication and common headers

All Search API calls are authenticated with OAuth 2.0. See Developer Tools in Sprinklr for API key and secret generation, and the Authorize flow.

HeaderValueDescriptionRequired on
Authorization******Credential used by the API to authenticate a user with the serverAll requests
Key{{apiKey}}API key that authenticates the application with the serverAll requests
Content-Typeapplication/jsonRepresentation header that determines the type of data present in the request bodyPOST
Acceptapplication/jsonDetermines the acceptable response type from the serverAll requests

4. Search by entity

POST /api/v3/search/{apiEntityName}

Fetches data for an entity type using filters. The response carries a cursor you can pass to Search by cursor to fetch the next set of data.

4.1 Path parameter

ParameterRequiredTypeDescription
apiEntityNameRequiredStringThe type of entity you are searching for. See §4.6.

4.2 Request body

ParameterSub-parameterRequiredTypeDescription
filterRequiredObjectFilter to apply on the entity type
typeRequiredStringThe filter type. Supported types: AND, OR, NOT, IN, GT, GTE, LT, LTE, NIN, EQUALS, NOT_EQUALS, CONTAINS. See §4.3.
filtersRequiredList[Filter]The list of nested filters. The type of filter must match the provided key and values.
keyRequiredStringThe key on which you want to apply the filter
valuesRequiredList[String]The value of the key. It must match the key.
timeFilterOptional — required for the MESSAGE entity typeObjectThe time range filter for the entities
keyRequiredStringThe key on which the time filter is applied, for example channelCreatedTime or createdTime
sinceRequiredLong (epoch ms)Time since when you want to fetch the results
untilRequiredLong (epoch ms)Time until when you want to fetch the results
sortsRequiredList[Object]Sorting information
keyRequiredStringKey on the basis of which you want to sort the query
orderOptionalStringSort in ascending or descending order — ASC or DESC
pageRequiredObjectPagination information
startOptionalIntegerSpecifies the starting index for pagination when retrieving records. Use this parameter to define the position from which the API should begin returning results.
sizeRequiredIntegerSize of the page to fetch in the response
cursorOptionalStringCursor token, as an alternative to the id query parameter on the cursor GET
qOptionalStringKeyword to search in the asset
includeCountOptionalBooleanWhen set to true, the response includes the total number of records available for the specified entity type. This helps determine the overall dataset size when implementing pagination. Supported only for the Case entity type.
includeFieldsOptionalList[String]Fields to include in the search results
excludeFieldsOptionalList[String]Fields to exclude from the search results
userIdOptionalLongSprinklr user ID
impersonatorOptionalStringImpersonation identifier

4.3 Filter types

Filter typeDescription
ANDSimilar to boolean AND. Added where more than one filter exists; returns values that meet all filter conditions.
ORSimilar to boolean OR. Added where more than one filter exists; returns values that meet at least one filter condition.
NOTSimilar to boolean NOT — returns values that do not match the applied filter conditions.
INReturns resources where the key matches any of the values mentioned in the list of values
NIN (not in)Returns resources where the key does not match the values mentioned in the list of values
EQUALSReturns resources where the given key is equal to the value(s) mentioned in the list of values
NOT_EQUALSReturns resources where the given key is not equal to the value(s) mentioned in the list of values
GT (greater than)Returns resources where the key is greater than the value(s) mentioned in the list of values
GTE (greater than or equal to)Returns resources where the key is greater than or equal to the value(s) mentioned in the list of values
LT (less than)Returns resources where the key is less than the value(s) mentioned in the list of values
LTE (less than or equal to)Returns resources where the key is less than or equal to the value(s) mentioned in the list of values
CONTAINSReturns resources where the given key contains the values mentioned in the list of values
EXISTSTests for presence of the key. Used by the COMMENT entity for includeReplyOnComments with a value of true or false.
SEARCHFree-text search on the key. Supported on MESSAGE.content.text and SOCIAL_ASSET.name.
BETWEENRange match. Supported on the OUTBOUND_MESSAGE date and time keys.

4.4 Example — search users in a workspace

curl --location 'https://api3.sprinklr.com/{env}/api/v3/search/USER' \
--header 'Authorization: ******' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
    "filter": {
        "type": "AND",
        "filters": [
            {
                "type": "IN",
                "key": "clientAttributes.clientId",
                "values": [
                    "66000002"
                ]
            }
        ]
    },
    "page": {
        "size": 1
    }
}'

Response — 200 OK

{
    "data": {
        "results": [
            {
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:User",
                    "urn:scim:schemas:extension:sprinklrGlobalAttributes:2.0:User",
                    "urn:scim:schemas:extension:sprinklrClientAttributes:2.0:User",
                    "urn:scim:schemas:extension:sprinklrUserAssignmentConfig:2.0:User",
                    "urn:scim:schemas:extension:sprinklrUserVoiceConfig:2.0:User",
                    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
                ],
                "id": "66016438",
                "externalId": "",
                "userName": "nitish.kumar@example.com",
                "name": {
                    "familyName": "Kumar",
                    "givenName": "Nitish"
                },
                "active": true,
                "locale": "en_US",
                "userPermissions": [
                    {
                        "entityType": "FOLDER",
                        "permissions": [
                            "LOCK_UNLOCK",
                            "CREATE",
                            "VIEW"
                        ]
                    }
                ],
                "accessibleClientIds": [],
                "globalAttributes": {},
                "clientAttributes": [],
                "meta": {
                    "resourceType": "User",
                    "createdTime": "2025-01-21 11:58:00",
                    "lastModified": "2026-05-14 19:50:08"
                }
            }
        ],
        "cursor": "id=6a062c9faffcb59a7b0a9e30"
    },
    "errors": []
}

USER results are SCIM-shaped: they declare schemas, and attributes are split across globalAttributes (partner level), clientAttributes (workspace level), and meta. Note that meta.createdTime and meta.lastModified are formatted date strings ("2025-01-21 11:58:00"), not epoch milliseconds — unlike every other entity in this guide.

4.5 Example — search cases with a compound filter

This request combines an EQUALS on caseNumber with a GT on modifiedTime under a single AND.

curl --location 'https://api3.sprinklr.com/{env}/api/v3/search/CASE' \
--header 'Authorization: ******' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
    "filter": {
        "type": "AND",
        "filters": [
            {
                "type": "EQUALS",
                "key": "caseNumber",
                "values": [
                    "6771665"
                ]
            },
            {
                "type": "GT",
                "key": "modifiedTime",
                "values": "1708873480000"
            }
        ]
    },
    "page": {
        "size": 10
    }
}'

Response — 200 OK (custom properties abridged)

{
    "data": {
        "results": [
            {
                "id": "67bdcfb28d6fd17e6994284d",
                "caseNumber": 6771665,
                "subject": "#6771665 Facebook Avinash Sprinklr",
                "description": "asd",
                "version": 74,
                "status": "New",
                "priority": "Medium",
                "caseType": "Complaint",
                "externalCase": {
                    "id": "500Ig000008xfSOIAY",
                    "caseNumber": "00005264",
                    "channelType": "SALESFORCE",
                    "permalink": "https://sprinklr-2a-dev-ed.develop.my.salesforce.com/500Ig000008xfSOIAY",
                    "createdTime": 1740493057000,
                    "modifiedTime": 1740494158000
                },
                "externalCaseInfo": {
                    "externalCases": []
                },
                "workflow": {
                    "customProperties": {
                        "_c_674db30dd6266d683949a697": ["50"],
                        "_c_65252be5825bb637b9857139": ["147258"],
                        "spr_uc_priority": ["Medium"]
                    },
                    "queues": []
                },
                "channelCustomProperties": [],
                "contact": {
                    "id": "FACEBOOK_110103441967171",
                    "name": "Addy Wayne Enterprise",
                    "channelType": "FACEBOOK",
                    "channelId": "110103441967171",
                    "fromSnUserId": "110103441967171"
                },
                "createdTime": 1740492722458,
                "modifiedTime": 1740838601419,
                "firstMessageId": "ACCOUNT_66005064_1740397109000_FACEBOOK_97_122199892268193678_930538535817351",
                "sentiment": -1,
                "latestProfileMessageAssociatedTime": 1740397109000,
                "conversationId": "240539989134747_122199892268193678",
                "firstMessageAssociatedTime": 1740397109000,
                "latestMessageAssociatedTime": 1740397109000,
                "totalProcessingClockTime": 19442359,
                "allEngagedUsersList": [
                    "66008592"
                ],
                "associatedFanMessageCount": 1,
                "associatedBrandMessageCount": 0,
                "associatedUserBrandMessageCount": 0,
                "deleted": false,
                "latestMessageId": "ACCOUNT_66005064_1740397109000_FACEBOOK_97_122199892268193678_930538535817351",
                "conversationIntentIds": []
            }
        ]
    },
    "errors": []
}

data.cursor is absent from this response. The result set (1 record) was smaller than the requested page size (10), so there is no next page. Always check for the presence of cursor rather than assuming it exists — see §8.

Search results for CASE use the same Case schema returned by the Case API. See the Case API V3 Developer Guide for the full field reference.

4.6 Supported entity types

The following entity types are supported: MESSAGE, CASE, USER, OUTBOUND_MESSAGE, CAMPAIGN, SUB_CAMPAIGN, COMMENT, SOCIAL_ASSET, TASK, AUDIENCE_ACTIVITY, PROFILE, CUSTOM_FIELD, TRANSACTION, assignmentSkill.

4.7 Supported filter keys by entity type

MESSAGE

KeySupported types
sourceTypeIN, NIN, EQUALS, NOT_EQUALS
content.titleIN, NIN, EQUALS, NOT_EQUALS, CONTAINS
content.textIN, SEARCH
channelTypeIN, NIN, EQUALS, NOT_EQUALS
deletedIN, NIN, EQUALS, NOT_EQUALS
enrichments.sentimentIN, NIN, EQUALS, NOT_EQUALS, GT, GTE, LT, LTE
workflow.customProperties / workflow.spaceWorkflows.customPropertiesIN, NIN, EQUALS, NOT_EQUALS
workflow.campaignIdIN, NIN, EQUALS, NOT_EQUALS
postIdIN, NIN, EQUALS, NOT_EQUALS
brandPostEQUALS, NOT_EQUALS
sourceIdIN, NIN, EQUALS, NOT_EQUALS
caseNumberIN, EQUALS

MESSAGE timeFilter keys: channelCreatedTime and createdTime, each supporting LT, LTE, GT, GTE, EQUALS. A timeFilter is required for MESSAGE.

CASE

KeySupported types
idIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
caseNumberIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
externalCase.caseNumberIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
externalCase.channelTypeEQUALS, NOT_EQUALS, IN, NIN
modifiedTimeIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
createdTimeLT, LTE, GT, GTE, EQUALS
contact.channelIdIN, NIN, EQUALS, NOT_EQUALS
workflow.customProperties.{customPropertyId}IN, NIN, EQUALS, NOT_EQUALS
workflow.queues.queueIdEQUALS, NOT_EQUALS, IN, NIN
deletedEQUALS, NOT_EQUALS
latestProfileAUMSnCreatedTimeLT, LTE, GT, GTE, EQUALS

USER

KeySupported types
idIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
userNameIN, NIN, EQUALS, NOT_EQUALS
activeIN, NIN, EQUALS, NOT_EQUALS
clientAttributes.userTypeIN, NIN, EQUALS, NOT_EQUALS
clientAttributes.clientIdIN, NIN, EQUALS, NOT_EQUALS
clientAttributes.clientCustomPropertiesIN, NIN, EQUALS, NOT_EQUALS
globalAttributes.partnerCustomPropertiesIN, NIN, EQUALS, NOT_EQUALS
globalAttributes.federationIdIN, NIN, EQUALS, NOT_EQUALS
globalAttributes.passwordLoginDisabledIN, NIN, EQUALS, NOT_EQUALS
meta.lastModifiedLT, LTE, GT, GTE, EQUALS
meta.createdTimeLT, LTE, GT, GTE, EQUALS

PROFILE

KeySupported types
idIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
channelTypeIN, NIN, CONTAINS
channelIdIN, NIN, CONTAINS
contact.emailIN, NIN, EQUALS, NOT_EQUALS
contact.phoneNoIN, NIN, EQUALS, NOT_EQUALS
profileWorkflow.customPropertiesIN, NIN, EQUALS, NOT_EQUALS
profileWorkflow.profileSpaceWorkflows.customPropertiesIN, NIN, EQUALS, NOT_EQUALS
profileWorkflow.profileListsIN, NIN, EQUALS, NOT_EQUALS
profileWorkflow.profileSpaceWorkflows.profileListsIN, NIN, EQUALS, NOT_EQUALS
createdTimeLT, LTE, GT, GTE, EQUALS
modifiedTimeLT, LTE, GT, GTE, EQUALS

COMMENT

KeySupported types
entityType (UNIVERSAL_CASE / MESSAGE_WORKFLOW / PROFILE_WORKFLOW)IN, NIN, EQUALS, NOT_EQUALS
entityId (case number, message ID, or profile ID)IN, NIN, EQUALS, NOT_EQUALS
includeReplyOnCommentsEXISTS → true / false
createdTimeLT, LTE, GT, GTE, EQUALS

entityId and entityType are required filters when searching for a comment.

SOCIAL_ASSET

KeySupported types
idIN, NIN, EQUALS, NOT_EQUALS
assetTypeIN, NIN, EQUALS, NOT_EQUALS
assetSourceIN, NIN, EQUALS, NOT_EQUALS
statusIN, NIN, EQUALS, NOT_EQUALS
taxonomy.clientCustomPropertiesIN, NIN, EQUALS, NOT_EQUALS
taxonomy.partnerCustomPropertiesIN, NIN, EQUALS, NOT_EQUALS
restrictedIN, NIN, EQUALS, NOT_EQUALS
validity.availableFromIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
validity.expiryTimeIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
shareConfigs.typeIN, NIN, EQUALS, NOT_EQUALS
templateTypeIN, NIN, EQUALS, NOT_EQUALS
channelsIN, NIN, EQUALS, NOT_EQUALS
nameSEARCH

CAMPAIGN / SUB_CAMPAIGN

KeySupported types
idIN, NIN, EQUALS, NOT_EQUALS
nameIN, NIN, CONTAINS
descriptionIN, NIN, CONTAINS
startDateLT, LTE, GT, GTE, EQUALS
endDateLT, LTE, GT, GTE, EQUALS
tagsIN, NIN, EQUALS, NOT_EQUALS
ownerIN, NIN, EQUALS, NOT_EQUALS
statusIN, NIN, EQUALS, NOT_EQUALS
archivedEQUALS, NOT_EQUALS
partnerCustomPropertiesIN, NIN, EQUALS, NOT_EQUALS
clientCustomPropertiesIN, NIN, EQUALS, NOT_EQUALS
createdTimeLT, LTE, GT, GTE, EQUALS
modifiedTimeLT, LTE, GT, GTE, EQUALS

TASK

KeySupported types
idIN, NIN, EQUALS, NOT_EQUALS
taskStatusIN, NIN, EQUALS, NOT_EQUALS
taskTypeIN, NIN, EQUALS, NOT_EQUALS
titleIN, NIN
assetIdIN, NIN, EQUALS, NOT_EQUALS
assetTypeIN, NIN, EQUALS, NOT_EQUALS
customPropertiesIN, NIN, EQUALS, NOT_EQUALS
dueDateLT, LTE, GT, GTE, EQUALS
createdTimeLT, LTE, GT, GTE, EQUALS
modifiedTimeLT, LTE, GT, GTE, EQUALS

AUDIENCE_ACTIVITY

KeySupported types
idIN, NIN, CONTAINS
activityTimeIN, NIN, EQUALS, NOT_EQUALS, LT, LTE, GT, GTE
accountIdIN, NIN, CONTAINS
messageIdIN, NIN, CONTAINS
activityTypeIN, NIN, CONTAINS
channelTypeIN, NIN, CONTAINS

OUTBOUND_MESSAGE

KeySupported types
templateIdIN, NIN
statusIN, NIN
searchDetails.customPropertiesIN, NIN
createdDate / createdTimeGTE, LTE, BETWEEN
scheduleDate / scheduleTimeGTE, LTE, BETWEEN
modifiedDate / modifiedTimeLTE, GTE, BETWEEN
publishedDate / publishedTimeGTE, LTE, BETWEEN

assignmentSkill

KeySupported Filter Types
skillSEARCH, CONTAINS, TEXT_CONTAINS, EQUALS, IN
skillCategoryIN, NIN, EQUALS, NOT_EQUALS
idIN, NIN, EQUALS, NOT_EQUALS
createdTimeLT, LTE, GT, GTE, EQUALS, BETWEEN
modifiedTimeLT, LTE, GT, GTE, EQUALS, BETWEEN

4.8 Filtering on custom properties

Custom properties are addressed by appending the custom field ID to the property path:

"filters": [
    {
        "type": "IN",
        "key": "workflow.customProperties.5e4e5f3954e68b2a475c05b6",
        "values": [
            "Andhra Pradesh"
        ]
    }
]

Resolve custom field IDs by searching the customField entity — see §4.9.

4.9 Example — search custom fields

Use this to discover the custom field IDs you need for the custom-property filters above.

curl --location 'https://api3.sprinklr.com/{env}/api/v3/search/customField' \
--header 'Authorization: ******' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
    "filter": {
        "type": "AND",
        "filters": [
            {
                "type": "LT",
                "key": "createdTime",
                "values": "1708873480000"
            }
        ]
    },
    "page": {
        "size": 10
    }
}'

Response — 200 OK (one result shown)

{
    "data": {
        "results": [
            {
                "id": "65da2e3013e1fe4109b8c77d",
                "fieldName": "_c_65da2e3013e1fe4109b8c779",
                "label": "s12",
                "assetTypes": [
                    "USER"
                ],
                "type": "PICKLIST",
                "values": [
                    { "key": "a", "label": "a" },
                    { "key": "b", "label": "b" },
                    { "key": "c", "label": "c" }
                ],
                "enabled": true,
                "visibility": {
                    "globallyVisible": true,
                    "visibilityConfig": []
                },
                "permissions": [],
                "optionType": "GENERAL",
                "accessibleClientIds": [
                    66000004,
                    66000010,
                    66000050
                ],
                "createdTime": 1708797488387,
                "modifiedTime": 1779195803742
            }
        ],
        "cursor": "id=6a0cca9fa62597c1d8643b11"
    },
    "errors": []
}

4.10 Example — search comments on a case

curl --location 'https://api3.sprinklr.com/{env}/api/v3/search/COMMENT' \
--header 'Authorization: ******' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
    "filter": {
        "type": "AND",
        "filters": [
            {
                "type": "IN",
                "key": "entityType",
                "values": [
                    "UNIVERSAL_CASE"
                ]
            },
            {
                "type": "IN",
                "key": "entityId",
                "values": [
                    "829"
                ]
            },
            {
                "type": "EXISTS",
                "key": "includeReplyOnComments",
                "values": [
                    "false"
                ]
            }
        ]
    },
    "page": {
        "size": 2
    },
    "sorts": [
        {
            "key": "createdTime",
            "order": "ASC"
        }
    ]
}'

Response — 200 OK

{
    "data": {
        "results": [
            {
                "id": "64e5febee06bd348943340bc",
                "text": "<p class=\"export-block__parent\">note1</p>",
                "commentingUser": 66000101,
                "createdTime": 1692794558032,
                "modifiedTime": 1692794558032,
                "entityType": "CASE",
                "entityId": "829",
                "conversationId": "19:6d1c3966-4da1-4eb6-9ee7-b07d72756abf_b1fc70a6-3878-4635-9462-29564f60fa6d@unq.gbl.spaces",
                "externalComment": {
                    "channelType": "MICROSOFT_TEAMS"
                }
            },
            {
                "id": "64e5fec2e06bd3489433420f",
                "text": "<p class=\"export-block__parent\">note 100</p>",
                "commentingUser": 66000101,
                "createdTime": 1692794562227,
                "modifiedTime": 1692794562227,
                "entityType": "CASE",
                "entityId": "829",
                "conversationId": "19:6d1c3966-4da1-4eb6-9ee7-b07d72756abf_b1fc70a6-3878-4635-9462-29564f60fa6d@unq.gbl.spaces",
                "externalComment": {
                    "channelType": "MICROSOFT_TEAMS"
                }
            }
        ],
        "cursor": "id=6a06339daffcb59a7b0aa53f"
    },
    "errors": []
}

Two behaviors worth planning for:

  1. The request filters on entityType: "UNIVERSAL_CASE", but the response returns entityType: "CASE". The filter value and the response value are not the same vocabulary. Do not round-trip the response value back into a filter.
  2. text is HTML, not plain text. Sanitize it before rendering.

4.11 Example — search profiles with a sort

curl --location 'https://api3.sprinklr.com/{env}/api/v3/search/PROFILE' \
--header 'Authorization: ******' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
    "filter": {
        "type": "AND",
        "filters": [
            {
                "type": "IN",
                "key": "channelType",
                "values": [
                    "WHATSAPP_BUSINESS"
                ]
            }
        ]
    },
    "sorts": [
        {
            "key": "modifiedTime",
            "order": "DESC"
        }
    ],
    "page": {
        "size": 10
    }
}'

Response — 200 OK (one result, abridged)

{
    "data": {
        "results": [
            {
                "restricted": false,
                "id": "652425977e759fa6379f4085",
                "contact": {
                    "firstName": "Savy",
                    "lastName": "Sharma",
                    "fullName": "Savy Sharma",
                    "email": "savy.sharma@example.com",
                    "phoneNo": "+919876543210",
                    "website": [
                        "https://www.example.com/"
                    ],
                    "phoneDetails": [
                        { "phoneNo": "+919876543210" }
                    ],
                    "emailDetails": []
                },
                "profileWorkflow": {
                    "profileLists": [
                        332,
                        333,
                        331188,
                        1
                    ],
                    "customProperties": {
                        "_c_64cbf526fd8b0e259d72470a": ["20"],
                        "_c_64e8a89a9deb2c0c668e7a57": [],
                        "last_updated_by_user": ["66000015"]
                    },
                    "profileSpaceWorkflows": [
                        {
                            "profileLists": [1, 5],
                            "tags": [],
                            "spaceId": "66000002"
                        }
                    ]
                },
                "createdTime": 1696867735563,
                "modifiedTime": 1778789065730
            }
        ],
        "cursor": "id=6a0631b9affcb59a7b0aa4d1"
    },
    "errors": []
}

Note that customProperties can contain empty arrays for fields that exist but have no value set. Handle that case rather than assuming a non-empty list.

Profile records also carry the résumé-style arrays works, profiles, demographics, organizations, certificates, recommendations, educations, languages, skills, courses, honors, patents, projects, publications, testScores, and voluntaryExp. Use includeFields or excludeFields to keep responses small if you do not need them.

4.12 Example — search assignment skills

curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/search/assignmentSkill' \
--header 'Authorization: Bearer <token>' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
    "filter": {
        "type": "AND",
        "filters": [
            {
                "type": "SEARCH",
                "key": "skill",
                "values": [
                    "Rahul"
                ]
            }
        ]
    },
    "page": {
        "size": 10
    }
}'

Response — 200 OK

{
    "data": {
        "results": [
            {
                "id": "69bbfbbca50a41755e093bff",
                "skill": "Rahul",
                "skillCategory": "64d2943548ed5b75fb38d34b",
                "createdTime": 1773927356834,
                "modifiedTime": 1773927356834
            }
        ]
    },
    "errors": []
}

6. Search by cursor

GET /api/v3/search/{apiEntityName}?cursor={cursorId}

Fetches the next set of available data. Before using this call, run a Search by entity POST to receive the cursor in the response.

6.1 Parameters

ParameterInRequiredTypeDescription
apiEntityNamePathRequiredStringThe type of entity you are searching for. Must match the entity type used in the originating POST.
cursorQueryRequiredStringCursor ID for pagination. This is the value you received as cursor in the POST response. Example: cursor=5dd2699aaf47f50001d3299d

The cursor ID is only valid for five minutes. If it expires, regenerate a new one with a fresh Search by entity call.

6.2 Reading the cursor value

The Search by Entity API response returns the cursor as a bare query fragment with id= prefix:

"cursor": "id=6a062c9faffcb59a7b0a9e30"

Extract the token, not the prefix. Strip any leading id=.

6.3 Example

curl --location 'https://api3.sprinklr.com/{env}/api/v3/search/USER?cursor=6a062b7daffcb59a7b0a9ccb' \
--header 'Authorization: ******' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'

Response — 200 OK

The response has the identical envelope and record shape as the originating POST, with a new cursor for the following page:

{
    "data": {
        "results": [
            {
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:User",
                    "urn:scim:schemas:extension:sprinklrGlobalAttributes:2.0:User",
                    "urn:scim:schemas:extension:sprinklrClientAttributes:2.0:User"
                ],
                "id": "66070390",
                "userName": "user@example.com",
                "active": true,
                "locale": "en_US",
                "meta": {
                    "resourceType": "User"
                }
            }
        ],
        "cursor": "id=6a062c41affcb59a7b0a9dc6"
    },
    "errors": []
}

Each page returns a fresh cursor. Always use the cursor from the most recent response, never the original one.

6.4 Pagination loop

const entity = 'USER';

let response = await post(`/api/v3/search/${entity}`, {
  filter: {
    type: 'AND',
    filters: [
      { type: 'IN', key: 'clientAttributes.clientId', values: ['66000002'] }
    ]
  },
  sorts: [{ key: 'meta.createdTime', order: 'ASC' }],
  page: { size: 100 }
});

const all = [];

// Accepts a bare token, "id=<token>", "cursor=<token>", or a full URL.
function extractCursorToken(cursor) {
  const withoutUrl = cursor.includes('?') ? cursor.slice(cursor.indexOf('?') + 1) : cursor;
  return withoutUrl.replace(/^(id|cursor)=/, '');
}

while (true) {
  if (response.errors && response.errors.length) {
    handleErrors(response.errors);
    break;
  }

  const data = response.data;
  if (!data || !data.results || data.results.length === 0) break;

  all.push(...data.results);

  // No cursor means there is no next page.
  if (!data.cursor) break;

  // The cursor expires after five minutes — do not queue it for later.
  const token = encodeURIComponent(extractCursorToken(data.cursor));

  // show `id`. Send `cursor`, fall back to `id` until the build is confirmed.
  response = await get(`/api/v3/search/${entity}?cursor=${token}`);
  if (response.errors && response.errors.length) {
    response = await get(`/api/v3/search/${entity}?id=${token}`);
  }
}

7. Response format and status codes

7.1 The V3 envelope

{
  "data": {
    "results": [ ... ],
    "cursor": "id=6a062c9faffcb59a7b0a9e30",
    "count": 42
  },
  "errors": []
}
FieldTypeDescription
data.resultsArrayList of assets returned as part of the search. The record shape is the entity's own schema — Case for CASE, the SCIM user for USER, and so on.
data.cursorStringLink to get the next set of results. Absent when there is no next page. Valid for five minutes.
data.countLongTotal number of records available for the entity type. Returned only when includeCount is true, and supported only for the Case entity type.
errorsArray[Error]Array of error objects. Empty when there were no errors.

7.2 The error shape

On an error, the response contains no data key at all — only errors:

{
    "errors": [
        {
            "id": "6a0633f7affcb59a7b0aa552",
            "code": 400,
            "message": "Invalid entity: LISTENING_TOPIC_BACKFILL"
        }
    ]
}
FieldTypeDescription
idStringRequest identifier. Quote this when raising a support ticket.
codeIntegerError code, mirroring the HTTP status
messageStringHuman-readable description of the failure

7.3 Response codes

HTTP codeScenarioDescription
200 OKSuccessResults returned, with a cursor when a next page exists
400 Bad RequestInvalid requestUnknown entity type, malformed filter, or an unsupported key/type combination. Also observed for transient backend failures, for example "Please try again, cluster: test-inbound1-es".
401 UnauthorizedAuthentication failedInvalid or missing Authorization token
403 ForbiddenInsufficient permissionsThe caller lacks read permission on the entity type
404 Not FoundNot foundThe requested resource does not exist

400 is overloaded. A 400 can mean either a permanent contract violation ("Invalid entity: …") or a transient backend condition ("Please try again, cluster: …"). Inspect errors[].message before deciding whether to retry. Retrying an "Invalid entity" failure will never succeed.


8. V2 → V3 migration

8.1 Endpoint mapping

V2V3
POST /api/v2/search/{entityType} (Search by Entity)POST /api/v3/search/{apiEntityName}
GET /api/v2/search/{entityType}?id={cursorId} (Search by Cursor)GET /api/v3/search/{apiEntityName}?cursor={cursorId} — parameter renamed

9. Use cases

9.1 Export all cases modified since the last sync

Filter CASE on modifiedTime with GT and the timestamp of your previous run, sort by modifiedTime ASC, and page with the cursor. Sorting ascending on the same key you filter on keeps the watermark monotonic, so a mid-run failure can resume from the last record processed rather than restarting.

9.2 Discover custom field IDs before building a filter

Custom properties are keyed by generated IDs such as _c_65da2e3013e1fe4109b8c779, which you cannot guess. Search the customField entity (§4.9), map label → fieldName, and cache the result. Then filter with workflow.customProperties.{fieldName}.

9.3 Pull the agent notes on a case

Search COMMENT with entityType and entityId — both are required for comment searches — sorted by createdTime ASC to get the notes in chronological order (§4.10). Remember that text is HTML and that the response entityType (CASE) differs from the filter value (UNIVERSAL_CASE).

9.4 Reconcile a user directory

Filter USER on clientAttributes.clientId for the workspace, page through with the cursor, and compare userName and active against your IdP. Use excludeFields to drop userPermissions — it is by far the largest part of a user record and is rarely needed for a directory reconciliation.

9.5 Find profiles on a specific channel

Filter PROFILE on channelType with IN, sorted by modifiedTime DESC to surface the most recently active profiles first (§4.11). Add contact.email or contact.phoneNo filters to resolve a specific customer.

9.6 Search messages within a time window

MESSAGE searches require a timeFilter. Set key to createdTime or channelCreatedTime and bound it with since and until:

{
    "filter": {
        "type": "AND",
        "filters": [
            {
                "type": "NOT_EQUALS",
                "key": "brandPost",
                "values": ["true"]
            }
        ]
    },
    "timeFilter": {
        "key": "createdTime",
        "since": 1775939449000,
        "until": 1778790649000
    },
    "page": {
        "size": 10
    }
}

This example filters to inbound (non-brand) messages only. Narrow the window rather than widening the page size when a message search is slow.

9.7 Size a dataset before exporting it

For CASE searches only, set includeCount: true to have the response report the total number of matching records. Use it to decide whether to run an export at all, to estimate runtime, and to validate that your page loop retrieved everything.


All JSON payloads in this guide are illustrative examples. Email addresses, user names, and phone numbers have been replaced with placeholder values. They are not real customer data and are not guaranteed production responses. All credentials are placeholders (******, {{apiKey}}) and must never be committed or logged.