POST /products/more-like-this returns products similar to a source product. The API resolves the source by URL or UUID within your catalog grants, builds the similarity query from indexed product enrichment, excludes the source product from results, and returns a standard product list page. The source can also be an image — see Image sources.
Use this endpoint for related product rails, substitutions, recommendation modules, and agent workflows that start from a known product. To see the strategies side by side with live results, open the interactive demo or the strategy recipes guide. For the image input, open the image input demo.
Request
Body parameters
object
required
Source identifier. Provide exactly one of
source.url, source.uuid, or source.image.string
Canonical product URL to use as the source product.
string
Indexed product UUID to use as the source product.
object
Source image to derive the similarity query from. Provide exactly one of
source.image.b64 or source.image.url. Slower than product sources — see Image sources for behavior, guards, and latency.string
Base64-encoded image bytes. Decoded size is capped at 8 MB (
413 beyond it). Downscale client-side before sending (~1024px JPEG) — the pipeline downscales internally, so larger uploads only add transfer time.string
HTTPS image URL fetched server-side — any public host, so retailer product-image URLs can be passed directly. Redirects are not followed, the fetch validates that both DNS resolution and the connected peer are public addresses, and the same 8 MB cap applies while streaming.
string[]
Optional catalog allowlist (1–100 keys) restricting results to these catalogs. Retrieval-only: the source product may live outside the allowlist and still resolves. Keys are not validated — an unknown or inaccessible key simply matches nothing. When omitted, search runs across all active crawled catalogs. With
debug: true, the applied allowlist is echoed as effectiveQuery.catalogs. Replaces the former single-valued catalog field, which is now rejected with a 422.Facet[]
Additional include facets appended after Octogen’s server-generated audience facets.
Facet[]
Facets to exclude from the similar-products search.
"lower" | "any" | "higher"
default:"any"
Relative price preference compared with the source product’s
currentPrice. Use lower for less expensive alternatives, higher for premium alternatives, or any for no relative price filter. Image sources require any (400 otherwise) — there is no source product to be price-relative to.EmbeddingColumn[]
Embedding columns used to retrieve candidate products. Overrides the server-selected default:
["style_embedding", "tags_embedding"] when the source product has styles or tags, otherwise ["embedding"]. Accepted values: embedding, style_embedding, tags_embedding, attributes_embedding. Must contain at least one value.EmbeddingColumn[]
Embedding columns used to re-score and rank the retrieved candidates. When omitted, ranking uses the base
embedding. Accepts the same values as retrieval_embedding_columns; must contain at least one value. Combine the two to retrieve one way and rank another — see Strategy recipes.string
Opaque pagination cursor from a previous response’s
nextCursor field. Pass it unmodified with the same request fields to retrieve the next page. Supported for image sources: the cursor embeds the relaxation round that produced the page, so continuations re-run the exact converged query. Deterministic within the 24h generation-cache window.integer
default:"12"
Number of products to return per page. Accepted range: 1–100.
boolean
default:"false"
When
true, the response includes a curated camelCase effectiveQuery object showing the server-derived retrieval query.Example
Embedding columns
Every indexed product carries several embeddings. Retrieval columns decide which products come back as candidates; ranking columns decide how those candidates are ordered.Strategy recipes
Send
debug: true with any combination and the response’s effectiveQuery shows the exact query the server executed. For worked examples of each strategy with live results, see the strategy recipes guide.
Image sources
Send a photo — a product shot, a look to match — and the API generates the similarity query from the image: a multimodal parse reads it, the query processors derive facets (category, gender, color, attributes), and the search runs with zero-result facet relaxation. See it live in the image input demo.- Latency: the first sight of an image runs generation — expect p50 ≤ 8s, ~11s when relaxation rounds run. Repeat images are served from a generation cache (24h) in ~0.25s, and the response’s
resolutionfield says which happened:image_query_generation(pipeline ran) orcached_image_query(cached). - Facet relaxation: every image-derived facet is an inference (including a
brand_nameread off a visible logo), so zero-result searches automatically retry with the least-trusted facet tiers dropped. Withdebug: truethe response reportsrelaxationRoundsand the released facets. Facets you pass ininclude_facetsare never dropped. - Response shape: image responses return
sourceImage.hashandresolutioninstead of the resolved-productsourcestanza.nextCursoris a normal opaque cursor — pass it back with the same request body to page through the result set. include_facets/exclude_facets/ embedding-column overrides work exactly as for product sources.
Response
object
Public identity of the source product that powered the similarity query. Present for
url/uuid sources; image sources return sourceImage instead.object
Present for image sources only:
{ "hash": string } — the content hash of the submitted image bytes.string
Present for image sources only. How the source was resolved:
"image_query_generation" (the generation pipeline ran) or "cached_image_query" (served from the 24h generation cache — a repeat of an image seen before).MerchantProductListItem[]
required
Similar products for the current page. See the Product model for the full field reference.
string | null
Cursor for the next page of similar products.
null means no more results are available.object | null
Present only when
debug is true. Contains the public server-derived query fields: text, retrievalEmbeddingColumns, rankingEmbeddingColumns, facets, exclusionFacets, priceMin, priceMax, limit, and — when a catalogs allowlist was sent — catalogs (the normalized allowlist as applied). For image sources it additionally carries generationStages (per-stage generation timings), degradedToTextFallback, and — when relaxation ran — relaxationRounds and relaxationDroppedFacets.