Product Catalog

Storefront API Reference

Every operation of the storefront API at https://catalog.usethrottle.dev, rendered from its OpenAPI document. Every route except the document itself takes a publishable key in X-Catalog-Key.

Sending the key

A GET may send the key as ?key= instead of the header, so a browser read needs no preflight. A browser, app or legacy key is accepted this way, never together with the header (that is a 400 INVALID_REQUEST): a server key in a URL answers 403 KEY_NOT_ALLOWED_IN_URL, and a POST always uses X-Catalog-Key. The customer token is never accepted in a URL; it travels in X-Customer-Token. The SDK's suggest never sends it, so suggestions from the SDK are list prices. See Keys and channels.

Meta

The store configuration and this document.

GET /v1/storefront/openapi.json No key

This OpenAPI document.

No key
Implementation details

Operation getOpenApi.

Headers

FieldTypeRequiredDescription
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Responses

200 OK. Headers: ETag.

Response fields

FieldTypeRequiredDescription
openapistringYes
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
GET /v1/storefront/config Publishable key

The store: name, currencies, locales, sorts, reviews and the catalog generation.

X-Catalog-Key · no customer token
Implementation details

Operation getConfig.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
storeNamestring | nullYes
currenciesstring[]Yes
defaultCurrencystring | nullYes
defaultLocalestring | nullYes
localesstring[]Yes
sortsstring[]Yes
reviewsobjectYes
reviews.enabledbooleanYes
reviews.onListsbooleanYes
relatedModestringYes
Values: automatic_with_picks, picks_only, automatic_only
lineResolverobjectYes
lineResolver.extensionIdstringYes
generationintegerYes
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.config()

The SDK sends the key, the customer token and the idempotency key for you.

Browse

Product lists, filters and products.

GET /v1/storefront/products Publishable key

A page of products with filters, facets and sorting.

X-Catalog-Key · customer token optional
Implementation details

Operation listProducts.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
X-Customer-TokenstringNoThe signed-in shopper's Throttle access token: customer prices and identity. Without it the answer is anonymous. Length 1–4096
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Query parameters

FieldTypeRequiredDescription
qstringNoFull-text search. Length at most 200
categorystringNoA category handle; products of its children are included.
collectionstringNoA collection handle.
tagstring[]NoA tag; repeat the parameter for several.
featuredbooleanNoOnly featured (true) or only other (false) products.
handlesstring[]NoProduct handles; repeat the parameter (commas are literal).
skusstring[]NoSKUs; repeat the parameter (commas are literal).
yearintegerNoVehicle year; the vehicle filter applies when make and model are set.
makestringNoVehicle make (with model).
modelstringNoVehicle model (with make).
submodelstringNoVehicle submodel (with make and model).
enginestringNoVehicle engine (with make and model).
sortstringNoThe order; absent, the store default. best_rated only while ratings show on lists.
Values: relevance, featured, manual, title_asc, title_desc, price_asc, price_desc, newest, updated, best_rated
limitintegerNoProducts per page. Value 1–100
pageintegerNoA page number (not with cursor). Value at least 1
cursorstringNopage.nextCursor of the previous page (not with page). Length at most 1024
facetsstring[]Notrue for every filter, or filter keys (comma-separated or repeated).
fieldsstring[]Nolite (default), full, or a comma list of top-level product keys.
includestring[]NoOpt-in parts, comma-separated or repeated: fitment, oemNumbers, supersessions, jsonLd, descriptionHtml.
currencystringNoAn ISO 4217 currency the store has enabled; prices are answered in it.
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35
filter.{key}string[]NoA selected value of the filter key (filter.color=Red); repeat for several values. A range filter takes one min..max value. The parameter name is a pattern: filter. followed by a filter key.

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
productsStorefrontListProduct[]Yes
pageobjectYes
page.numberintegerYesValue at least 1
page.limitintegerYesValue 1–100
page.totalinteger | nullYes
page.pageCountinteger | nullYes
page.nextCursorstring | nullYes
page.cappedtrueNo
filtersobject[]No
filters[].keystringYesLength at least 1
filters[].labelstringYes
filters[].displaystringYes
Values: checkbox, swatch, range, boolean, dropdown
filters[].valuesobject[]YesItems at most 50
filters[].rangeobjectNo
filters[].morebooleanYes
appliedobjectYes
applied.qstringNo
applied.categorystringNo
applied.collectionstringNo
applied.tagsstring[]No
applied.featuredbooleanNo
applied.filtersobjectYes
applied.ignoredstring[]No
sortstringYes
Values: relevance, featured, manual, title_asc, title_desc, price_asc, price_desc, newest, updated, best_rated
currencystring | nullYes
localestring | nullYes
priceContextstringNo
Values: anonymous, customer, email_unverified, anonymous_fallback
indexingtrueNo
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.products.list()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/filters/{key}/values Publishable key

