Skip to navigation

Analytics

Product Search is in beta with design partners. Endpoints roll out per tenant.

Send events

Send events from the application with the search key, or from a browser with a scoped key. Tie a click or conversion to the search that produced it with the query_id from the search reply.

Send user_token on each search, the same value as the events’ userToken. A search with a user token is a tracked search: the click-through and conversion rates count only tracked searches, and Count Users counts distinct user tokens. A search without one still counts as a search. On the Algolia-compatible routes, userToken or the X-Algolia-UserToken header does the same.

curl -X POST "https://acme.captain.dev/v1/events" \
-H "Authorization: Bearer $CAPTAIN_SEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"eventType": "click",
"eventName": "Result clicked",
"index": "products",
"userToken": "user-481",
"queryID": "7f3a9c2e4b1d48e6a0c5d2f18b93e470",
"objectIDs": [
"sku-10482"
],
"positions": [
1
]
}
]
}'
Example: (200 OK)
{
"accepted": 1
}

Up to 1,000 events per request. A click tied to a search carries one position per record id, starting at 1.

Read analytics

curl -G "https://acme.captain.dev/v1/indexes/products/analytics" \
-H "Authorization: Bearer $CAPTAIN_SEARCH_KEY" \
--data-urlencode "days=7"
Example: (200 OK)
{
"dataset": "products",
"days": 7,
"search_requests": 48213,
"searches": 9604,
"top_queries": [
{
"query": "hiking boots",
"count": 412,
"avg_hits": 42.0
},
{
"query": "rain jacket",
"count": 355,
"avg_hits": 18.0
},
{
"query": "trail running shoes",
"count": 298,
"avg_hits": 37.0
}
],
"zero_result_queries": [
{
"query": "gaiter size chart",
"count": 21
},
{
"query": "crampons",
"count": 14
}
],
"zero_result_rate": 0.0187,
"events": {
"click": 3920,
"conversion": 611,
"view": 12078
},
"click_through_rate": 0.3842,
"mean_click_position": 2.34,
"conversion_rate": 0.0642,
"tracked_searches": 9517
}
FieldMeaning
searchesSearches in the period. Keystrokes on the way to a search count once.
top_queriesThe most frequent searches, with their average number of results.
zero_result_queries, zero_result_rateSearches that returned nothing.
click_through_rate, mean_click_positionShare of tracked searches with a click, and where the clicks landed.
conversion_rateShare of tracked searches followed by a conversion.
eventsEvent counts by type.
tracked_searchesSearches that carried a user token, the base for the rates above.

Before an index’s first build, analytics return 200 with empty reports, since the index hasn’t served any searches yet.

Query logs can hold sensitive text. On an index with per-record access control, Captain provides analytics until a dedicated analytics key is available.

Analytics by metric

Each metric also has its own endpoint, for dashboards that chart one number over time. They take start_date and end_date (UTC, inclusive, YYYY-MM-DD, the last 7 days by default). For an exact window, send start_time and end_time instead, as unix seconds or ISO 8601 in UTC (2026-10-10T10:00:00Z). end_time is exclusive. The list endpoints also take limit and offset. Every analytics answer carries partial. Analytics requests usually answer within 6 seconds and within about 7.5 seconds at most, even when several dashboards ask at once. A window too large to read whole in that time (more than 500,000 searches, or more than about 3.5 seconds of reading) answers with what was counted, partial: true, partial_reason (row_budget or time_budget) and counted_through, the time of the last record counted. Ask for fewer days to get whole numbers. The same report asked again within a minute, with no new searches since, answers at once.

EndpointReturns
Count SearchesSearches in total and per day.
List Top SearchesThe most frequent searches, with average results, and click-through and conversion rates with with_rates=true.
List No-Result SearchesThe most frequent searches that returned nothing, and the no-result rate.
List No-Click SearchesThe most frequent tracked searches with no click, and the no-click rate.
Get ClicksThe click-through rate, the average click position and clicks per position.
Get ConversionsThe share of tracked searches followed by a conversion.
List Top HitsThe records clicked most often, for all searches, for one (search), or for up to 25 at once (searches, separated by commas).
Count UsersDistinct user tokens, in total and per day.
List Top FiltersThe fields searches filtered on most often.
List Filter ValuesThe values one field was filtered by most often.
Get RevenueRevenue, orders and average order value that searches earned, by day, from purchase events, with the shopper funnel from search to purchase.

Rates come with a daily series, so one call fills a chart.

For example, the top searches of the last week:

curl -G "https://acme.captain.dev/v1/indexes/products/analytics/searches" \
-H "Authorization: Bearer $CAPTAIN_SEARCH_KEY" \
--data-urlencode "start_date=2026-09-22" \
--data-urlencode "end_date=2026-09-28" \
--data-urlencode "limit=3"
Example: (200 OK)
{
"start_date": "2026-09-22",
"end_date": "2026-09-28",
"searches": [
{
"search": "hiking boots",
"count": 412,
"avg_hits": 42.0
},
{
"search": "rain jacket",
"count": 355,
"avg_hits": 18.0
},
{
"search": "trail running shoes",
"count": 298,
"avg_hits": 37.0
}
]
}