Skip to main content
The Catalog API supports public browsing without creating a user session. Use the public SDK accessor for products, categories, search, variants, reviews, recommendations, and store-facing catalog pages.

Product, Variant, and Item

Commerce Engine exposes three related models:
A product without variants is still sellable. Its cart identity is the product ID plus variant_id: null.

Choose the listing operation

Do not build a faceted PLP with listProducts(). searchProducts() returns flattened Item records plus facet distribution and statistics.

Public accessor

Browser SPA:
Framework wrappers:
Public accessors are safe for prerendering and build-time reads. They do not create anonymous users or write session tokens.

Product listing page

Grouped products

Use this model when the card represents the product and variant choice belongs on the PDP.

Flattened Items

Use product_id and variant_id from the Item for Add to Cart. Use product and variant slugs from the response to construct stable URLs when available.

Category routes

Resolve the route slug to a category before issuing a scoped product query.
Do not omit category_id when category resolution is still pending. That silently broadens the request to the entire catalog and produces a convincing but incorrect category page.
Cache categories according to the store’s update frequency, but invalidate them when catalog configuration changes. Retrieve the exact current method signature from:
A typical request:
Search returns Items/SKUs, not grouped Products.

Filter safety

When constructing filter strings from user-visible catalog values:
  • allow only known filter fields and operators
  • escape quotes and backslashes in values
  • do not concatenate arbitrary filter expressions supplied by the browser
  • keep URL state separate from the compiled API filter

URL state

Store search and filter state in the URL so pages can be shared, refreshed, indexed where appropriate, and restored after back/forward navigation. Typical parameters:
Debounce text input, but update structured filter controls immediately unless the UI benefits from an explicit Apply action.

Request supersession

A slower previous request must not replace a newer query’s state. Use the data library’s cancellation signal or a request sequence:
Reset captured base facets when the query changes; facets from an earlier query must not constrain the new one.

Faceted search with stale-response protection

Product detail page

Some SDK versions expose a parameter name such as product_id_or_slug; retrieve the exact operation contract before implementation rather than guessing the key. Prefer the variants included in product detail. Call listProductVariants() only when the response omits them or the feature needs the dedicated operation.

Variant option model

For has_variant: true, option query parameters are the canonical state:
The optional variant parameter can be derived or used to backfill missing option parameters, but it should not replace the customer-visible option state.

Resolve a variant

  1. Read option groups in product.variant_options order.
  2. Normalize values consistently:
    • color option → compare value.name; use value.hexcode for UI
    • single-select option → compare the string value
  3. Match every selected option against variant.associated_options.
  4. Resolve a variant only when all required option keys are selected.
  5. Update displayed price, image, stock, SKU, and description from the resolved variant.
Build requiredOptionKeys from the normalized option groups rendered by the PDP. Keep a separate partial-selection matcher for disabling impossible choices; do not use a partial match as the resolved purchasable variant.

Disable impossible choices

For each displayed option value, check whether at least one variant matches the current partial selection and remains purchasable. Disable values that cannot lead to a valid selection. A variant is purchasable when:

Add to Cart

With Hosted Checkout:
With a custom cart, use the cart skill’s first-add or existing-cart operation.

Attributes versus variant options

Attributes enrich product data and power filtering/specification display. Variant options create distinct sellable variants. A product without variants can still expose color or single-select attributes that a brand wants to render with option-style UI. Keep one normalized display model, but make those values read-only and do not invent a variant ID. Avoid rendering the same key twice when an attribute overlaps a variant option.

Pricing and customer groups

B2B stores can apply group-specific catalog pricing and promotions. Set authoritative customer-group context through the SDK’s supported headers/configuration rather than adding ad hoc parameters to every request. A public page without known customer-group identity should render the store’s public/default pricing. After login or group resolution, invalidate affected catalog queries.

Reviews and recommendations

Read reviews publicly where allowed. Submitting a review is a session-bound write and can require a logged-in user and eligible order context. Use recommendation operations for:
  • similar products
  • upsell products
  • cross-sell products
Run independent detail, review, and recommendation reads in parallel when doing so does not delay the essential PDP content.

SEO and structured data

A server-rendered or prerendered PDP should include:
  • product title and description
  • canonical product URL
  • social metadata and a valid product image when available
  • Product JSON-LD with name, description, URL, SKU, price, currency, and availability
  • AggregateRating only when the rating count and values are valid
  • BreadcrumbList JSON-LD
Safely serialize JSON-LD. Catalog names and descriptions must not be inserted into an inline script using raw JSON.stringify() without escaping <, >, and &. Category pages should have unique titles, descriptions, canonical URLs, and useful not-found behaviour.

Rendering and performance

  • prerender/cache public catalog routes according to the framework and catalog-change frequency
  • use ISR or equivalent revalidation when appropriate
  • parallelize independent reads
  • provide fixed image dimensions or aspect-ratio containers
  • render meaningful skeletons that match the final layout
  • keep session bootstrap out of public rendering
  • paginate full-catalog build discovery rather than assuming one page contains every route
  • warn in build logs when catalog discovery fails; do not silently publish a partial route set

Failure handling

Distinguish:
  • successful response with no matching resource → confirmed not found
  • 404 operation response → confirmed not found where contractually applicable
  • timeout, 5xx, network error → recoverable upstream failure
  • empty search results → valid empty state
Do not turn a transient catalog outage into a permanent 404 or silently show the entire catalog for an unresolved filter.

Production checklist

Catalog skills and production examples

Use the Commerce Engine catalog skill for decision logic, the LLM-first reference for exact contracts, and the starters for integrated PLP/PDP patterns.