Skip to main content
This API will be removed at the end of this year. It is the current-generation storefront search API, and it is the supported and recommended way to build a custom search UI today — the Depict search modal runs on exactly these endpoints. A successor API is coming, and every team building on this one should plan for a migration before year end. Migration documentation will follow; ask your Depict contact to be notified when it is published.
This guide is for developers building a custom search interface against the Depict storefront search API. It covers the four calls a working search UI needs, plus the tracking events that keep analytics and attribution intact. The API is public and unauthenticated for the read endpoints: it is called directly from the shopper’s browser, and every request identifies the store with a merchant id. There is no API key to manage for search.

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

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?.
A default response contains four lines, always in this order:
  • keyword is the product array — the field is not called products.
  • filter_facets lists the filter field names enabled for your account, not values or counts.
  • sorts lists the sort options your account offers, on every response. Read the sort request field’s allowed values from here rather than hardcoding them.
  • keyword_page_info carries pagination: has_next_page says whether to request the next page, n_hits is the total. Page size is the request’s limit (default 30, up to 250). See Pagination.
  • error can 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.
See the API reference for every field, every stream key, filters and pagination.
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.
Suggestions are markdown: **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.
At minimum, send 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: 2 for the next limit products (default 30, up to 250). has_next_page is true exactly when a page came back full, so a page past the end is empty rather than an error. Keep search_id across the pages of one search; a query, filter or sort change is a new search with a new id and page: 1. Rules and a worked three-request example are under Pagination.
  • Filters re-run the search. There is no separate filter endpoint: add a filters array to the same /search_v2 request. 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_v2 request to reorder results server-side, with correct ordering across pages. Read the offered options from the response’s sorts: line rather than hardcoding them — an unoffered field/order combination returns 422 naming what is offered, never a silently different ordering. Omit the field for relevance order.
  • is_fallback: true means 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-200 responses and dropped connections. A mid-stream error line 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_v2 response 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.