Product pages

Fetch one product as its page shows it, with its offer, details and variants, by its id or its URL.

GET /v1/product answers one product as its page shows it: text, photos, categories, its offer, its details with labels and units, and its variants. The offer and badges are those its tile shows, so a page and a tile never disagree:

Terminal
curl -s 'http://127.0.0.1:7800/v1/product?id=SOFA-ASKA-2' \
  | jq -c '.product | .title, .badges, .signals, .offer, (.details[] | select(.attribute == "width"))'
200 · 5.4 ms · release b25a6aaa
"Aska 2-Sitzer-Sofa aus Samt"
["Bestseller"]
{"rating":4.3,"rating_count":118}
{"price":749.0,"sale_price":649.0,"currency":"EUR","availability":"in_stock","stock":16,"delivery_days":{"min":3,"max":5}}
{"attribute":"width","label":"Breite","values":[164],"unit":"cm"}

The offer sums up the variants. It takes the lowest price a shopper pays among those with the best availability, here the sage variant's sale price, and adds up the stock of both.

"Bestseller" is a badge the release gives it in its overlays, and 4.3 stars from 118 ratings are the catalog's signals. Each detail carries its label in the request's locale and its unit: Breite (width), 164 cm.

Reference: GET /v1/product · Product · ProductOffer

Variants

Each variant carries what sets it apart and its own offer:

Terminal
curl -s 'http://127.0.0.1:7800/v1/product?id=SOFA-ASKA-2' \
  | jq -c '.product.variants[] | {id, details: [.details[] | {label, values, swatch}],
      offer: (.offer | {price, sale_price, stock} | del(..|nulls))}'
200 · 6.2 ms · release b25a6aaa
{"id":"SOFA-ASKA-2-GRAU","details":[{"label":"Farbe","values":["Grau"],"swatch":"#9B9B9B"}],"offer":{"price":749.0,"stock":12}}
{"id":"SOFA-ASKA-2-SALBEI","details":[{"label":"Farbe","values":["Salbei"],"swatch":"#9CAF92"}],"offer":{"price":749.0,"sale_price":649.0,"stock":4}}

The Aska comes in grey (Grau) and sage (Salbei), and only sage is on sale. A color of one value carries the swatch its facet draws, its own or its color group's, so the page draws the same swatches as the filter. What every variant sold in the channel shares stands in the product's details, such as the width.

Reference: ProductVariant · ProductDetail

Name it by its URL

A storefront that knows the page's path asks by url, in the locale the path belongs to:

Terminal
curl -s 'http://127.0.0.1:7800/v1/product?url=/en/p/aska-two-seater-sofa&locale=en' \
  | jq -c '.product | {id, title, url, alternates, badges}'
200 · 5.1 ms · release b25a6aaa
{"id":"SOFA-ASKA-2","title":"Aska two-seater velvet sofa","url":"/en/p/aska-two-seater-sofa","alternates":{"de":"/p/aska-2-sitzer-sofa"},"badges":["Best seller"]}

The English page answers in English, badge included. alternates holds the product's URL in each other locale of the channel, for a language switch and hreflang. A URL matches only as the catalog writes it: another case or a trailing slash is not found.

Reference: url · alternates

When the channel sells no such product

The rug TEPPICH-SILO never went live: the index run left it out for its broken price. So the channel sells no product by that id:

Terminal
curl -s 'http://127.0.0.1:7800/v1/product?id=TEPPICH-SILO' | jq -c '{status, detail}'
404 · 3.8 ms
{"status":404,"detail":"The channel de sells no product with the id TEPPICH-SILO."}

Answer the shopper with your own 404 page; the client's product call returns null here (The client). An engine that does not answer is a 503, never a 404, so a crawler is never told a product is gone while Meilisearch is down.

Reference: 404

A product's URL through resolve

A storefront that serves every page by its URL asks resolve, which answers the product with the status, canonical and robots its page needs, in one call:

Terminal
curl -s -G http://127.0.0.1:7800/v1/resolve --data-urlencode 'url=/p/aska-2-sitzer-sofa' \
  | jq -c '{type, status, canonical, robots, product: .product.id}'
200 · 5.9 ms · release b25a6aaa
{"type":"product","status":200,"canonical":"/p/aska-2-sitzer-sofa","robots":"index,follow","product":"SOFA-ASKA-2"}

product is what GET /v1/product answers for it. URLs and redirects shows the route that serves it.

Next

On this page