This page covers the read catalog of the Products domain: the main listing with filters, free-text search, count, SKU existence check, resolving a parent product from a variant's SKU, the auxiliary brand/kind catalogs, and advanced search via POST.
No single envelope in Products
Unlike other domains in the API, Products does not respond with a consistent envelope shape across all its endpoints. Each endpoint on this page documents its actual response shape — don't assume {data, meta} in any of them except the explicit case flagged below.
Permission required on every endpoint on this page:products:read.
The only endpoint in the domain with a {data, meta} envelope
Without the availableAt parameter, GET /products responds with a flat array of products (legacy behavior, shown above). When you send availableAt=<locationId>, the response shape changes to an envelope with pagination:
This is the only endpoint in the entire Products domain that uses this envelope. No other one — not the rest of the catalog, not collections, not categories, not the bulk routes — replicates it. Don't build your client assuming this contract is general.
This endpoint delegates directly to the library's ProductsService.search. The audit confirmed the input parameters, but did not verify line by line the exact output envelope (flat array vs. wrapping object). The products it returns have the real Product shape (see data model); confirm the exact container shape against a real response before depending on it.
Accepts the same set of filters as the main listing (q, status, category, brands, minPrice, maxPrice, tags, channelId, etc.); it does not apply page/limit because it doesn't paginate results. When you send a search term (term), the response also includes the search strategy used:
{ "count": 27, "searchStrategy": "text" }
Tip
The exact value of searchStrategy was not exhaustively enumerated in the audit — treat it as informational, not as a closed enum for your business logic.
400 error without a code, and response shape not verified
If you omit locationId, this endpoint responds 400 with {"error": "Missing required query parameter: locationId"} — without a code field, unlike the rest of the domain's convention. The exact shape of the successful response (the result of getProductsByLocation) was also not verified line by line in the audit; confirm it against a real response.
Minimized view of products with inventory at a location (reduced payload, meant for large lists)
The confirmed response wraps in {products, total} — with a minimized payload (~500 bytes per product, vs ~3 KB for the full product). The audit did not enumerate the complete and definitive list of fields each item carries; the example above is illustrative with fields that do exist in the real model, not an exact verified copy of the code.
Common errors for /products/inventory-view:400 bad-request/missing-param, 400 bad-request/invalid-param, 500 inventory-view/error.
Several Products endpoints (this listing and GET /products/{id}) accept extend as a comma-separated list of additional fields to include in the response, from a closed set:
variants, options, description, bindings, metadata, inventory, dimensions, seo, all
all includes all available extended fields. The details of what extend=inventory/extend=all specifically do (attach inventory per variant and location) are documented in Retrieve a product, where the parameter has its most complete effect.