Search
Query customers, conversations, messages, companies, notes and custom objects with Kustomer's search API, including filters, operators, dates, custom attributes, sorting, limits and every standard attribute.
The search API runs the same queries as saved searches in Kustomer. One endpoint covers every object type: you pick what to return with queryContext, and filter with and, or and not criteria on any standard or custom attribute.
/v1/customers/search
curl -X POST "https://acme.api.kustomerapp.com/v1/customers/search?pageSize=100" \
-H "Authorization: Bearer $KUSTOMER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"queryContext": "conversation",
"and": [
{ "conversation_status": { "equals": "open" } },
{ "conversation_priority": { "gte": 4 } },
{ "conversation_created_at": { "gte": "2026-10-01" } }
],
"timeZone": "America/New_York"
}'Despite the path, the endpoint isn't limited to customers. With queryContext: "conversation", it returns conversations.
Request body
queryContextstringrequired- What to return:
customer,conversation,message,company,note,kobject,kobject_<klass>,conversation_time,work_sessionorwork_item. andobject[]- Every criterion must match.
orobject[]- At least one criterion must match.
notobject | object[]- Exclude matches.
sortobject[]- Sort order. Only customer attributes are sortable (see below).
timeZonestring- IANA time zone applied to local dates such as
2026-10-01. Defaults to GMT. includeDeletedboolean- Include deleted records.
fieldsobject[]- Limit the attributes returned (up to 20).
Query parameters: page, pageSize (up to 500), and idsOnly=true to return only matching IDs, which is faster for large syncs.
Criteria
Each criterion maps one attribute to one operator and value:
{ "<attribute>": { "<operator>": <value> } }Attribute names are <object>_<attribute> in snake case, such as conversation_status or customer_created_at. You can filter on attributes of related objects too: a customer search can filter on conversation_status to find customers with open conversations.
Operators
Which operators an attribute accepts depends on its operator group, listed in the standard attributes tables.
in and not_in take arrays. is_set and not_set ignore their value; send an empty string (company searches need true). contains is case-insensitive.
Combining criteria
{
"queryContext": "customer",
"and": [{ "customer_custom_loyaltyTierStr": { "equals": "gold" } }],
"or": [
{ "conversation_status": { "equals": "open" } },
{ "conversation_status": { "equals": "snoozed" } }
],
"not": [{ "customer_email": { "contains": "@acme.example" } }]
}{"queryContext": "conversation","and": [{ "conversation_status": { "equals": "open" } },{ "conversation_priority": { "gte": 4 } },{ "conversation_created_at": { "gte": "2026-10-01" } }],"timeZone": "America/New_York"}
- #1Where is my order?openP4Oct 03Jane Riveragoldcust. updated Oct 18
- #2Damaged item on arrivalopenP5Oct 19Luis Ortegagoldcust. updated Oct 13
- #3Order arrived lateopenP4Oct 20Ben Cartersilvercust. updated Oct 16
- outRefund for #4417snoozedP3Oct 12Omar Haddadsilvercust. updated Oct 20
- outChange shipping addressopenP2Oct 15Mia Chenbronzecust. updated Oct 09
- outCancel my subscriptiondoneP3Sep 28Ava Patelsilvercust. updated Oct 02
- outPromo code not workingopenP1Oct 07Noah Kimbronzecust. updated Oct 14
- outExchange for a larger sizesnoozedP4Oct 05Zoe Martingoldcust. updated Oct 11
- outInvoice copy requestdoneP2Oct 16Ethan Brooksbronzecust. updated Oct 17
- outPackage not deliveredopenP5Sep 30Sofia Rossisilvercust. updated Oct 06
- outWarranty claimsnoozedP5Oct 17Liam Walshgoldcust. updated Oct 19
- outUpdate billing emaildoneP1Oct 10Grace Leegoldcust. updated Oct 12
in under and, or one equals each under or. Local dates are read in timeZone, and lte includes the whole day. Sorting uses customer attributes even for conversation results.Dates
Dates can be local (YYYY-MM-DD) or UTC timestamps:
- A local date is interpreted in
timeZone, or GMT if you omit it.{"conversation_created_at": {"lte": "2026-10-19"}}with"timeZone": "America/New_York"means "up to the end of 19 October, New York time." - A UTC timestamp such as
2026-10-20T16:34:00.000Zis used exactly, with no time-zone adjustment.
Custom attributes
The attribute's suffix decides its operator group: Str behaves like string, Num like number, At like datetime, Bool like boolean.
Sorting
Sorting only works on customer attributes, whatever the queryContext:
{ "sort": [{ "customer_updated_at": "asc" }] }Sortable attributes: customer_name, customer_gender, customer_created_at, customer_updated_at, customer_modified_at, customer_externalId, customer_activity_at, customer_last_seen_at, customer_signed_up_at, customer_lastmessage_preview, customer_progressive_status, customer_done, customer_open, customer_snoozed, customer_last_message_sent_at, customer_last_message_out_sent_at, customer_last_message_unresponded_to_sent_at, customer_last_message_at.
Response
{
"meta": { "pageSize": 100, "page": 1, "total": 238, "totalPages": 3 },
"links": { "self": "...", "next": "..." },
"data": [
{ "type": "conversation", "id": "58228e05d4e96711004eccb7", "attributes": { "name": "Where is my order?", "status": "open" } }
]
}Limits
- 10,000 results per query.
pageSizegoes up to 500, and a request wherepage × pageSizeis over 10,000 returns400. For bigger result sets, window the query byupdated_atand run one search per window. Search recipes has the code. - Two years of data. Search covers records updated in the past two years. For older standard and custom objects, use the archive search endpoint with the same body:
/v1/customers/archive/search
- Rate limit. Machine users (API keys) can make 100 search requests per minute. See Rate limits.
- Index delay. Search is updated asynchronously, so a record you just created can take a moment to appear. To read your own writes, fetch the record by ID or
externalId.
Standard attributes JSON schema
Every standard attribute you can filter on, grouped by object. The operator group decides which operators apply. The full JSON schema is also in the search endpoint's reference.