Every value of one filter for the current selection (the list's parameters).

X-Catalog-Key · no customer token
Implementation details

Operation listFilterValues.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Path parameters

FieldTypeRequiredDescription
keystringYesThe filter key. Length at least 1

Query parameters

FieldTypeRequiredDescription
qstringNoFull-text search. Length at most 200
categorystringNoA category handle; products of its children are included.
collectionstringNoA collection handle.
tagstring[]NoA tag; repeat the parameter for several.
featuredbooleanNoOnly featured (true) or only other (false) products.
handlesstring[]NoProduct handles; repeat the parameter (commas are literal).
skusstring[]NoSKUs; repeat the parameter (commas are literal).
yearintegerNoVehicle year; the vehicle filter applies when make and model are set.
makestringNoVehicle make (with model).
modelstringNoVehicle model (with make).
submodelstringNoVehicle submodel (with make and model).
enginestringNoVehicle engine (with make and model).
sortstringNoThe order; absent, the store default. best_rated only while ratings show on lists.
Values: relevance, featured, manual, title_asc, title_desc, price_asc, price_desc, newest, updated, best_rated
limitintegerNoProducts per page. Value 1–100
pageintegerNoA page number (not with cursor). Value at least 1
cursorstringNopage.nextCursor of the previous page (not with page). Length at most 1024
facetsstring[]Notrue for every filter, or filter keys (comma-separated or repeated).
fieldsstring[]Nolite (default), full, or a comma list of top-level product keys.
includestring[]NoOpt-in parts, comma-separated or repeated: fitment, oemNumbers, supersessions, jsonLd, descriptionHtml.
currencystringNoAn ISO 4217 currency the store has enabled; prices are answered in it.
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35
filter.{key}string[]NoA selected value of the filter key (filter.color=Red); repeat for several values. A range filter takes one min..max value. The parameter name is a pattern: filter. followed by a filter key.

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
keystringYesLength at least 1
labelstringYes
displaystringYes
Values: checkbox, swatch, range, boolean, dropdown
valuesobject[]YesItems at most 1000
values[].valuestringYes
values[].labelstringYes
values[].countintegerYes
values[].selectedbooleanYes
values[].swatchobject | objectNo
rangeobjectNo
range.minnumberYes
range.maxnumberYes
range.selectedMinnumberNo
range.selectedMaxnumberNo
morebooleanYes
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.filters.values()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/products/{handle} Publishable key

One product. With fields, include, currency or locale the full product; without, the legacy answer. An old handle answers { redirectTo }.

X-Catalog-Key · customer token optional
Implementation details

Operation getProduct.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
X-Customer-TokenstringNoThe signed-in shopper's Throttle access token: customer prices and identity. Without it the answer is anonymous. Length 1–4096
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Path parameters

FieldTypeRequiredDescription
handlestringYesThe product handle. Length at least 1

Query parameters

FieldTypeRequiredDescription
fieldsstring[]NoAny value switches to the full product (the page is always full).
includestring[]NoOpt-in parts, comma-separated or repeated: fitment, oemNumbers, supersessions, jsonLd, descriptionHtml.
currencystringNoAn ISO 4217 currency the store has enabled; prices are answered in it.
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35

Responses

200 OK. One of 2 answer shapes. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
productobjectNo
product.handlestringNoLength at least 1
product.titlestring | nullNo
product.descriptionstring | nullNo
product.brandstring | nullNo
product.productTypestring | nullNo
product.googleCategorystring | nullNo
product.linkstring | nullNo
product.imagesobject[]No
product.priceRangeobject | nullNo
product.availabilitystring | nullNo
product.variantsobject[]No
product.shortDescriptionstring | nullNo
product.seoTitlestring | nullNo
product.seoDescriptionstring | nullNo
product.tagsstring[]No
product.categoriesobject[]No
product.featuredbooleanNo
product.draftbooleanNo
product.descriptionHtmlstring | nullNo
product.seoobjectNo
product.jsonLdobjectNo
product.optionsobject[]No
product.breadcrumbsobject[]No
product.lowStockbooleanNo
product.purchasablebooleanNo
product.availableInCurrencybooleanNo
product.ratingobjectNo
localestring | nullNo
priceContextstringNo
Values: anonymous, customer, email_unverified, anonymous_fallback
redirectTostringNoLength 1–255
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.products.get()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/products/{handle}/related Publishable key

Products related to one product (the store's picks, then the related mode).

X-Catalog-Key · customer token optional
Implementation details

Operation listRelatedProducts.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
X-Customer-TokenstringNoThe signed-in shopper's Throttle access token: customer prices and identity. Without it the answer is anonymous. Length 1–4096
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Path parameters

FieldTypeRequiredDescription
handlestringYesThe product handle. Length at least 1

Query parameters

FieldTypeRequiredDescription
limitintegerNoProducts to answer. Value 1–24
fieldsstring[]Nolite (default), full, or a comma list of top-level product keys.
currencystringNoAn ISO 4217 currency the store has enabled; prices are answered in it.
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
productsStorefrontListProduct[]YesItems at most 24
localestring | nullNo
priceContextstringNo
Values: anonymous, customer, email_unverified, anonymous_fallback
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.products.related()

The SDK sends the key, the customer token and the idempotency key for you.

Taxonomy

Categories, tags and collections.

GET /v1/storefront/categories Publishable key

The category tree.

X-Catalog-Key · no customer token
Implementation details

Operation getCategoryTree.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Query parameters

FieldTypeRequiredDescription
depthintegerNoLevels of the tree to answer. Value 1–10
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
categoriesStorefrontCategoryNode[]Yes
localestring | nullNo
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.categories.tree()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/categories/{handle} Publishable key

One category with its breadcrumb and children.

X-Catalog-Key · no customer token
Implementation details

Operation getCategory.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Path parameters

FieldTypeRequiredDescription
handlestringYesThe category handle. Length at least 1

Query parameters

FieldTypeRequiredDescription
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
categoryobjectYes
category.idstringYesLength at least 1
category.handlestringYesLength at least 1
category.namestringYesLength at least 1
category.descriptionstring | nullYes
category.seoTitlestring | nullYes
category.productCountintegerYes
breadcrumbsobject[]Yes
breadcrumbs[].handlestringYesLength at least 1
breadcrumbs[].namestringYesLength at least 1
childrenStorefrontCategoryNode[]Yes
localestring | nullNo
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.categories.get()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/tags Publishable key

Product tags with counts.

X-Catalog-Key · no customer token
Implementation details

Operation listTags.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Query parameters

FieldTypeRequiredDescription
qstringNoTags that start with this text. Length at most 100
limitintegerNoTags to answer. Value 1–200

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
tagsobject[]Yes
tags[].tagstringYesLength at least 1
tags[].productCountintegerYes
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.tags.list()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/collections Publishable key

A page of published collections.

X-Catalog-Key · no customer token
Implementation details

Operation listCollections.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Query parameters

FieldTypeRequiredDescription
limitintegerNoCollections per page. Value 1–100
cursorstringNonextCursor of the previous page. Length at most 1024
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
collectionsobject[]Yes
collections[].handlestringYesLength at least 1
collections[].titlestringYes
collections[].kindstringYes
Values: manual, rule
collections[].imageobject | nullYes
collections[].productCountintegerYes
nextCursorstring | nullYes
localestring | nullNo
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.collections.list()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/collections/{handle} Publishable key

One collection. An old handle answers { redirectTo }.

X-Catalog-Key · no customer token
Implementation details

Operation getCollection.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Path parameters

FieldTypeRequiredDescription
handlestringYesThe collection handle. Length at least 1

Query parameters

FieldTypeRequiredDescription
localestringNoThe answer language (BCP 47 style, e.g. fr or fr-CA); the answer names the locale it used. Length at most 35

Responses

200 OK. One of 2 answer shapes. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
collectionobjectNo
collection.handlestringNoLength at least 1
collection.titlestringNo
collection.descriptionstring | nullNo
collection.descriptionHtmlstring | nullNo
collection.imageobject | nullNo
collection.seoobjectNo
collection.kindstringNo
Values: manual, rule
collection.defaultSortstringNo
Values: featured, manual, title_asc, title_desc, price_asc, price_desc, newest, updated
localestring | nullNo
redirectTostringNoLength 1–255
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.collections.get()

The SDK sends the key, the customer token and the idempotency key for you.

Carts

Cart checks and hosted carts in Throttle.

POST /v1/storefront/carts/check Publishable key

Prices and checks cart lines without creating a cart.

X-Catalog-Key · customer token optional
Implementation details

Operation checkCart. The JSON request body is required.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
X-Customer-TokenstringNoThe signed-in shopper's Throttle access token: customer prices and identity. Without it the answer is anonymous. Length 1–4096

Request body

FieldTypeRequiredDescription
itemsobject[]YesItems 1–50
items[].skustringYesLength 1–255
items[].quantityintegerYesValue 1–10000
currencystringNo

Responses

200 OK.

Response fields

FieldTypeRequiredDescription
priceContextstringNo
Values: anonymous, customer, email_unverified, anonymous_fallback
itemsobject[]Yes
items[].skustringYes
items[].okbooleanYes
items[].codestringNo
Values: NOT_FOUND, NOT_PURCHASABLE, OUT_OF_STOCK, QUANTITY_UNAVAILABLE, BELOW_MIN, ABOVE_MAX, NO_PRICE_IN_CURRENCY, PRICE_SOURCE_MISMATCH
items[].unitPriceMinorinteger | nullYes
items[].currencystring | nullYes
items[].maxQuantityintegerNo
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
413 Request body too large.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.carts.check()

The SDK sends the key, the customer token and the idempotency key for you.

POST /v1/storefront/carts Publishable key

Creates a Throttle cart from catalog lines and opens its hosted cart session.

X-Catalog-Key · customer token optional
Implementation details

Operation createCart. The JSON request body is required.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
X-Customer-TokenstringNoThe signed-in shopper's Throttle access token: customer prices and identity. Without it the answer is anonymous. Length 1–4096
Idempotency-KeystringNoA retry with the same key answers the first request again instead of repeating it. Length 1–200

Request body

FieldTypeRequiredDescription
itemsobject[]YesItems 1–50
items[].skustringYesLength 1–255
items[].quantityintegerYesValue 1–10000
currencystringNo
localestringNoLength at most 35
returnUrlstringNoWhere the hosted checkout sends the shopper after paying. An absolute https URL on one of the store's allowed return websites (Checkout settings). Length at most 2048
cancelUrlstringNoWhere the hosted cart's cancel link goes. An absolute https URL on one of the store's allowed return websites (Checkout settings). Length at most 2048
storefrontUrlstringNoThe hosted cart's "Continue shopping" link. An absolute https URL on one of the store's allowed return websites (Checkout settings). Length at most 2048

Responses

201 Created.

Response fields

FieldTypeRequiredDescription
priceContextstringNo
Values: anonymous, customer, email_unverified, anonymous_fallback
sessionIdstringYes
cartUrlstringYes
expiresAtstringYes
cartobjectYes
cart.linesobject[]Yes
cart.currencystringYes
cart.subtotalMinorintegerYes
returnUrlAppliedbooleanNo
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
409 Conflict with the store setup or an earlier request.
413 Request body too large.
422 The request is well formed but cannot be done (items names refused lines).
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
502 Throttle refused the request (throttleCode).
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.carts.create()

The SDK sends the key, the customer token and the idempotency key for you.

Reviews

Product reviews.

GET /v1/storefront/products/{handle}/reviews Publishable key

A page of a product's published reviews with its rating summary.

X-Catalog-Key · no customer token
Implementation details

Operation listReviews.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Path parameters

FieldTypeRequiredDescription
handlestringYesThe product handle. Length at least 1

Query parameters

FieldTypeRequiredDescription
sortstringNoThe order.
Values: newest, highest, lowest
ratingintegerNoOnly reviews with this rating. Value 1–5
limitintegerNoReviews per page. Value 1–50
cursorstringNonextCursor of the previous page. Length at most 1024
localestringNoChecked and ignored: reviews are answered as written. Length at most 35

Responses

200 OK. One of 2 answer shapes. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
summaryobjectNo
summary.averagenumber | nullNo
summary.countintegerNo
summary.histogramobjectNo
reviewsobject[]No
reviews[].idstringNoLength at least 1
reviews[].ratingintegerNoValue 1–5
reviews[].titlestring | nullNo
reviews[].bodystringNo
reviews[].displayNamestringNo
reviews[].verifiedbooleanNo
reviews[].importedbooleanNo
reviews[].createdAtstringNo
reviews[].replyobject | nullNo
nextCursorstring | nullNo
redirectTostringNoLength at least 1
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.reviews.list()

The SDK sends the key, the customer token and the idempotency key for you.

POST /v1/storefront/products/{handle}/reviews Customer token

Submits a review as the signed-in shopper.

X-Catalog-Key · customer token required
Implementation details

Operation submitReview. The JSON request body is required.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
X-Customer-TokenstringYesThe signed-in shopper's Throttle access token. Length 1–4096
Idempotency-KeystringNoA retry with the same key answers the first request again instead of repeating it. Length 1–200

Path parameters

FieldTypeRequiredDescription
handlestringYesThe product handle. Length at least 1

Request body

FieldTypeRequiredDescription
ratingintegerYesValue 1–5
titlestring | nullNo
bodystringYes
displayNamestringYesLength 1–120

Responses

201 Created.

Response fields

FieldTypeRequiredDescription
reviewobjectYes
review.idstringYesLength at least 1
review.statusstringYes
Values: pending, approved
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
409 Conflict with the store setup or an earlier request.
413 Request body too large.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.reviews.submit()

The SDK sends the key, the customer token and the idempotency key for you.

GET /v1/storefront/products/{handle}/reviews/eligibility Publishable key

Whether the signed-in shopper may review the product, and why not.

X-Catalog-Key · customer token optional
Implementation details

Operation getReviewEligibility.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
X-Customer-TokenstringNoThe signed-in shopper's Throttle access token: customer prices and identity. Without it the answer is anonymous. Length 1–4096

Path parameters

FieldTypeRequiredDescription
handlestringYesThe product handle. Length at least 1

Responses

200 OK.

Response fields

FieldTypeRequiredDescription
canReviewbooleanYes
reasonstringNo
Values: reviews_disabled, not_signed_in, email_not_verified, already_reviewed, not_verified_buyer
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
404 Not found.
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

SDK coverage

@usethrottle/catalog · Browsers and Node.js 20+

  • catalog.reviews.eligibility()

The SDK sends the key, the customer token and the idempotency key for you.

Legacy

Routes kept for stores built before the storefront API.

GET /v1/storefront/search Publishable key

Legacy search (before the Part 2 list). Use listProducts.

X-Catalog-Key · no customer token
Implementation details

Operation legacySearch.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Query parameters

FieldTypeRequiredDescription
qstringNoFull-text search. Length at most 200
categorystringNoA Google product category.
collectionstringNoA category handle.
featuredbooleanNoOnly featured or only other products.
sortstringNoThe order.
Values: relevance, title, price_asc, price_desc, updated
cursorstringNonextCursor of the previous page.
brandstring[]NoBrands, comma-separated or repeated.
productTypestring[]NoProduct types, comma-separated or repeated.
availabilitystring[]NoAvailabilities, comma-separated or repeated.
facetsstring[]Nobrand and/or productType, comma-separated or repeated.
priceMinintegerNoLowest price in minor units.
priceMaxintegerNoHighest price in minor units.
limitintegerNoProducts per page. Value 1–100
yearintegerNoVehicle year.
makestringNoVehicle make.
modelstringNoVehicle model.
submodelstringNoVehicle submodel.
enginestringNoVehicle engine.

Responses

200 OK. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
productsobject[]Yes
products[].handlestringYesLength at least 1
products[].titlestring | nullYes
products[].descriptionstring | nullYes
products[].brandstring | nullYes
products[].productTypestring | nullYes
products[].googleCategorystring | nullYes
products[].linkstring | nullYes
products[].imagesobject[]Yes
products[].priceRangeobject | nullYes
products[].availabilitystring | nullYes
products[].variantsobject[]Yes
products[].shortDescriptionstring | nullNo
products[].seoTitlestring | nullNo
products[].seoDescriptionstring | nullNo
products[].tagsstring[]No
products[].categoriesobject[]No
products[].featuredbooleanNo
products[].draftbooleanNo
products[].descriptionHtmlstring | nullNo
products[].seoobjectNo
products[].jsonLdobjectNo
nextCursorstring | nullYes
facetsobjectYes
facets.brandobject[]No
facets.productTypeobject[]No
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.
GET /v1/storefront/vehicles Publishable key

The vehicle picker: years, then makes for a year, models for a make, then submodels and engines.

X-Catalog-Key · no customer token
Implementation details

Operation listVehicles.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
If-None-MatchstringNoAn ETag of an earlier answer: 304 when it still matches.

Query parameters

FieldTypeRequiredDescription
yearintegerNoVehicle year.
makestringNoVehicle make.
modelstringNoVehicle model.

Responses

200 OK. One of 4 answer shapes. Headers: ETag, Server-Timing.

Response fields

FieldTypeRequiredDescription
yearsinteger[]No
makesstring[]No
modelsstring[]No
submodelsstring[]No
enginesstring[]No
304 Not modified: the answer still matches If-None-Match. Headers: ETag.
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.
POST /v1/storefront/checkout Publishable key

Legacy checkout: a Throttle checkout session from catalog lines. Use createCart.

X-Catalog-Key · no customer token
Implementation details

Operation legacyCheckout. The JSON request body is required.

Headers

FieldTypeRequiredDescription
X-Catalog-KeystringYesA publishable catalog key (pc_pk_…).
Idempotency-KeystringNoA retry with the same key answers the first request again instead of repeating it. Length 1–200

Request body

FieldTypeRequiredDescription
itemsobject[]YesItems 1–50
items[].skustringYesLength 1–255
items[].quantityintegerYesValue 1–10000
returnUrlstringYesLength at most 2048
cancelUrlstringYesLength at most 2048
customerEmailstringNoLength at most 320

Responses

200 OK.

Response fields

FieldTypeRequiredDescription
checkoutUrlstringYes
sessionIdstringYes
expiresAtstring | nullYes
cartIdstringYes
currencystringYes
linesobject[]Yes
lines[].skustringYes
lines[].quantityintegerYes
lines[].unitPriceMinorintegerYes
replayedtrueNo
400 Invalid request: an unknown or malformed parameter or body (issues names each).
401 Missing or unknown key (AUTHENTICATION_FAILED), or an invalid customer token (CUSTOMER_TOKEN_INVALID).
403 Refused for this key or shopper (ORIGIN_NOT_ALLOWED, SERVER_KEY_IN_BROWSER, KEY_NOT_ALLOWED_IN_URL, review eligibility codes).
409 Conflict with the store setup or an earlier request.
413 Request body too large.
422 The request is well formed but cannot be done (items names refused lines).
429 Rate limited: retry after Retry-After seconds. Headers: Retry-After.
500 Internal error.
502 Throttle refused the request (throttleCode).
503 Temporarily unavailable: retry after Retry-After seconds when present. Headers: Retry-After.

Error codes

Every error answers the same envelope, with a stable error.code. These are all the codes the API returns, with their HTTP statuses and whether a retry can succeed.

error.codeHTTPRetryable
INVALID_REQUEST400No
AUTHENTICATION_FAILED401No
INFRASTRUCTURE_UNAVAILABLE503Yes
PROVIDER_UNAVAILABLE503Yes
INTERNAL_ERROR500No
CUSTOMER_TOKEN_INVALID401No
ORIGIN_NOT_ALLOWED403No
SERVER_KEY_IN_BROWSER403No
KEY_NOT_ALLOWED_IN_URL403No
NOT_FOUND404No
RATE_LIMITED429Yes
STOREFRONT_UNAVAILABLE503Yes
REQUEST_BODY_TOO_LARGE413No
CART_CURRENCY_REQUIRED422No
CART_CURRENCY_NOT_ENABLED422No
CHECKOUT_NOT_CONFIGURED409No
EXTENSION_UPGRADE_REQUIRED409No
CART_ITEMS_INVALID422No
CART_REJECTED502No
CART_UNAVAILABLE503Yes
CHECKOUT_UNAVAILABLE503Yes
RETURN_URL_NOT_ALLOWED422No
CHECKOUT_TOTAL_TOO_LARGE422No
CHECKOUT_CART_MISMATCH409No
CHECKOUT_ITEMS_INVALID422No
CHECKOUT_REJECTED502No
CURRENCY_NOT_ENABLED400No
STOREFRONT_INDEXING503Yes
EMAIL_NOT_VERIFIED403No
NOT_VERIFIED_BUYER403No
PURCHASE_REFUNDED403No
ALREADY_REVIEWED409No
REVIEW_QUEUE_FULL429Yes
REVIEW_VERIFICATION_UNAVAILABLE503Yes