What you need
locale and country are required on every request. A country that is not
mapped to one of your markets returns 404, as does an unknown merchant_id.
Base URL
1. Run a search
POST /search_v2 is a plain HTTPS POST — one request per page, no WebSocket
or Server-Sent Events — whose response body is streamed as
newline-delimited key:value lines, so you can render products before the
response has finished. Each line is a key, a colon, then JSON. If you would
rather not stream, await the whole body and split it on newlines; both
patterns are in
REST or streaming?.
keywordis the product array — the field is not calledproducts.filter_facetslists the filter field names enabled for your account, not values or counts.sortslists the sort options your account offers, on every response. Read thesortrequest field’s allowed values from here rather than hardcoding them.keyword_page_infocarries pagination:has_next_pagesays whether to request the next page,n_hitsis the total. Page size is the request’slimit(default 30, up to 250). See Pagination.errorcan appear mid-stream if retrieval fails after headers were sent. The search failed — render an error state. See Retries for why this case is not the same as a failed request.
search_id identifies one search. Generate a new one when the shopper
submits a query, and reuse it for the pages of that search and for every
tracking event about its results. Changing a filter is a new search —
the modal mints a fresh search_id for it, because the shopper is now
looking at a different result set. Reusing the old id there would merge two
result sets into one row in your analytics. session_id is one id per
browser tab, stable across searches.2. Query suggestions
GET /autocomplete_v2 returns up to three suggestions for a partial query.
Call it as the shopper types.
**bold** marks the part the shopper has not typed
yet. Render the markdown, but search the plain text — strip the markers
before passing the suggestion to /search_v2, or the query will not match.
Responses are CDN-cached, so late responses for an earlier keystroke can arrive
after newer ones. Track which query each response belongs to and ignore stale
ones.
3. Empty state
Before the shopper types anything,GET /empty-state-products gives you
products to show, starter suggestions, and the localized UI strings for your
locale.
localized_strings holds 46 translated interface strings (button labels, facet
labels, sort labels, empty and error messages). Using them keeps a custom UI
translated in every locale you already support, and picks up merchant-specific
overrides configured in Depict.
4. Send tracking events
Analytics in the Depict portal, and the ranking that feeds on it, come from client-side events. A custom UI must send them itself — nothing is inferred server side from a search request.product_impression and product_click for search results,
and add_to_cart and purchase with the search_id of the search that led to
them. Full event list, required fields and the attribution rules are in
Tracking events.
Behaviour worth knowing before you build
- Pagination is page-based. Send the same body with
page: 2for the nextlimitproducts (default 30, up to 250).has_next_pageis true exactly when a page came back full, so a page past the end is empty rather than an error. Keepsearch_idacross the pages of one search; a query, filter or sort change is a new search with a new id andpage: 1. Rules and a worked three-request example are under Pagination. - Filters re-run the search. There is no separate filter endpoint: add a
filtersarray to the same/search_v2request. Debounce rapid filter toggles, and cancel the in-flight request when a new one starts. - Sorting is a request field. Add
sort: { "field": "created", "order": "desc" }to the same/search_v2request to reorder results server-side, with correct ordering across pages. Read the offered options from the response’ssorts:line rather than hardcoding them — an unoffered field/order combination returns422naming what is offered, never a silently different ordering. Omit the field for relevance order. is_fallback: truemeans no good match was found for the query as typed and a relaxed search answered instead. The Depict modal labels these results as close matches rather than presenting them as exact hits.- Retries. The modal retries a failed request twice — three attempts in
total — with a randomised 0.5–2s wait between them. That covers non-
200responses and dropped connections. A mid-streamerrorline is not retried: the modal stops and shows an error, because the server already decided the search failed. Decide deliberately which of the two your UI does. - Response size. Cap how much you read from a stream. The Depict modal
aborts a
/search_v2response after 100 kB.
Next
API reference
Every endpoint, field, stream key and filter.
Filters and suggestions
Building filter controls and rendering suggestions, and the traps in both.
Tracking events
The events to send, and how attribution works.

