Skip to main content
POST
cURL

Overview

The top recommendations endpoint lets headless storefronts fetch products without a seed anchor — unlike /recommendations and /recommendations/automatic, no product_ids are required. It is the right endpoint for:
  • Catalog / collection landing pages (“Bestsellers”, “New arrivals”, “Trending now”)
  • Search results constrained by a strategy (e.g. trending products matching “wireless charger”)
  • Merchandising widgets that need filtered top-N lists with facet sidebars
The filter contract is identical to /recommendations/automatic — same filter shape, same Joi schema — extended with four additional dimensions (excluded_tags, collections, product_types, price). Those extensions are also accepted by the automatic endpoint going forward.
Authentication. Pass Authorization: Bearer <shop storefront token> and x-shop: <myshopify domain> on every call. See Get Started → Headless Authentication for token provisioning.

Ranking strategies

Filter dimensions

filter is fully optional. Each sub-field is independently optional and combined as an AND:
  • tags / excluded_tags — include / exclude by product tag.
  • vendors — vendor names (exact match).
  • product_types — product type values.
  • collections — collection IDs the product must belong to.
  • price.min / price.max — price range in shop currency.
  • variants.is_in_stock, variants.available_for_sale — variant-level availability (matches any variant).
  • variants.options[] — variant option matches (e.g. Color: Black).
  • variants.sku[] — variant SKU match.
  • metafields[] — match by {namespace, key, value}; requires a filterKey to exist on the indexed product.
Array or comma-separated string. The list-style fields tags, excluded_tags, vendors, product_types, and collections accept either a JSON array of strings or a single comma-separated string. Useful for clients whose query serializers can’t construct arrays from variables. Both forms below are equivalent:
Whitespace around commas is trimmed.

Text query

When query is provided, a multi_match clause is added across title^3, description, tags, vendor, productType with operator: AND, lenient: true. The strategy sort still wins — products matching the text query are ranked by sales (or recency / trending score), not by BM25 relevance. For relevance-first text search, use the AI Search endpoint instead.

Facets

Pass facets: ["vendor", "product_type", "tag", "price"] (any subset) to receive aggregations alongside the products. Each facet returns top values with counts. The price facet returns fixed buckets (0-50, 50-100, 100-250, 250+). Facet counts are computed using a post-filter model — each facet’s counts ignore that dimension’s filter so a sidebar UI can show “all available vendors” even when the user has selected one. Other filters still apply.

Pagination

Cursor-based, matching the rest of the v3 headless surface. The first request can pass pagination.limit (1–100, default 24). Subsequent pages pass the cursor returned in the previous response.
When paginating with a cursor, the filter, query, and strategy must stay identical to the request that produced the cursor — changing them invalidates the sort context and returns incoherent ordering.
The response includes pagination.total and pagination.totalRelation ("eq" or "gte"). Elasticsearch caps totals at 10,000 by default — when the relation is "gte", the real total is ≥ that value.

Examples

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

x-shop
string
required

Shopify store URL

Example:

"shop.myshopify.com"

Body

application/json

Request body

strategy
enum<string>
required

Ranking strategy to apply

Available options:
BESTSELLERS,
NEW_ARRIVALS,
TRENDING
view
enum<string>
required

Response shape for each product entry.

Available options:
product_details,
product_ids
strategy_options
object

Strategy-specific tuning. Currently only BESTSELLERS uses this.

query
string

Optional free-text query. Applied as a multi_match across title, description, tags, vendor, and product_type. The strategy sort still wins; products matching the text query rank by sales/recency/trending score, not BM25.

filter
object

Same filter shape as /recommendations/automatic, extended with excluded_tags, collections, product_types, and price.

facets
enum<string>[]

Facet dimensions to return alongside the products. Facets are computed only when this array is non-empty.

Available options:
vendor,
product_type,
tag,
price
pagination
object

Response

Top recommendations

ok
enum<boolean>
Available options:
true
serve_id
string

Unique identifier for this serve.

strategy
string

Echo of the ranking strategy that produced the results.

products
object[]
pagination
object
facets
object

Present only when the request specified facets. Each requested dimension is a top-level key.