Read Products and Categories with the Core Subgraph.
Queries
Get Product by ID, SKU, or slug
id, sku, or slug, otherwise the query returns a
BAD_USER_INPUT error. Null when no Product in the Store's assortment matches.product(id:) field per ID.| Arguments | |
|---|---|
idID | Unique identifier of the Product. |
skuString | SKU of one of the Product's variants. |
slugString | Slug of the Product for the session's locale. |
query GetProduct {
product(slug: "oak-dining-chair") {
id
slug
productName
description
price { formatted }
availability { inStock quantity }
variants { sku }
}
}
{
"data": {
"product": {
"id": "AQAAAREQERAREUEQoRAREREQERAAAAABAAAAAAABAAEAAAAAAAEAAAABAAEAAA",
"slug": "oak-dining-chair",
"productName": "Oak Dining Chair",
"description": "A solid oak dining chair with a curved backrest.",
"price": { "formatted": "£89.00" },
"availability": { "inStock": true, "quantity": 3 },
"variants": [{ "sku": "CHAIR-OAK-01" }, { "sku": "CHAIR-OAK-02" }]
}
}
}
Query Products
search for text search and a filter rail.PRODUCT_SEARCH_NOT_ENABLED error.
Catalog changes appear with a short delay.| Arguments | |
|---|---|
filter | Filters to apply to the list. |
sort | Sort order of the list. |
firstInt | Number of Products to return, from 0 to 100. A value outside this range returns a
Default: BAD_USER_INPUT error whose extensions name the argument and the limit.20 |
afterString | Cursor after which the page starts, from ProductEdge.cursor or
PageInfo.endCursor. A cursor that this API didn't issue returns a
BAD_USER_INPUT error. |
query ListProducts {
products(sort: {field: NAME}, first: 2) {
totalCount
pageInfo { hasNextPage endCursor }
nodes { slug productName }
}
}
{
"data": {
"products": {
"totalCount": 48,
"pageInfo": { "hasNextPage": true, "endCursor": "AW9nZ3NkdDsx" },
"nodes": [
{ "slug": "linen-cushion", "productName": "Linen Cushion" },
{
"slug": "oak-dining-chair",
"productName": "Oak Dining Chair"
}
]
}
}
}
Search Products
Searches the Products in the Store's assortment by text and returns a page of results with facets for a filter rail.
PRODUCT_SEARCH_NOT_ENABLED error.| Arguments | |
|---|---|
queryString | Text to search for in the Product name, description, slug, and search keywords for the session's locale. |
queryMode | Matching mode for Can be query. Defaults to FULL_TEXT.FULL_TEXT, CONTAINS, FUZZY, or PREFIX |
filter | Filters to apply to the result. |
sort | Sort order of the result. |
firstInt | Number of Products to return, from 0 to 100. A value outside this range returns a
Default: BAD_USER_INPUT error whose extensions name the argument and the limit.20 |
afterString | Cursor after which the page starts, from ProductEdge.cursor or
PageInfo.endCursor. A cursor that this API didn't issue returns a
BAD_USER_INPUT error. |
query SearchProducts {
search(query: "chair", filter: {priceMax: 100}, sort: {field: PRICE}, first: 20) {
totalCount
facets {
label
options { value count }
}
nodes { productName }
}
}
{
"data": {
"search": {
"totalCount": 1,
"facets": [
{
"label": "Finish",
"options": [
{ "value": "natural-oak", "count": 1 },
{ "value": "smoked-oak", "count": 1 }
]
}
],
"nodes": [{ "productName": "Oak Dining Chair" }]
}
}
}
Query Categories
orderHint order. Use parent and
children to build the tree.query GetCategories {
categories {
slug
name
parent { slug }
}
}
{
"data": {
"categories": [
{ "slug": "furniture", "name": "Furniture", "parent": null },
{
"slug": "dining-chairs",
"name": "Dining Chairs",
"parent": { "slug": "furniture" }
}
]
}
}
Get Category by ID or slug
id or slug, otherwise the query returns a
BAD_USER_INPUT error. Null when no Category matches.| Arguments | |
|---|---|
idID | Unique identifier of the Category. |
slugString | Slug of the Category for the session's locale. |
query GetCategory {
category(slug: "dining-chairs") {
id
slug
name
description
parent { slug name }
children { slug }
}
}
{
"data": {
"category": {
"id": "AQUAAWZnZmdmZkZnpmdmZmZnZmcAAAABAAAAAAABAAEAAAAAAAEAAAABAAEAAA",
"slug": "dining-chairs",
"name": "Dining Chairs",
"description": "Chairs for the dining room and kitchen.",
"parent": { "slug": "furniture", "name": "Furniture" },
"children": []
}
}
}
Output types
Product
A Product in the Store's assortment.
attributes field to Product and ProductVariant,
generated from its Product Types. It returns the ProductAttributes or
ProductVariantAttributes interface, with one implementing
<ProductType>Attributes type per Product Type, and a raw JSON map of the
attribute values.idID | Unique identifier of the Product. |
keyString | User-defined unique identifier of the Product. |
slugString | User-defined identifier used in a deep-link URL for the Product, for the session's locale. |
productNameString | Name of the Product, for the session's locale. |
descriptionString | Description of the Product, for the session's locale. Null when the Product has no description. |
categoriesArray of Category | Categories assigned to the Product. |
imagesArray of Image | Images of the default variant. |
price | Price of the default variant, resolved as described on
ProductVariant.price.null when the session isn't entitled to a price, or the default variant has no
price in the session's currency or country. addCartLine refuses such a variant
with PRICE_NOT_AVAILABLE. Other variants can still have a price, so check
variants. |
priceBeforeDiscount | The price before its Product Discount: the strike-through price. |
discountedPrice | The default variant's price after its Product Discount, and the Product Discount behind it; null when no Product Discount applies. price then equals discountedPrice.value. |
availability | Inventory of the default variant, counted as described on
ProductVariant.availability. |
optionsArray of ProductOption | Axes on which the Product's variants differ, for rendering a variant picker. Empty when the variants don't differ on any selectable attribute. |
variantsArray of ProductVariant | Variants of the Product, starting with the default variant. Variants without a SKU are left out. |
defaultVariant | Default variant of the Product. This is the master variant, or the first variant with a SKU when the master variant has none. |
matchingVariantsArray of ProductVariant | Variants that matched the query or filter of Query.search or
Query.products. Null when the Product was read another way. |
attributeLabelsArray of AttributeLabel | Labels for the Product's attributes. Use them to label attribute rows without selecting a specific Product Type. |
_standalonePricesArray of InternalStandalonePrice | All Standalone
Prices of the
Product's variants, for extensions. Storefronts read ProductVariant.price. Not
part of the public API: an extension can read it with @requires, and it's
removed from the composed API schema. |
_ctIdID | Platform identifier (UUID) of the Product, for extensions that key an external
system by it. The public id is an opaque global identifier, so don't parse it.
Not part of the public API: an extension can read it with @requires, and it's
removed from the composed API schema. |
InternalStandalonePrice
Product._standalonePrices.skuString | SKU of the Product Variant the price applies to. |
channelIdID | Identifier of the distribution Channel the price is scoped to. Null when the price has no Channel. |
channelKeyString | Key of the distribution Channel the price is scoped to. Null when the price has no Channel or the Channel has no key. |
centAmountInt | Amount in the smallest indivisible unit of the currency, such as cents for EUR and USD, or pence for GBP. |
currencyCodeString | Currency code compliant to ISO 4217. |
Product Variant
A purchasable version of a Product, such as one combination of size and color.
idID | Unique identifier of the Product Variant. Unique across all Products. |
skuString | SKU of the Product Variant. Unique across all Product Variants in a Project. Pass it
to addCartLine to add the variant to the Cart. |
selectedOptionsArray of SelectedOption | Values of this variant on the axes in Product.options. Axes for which the
variant has no value are left out. |
price | Price of the variant for the session's currency, country, distribution channel, and Customer Group, with any Product Discount applied. null if the session isn't entitled to a price, if the variant has no price for
the session's currency or country, or if the Store has no prices in the session's
currency. Adding such a variant with addCartLine returns
PRICE_NOT_AVAILABLE. |
priceBeforeDiscount | The price before its Product Discount: the strike-through price. |
discountedPrice | The price after its Product Discount, and the Product Discount behind it; null when no Product Discount applies. price then equals discountedPrice.value. |
priceTiersArray of PriceTier | Price tiers of price, lowest minimumQuantity first. Empty when the price has
no tiers or the variant has no price. |
availability | Inventory of the variant for the session's supply channel. Without a supply channel, the stock of all supply channels is added up. |
imagesArray of Image | Images of the Product Variant. |
assetsArray of Asset | Assets of the Product Variant, such as documents, videos, or 3D models. Empty when the
variant has no Assets, or none matches tags. |
Discounted Price
A product's price after its Product Discount, per unit.
value | |
productDiscount |
Asset
sources. Text fields are resolved for the session's locale.keyString | User-defined identifier of the Asset. Unique within the Product Variant. |
nameString | Name of the Asset, for the session's locale. An empty string when the Asset has no name. |
descriptionString | Description of the Asset, for the session's locale. Null when the Asset has no description. |
tagsArray of String | Keywords for categorizing and organizing Assets. Empty when the Asset has no tags. |
sourcesArray of AssetSource | Files of the Asset. One Asset can have several, for example the same video in different formats or resolutions. |
{
"key": "assembly-instructions",
"name": "Assembly instructions",
"description": "Step-by-step guide for assembling the chair.",
"tags": ["manual"],
"sources": [
{
"uri": "https://assets.example.com/oak-dining-chair-assembly.pdf",
"key": "pdf",
"contentType": "application/pdf",
"width": null,
"height": null
}
]
}
Asset Source
One file of an Asset.
uriString | URI of the file. |
keyString | User-defined identifier of the source. Unique within the Asset. |
contentTypeString | Media type of the file, for example application/pdf. Null if not set. |
widthInt | Width of the file. Null if not set. |
heightInt | Height of the file. Null if not set. |
{
"uri": "https://assets.example.com/oak-dining-chair-360.mp4",
"key": "video-1080p",
"contentType": "video/mp4",
"width": 1920,
"height": 1080
}
Selected Option
ProductOption axis.codeString | Name of the attribute, matching ProductOption.code. |
valueString | Value of the variant for the attribute, in the same form as
ProductOptionValue.value, for example #FFF. |
Price Tier
minimumQuantity units on a Cart line,
each unit costs price.minimumQuantityInt | Minimum quantity this price tier is valid for. Always 2 or greater, since a single
unit costs the variant's price. |
price | Price of one unit at this quantity, not the line total. |
Product Option
A variant selection axis of a Product, such as color or size.
code values you want to render.codeString | Name of the attribute behind this axis. |
labelString | Display label of the attribute for the session's locale. Falls back to code when
the attribute definition has no label for that locale. |
valuesArray of ProductOptionValue | Distinct values of the attribute across the Product's variants, in the order in which the variants first use them. |
Product Option Value
ProductOption axis. A variant has this value when
its SelectedOption with the same code has the same value.valueString | Attribute value as stored, such as an enum key, or localized text resolved for the session's locale. |
labelString | Display label of the value for the session's locale. Falls back to value when
the value has no label. |
Attribute Label
An attribute name paired with its display label.
nameString | Name of the attribute, for example iso45001. |
labelString | Display label of the attribute for the session's locale, for example ISO 45001.
Falls back to name when the attribute definition has no label for that locale. |
Category
slug as
ProductFilter.categorySlug to list its Products. Text fields are resolved for the
session's locale.idID | Unique identifier of the Category. |
keyString | User-defined unique identifier of the Category. |
slugString | User-defined identifier used as a deep-link URL to the Category, for the session's locale. An empty string when the Category has no slug for that locale. |
nameString | Name of the Category, for the session's locale. An empty string when the Category has no name for that locale. |
descriptionString | Description of the Category, for the session's locale. Null when the Category has no description for that locale. |
orderHintString | Decimal value between 0 and 1 for ordering Categories within the same level of the category tree. |
parent | Parent Category of this Category. Null for a root Category. |
childrenArray of Category | Child Categories of this Category, sorted by orderHint in ascending order. Empty
for a Category without children. |
_ctIdID | Platform identifier (UUID) of the Category, for extensions that correlate a search
index or merchandising system by it. The public
id is an opaque global
identifier, so don't parse it.Not part of the public API: an extension can read it with @requires, and it is
removed from the composed API schema. |
Product Connection
Query.products.edgesArray of ProductEdge | Products on this page, with their cursors. |
nodesArray of Product | Products on this page, in the same order as edges. |
pageInfo | Pagination information for this page. |
totalCountInt | Total number of Products that match the request, across all pages. |
Product Edge
ProductConnection or ProductSearchConnection.node | Product at this position in the list. |
cursorString | Opaque cursor of this Product. Pass it as after to get the Products that follow
it. |
Product Search Connection
Query.search results. Same as ProductConnection, plus facets.facetsArray of Facet | Facets of the search result. |
edgesArray of ProductEdge | Products on this page, with their cursors. |
nodesArray of Product | Products on this page, in the same order as edges. |
pageInfo | Pagination information for this page. |
totalCountInt | Total number of Products that match the search, across all pages. |
Facet
Filter-rail entry for one attribute of the search result.
options doesn't list, pass it
in ProductFilter.attributes.codeString | Identifier of the attribute, in the format variants.attributes.<attributeName>.
Pass it unchanged as code in AttributeFilterInput or
AttributeRangeFilterInput. |
labelString | Display label of the attribute for the session's locale. Falls back to the attribute name. |
optionsArray of FacetOption | Up to 10 most common values, highest count first. Values with the same count are
sorted by value, so the order is stable between requests. |
Facet Option
Facet.valueString | Attribute value as stored, such as an enum key. Pass it in
AttributeFilterInput.values to filter on it. |
labelString | Display label of the value for the session's locale. Falls back to value when
the value has no label. |
countInt | Number of Products in the result that have this value. |
Attribute Filter Operator
values of an AttributeFilterInput are matched against the attribute.EXACT- Matches a value exactly.
FUZZY- Matches a value with small typos. The tolerance increases with the length of the value.
PREFIX- Matches an attribute value that starts with the given text.
WILDCARD- Matches using the `*` and `?` wildcards written in the value.
EXISTS- Matches Products that have any value for the attribute.
Product Sort Field
ProductSort. Each value has its own default direction.RELEVANCE- Relevance to the search `query`. Most relevant first by default.
PRICE- Price for the session. Cheapest first by default, and `direction: DESC` reverses it. Ascending order uses each Product's cheapest variant price, and descending order its most expensive one. This can differ from `Product.price`, which is the price of the DEFAULT variant, so a Product's position may not match the price it shows. To show the prices a Product was ranked on, select `variants { price }`. `ProductFilter.priceMin` and `ProductFilter.priceMax` use the same per-variant rule.
NAME- Product name for the session's locale. A to Z by default.
NEWEST- Creation date of the Product. Newest first by default.
Search Query Mode
Query.search. A query equal to a variant's SKU matches
that Product in every mode.FULL_TEXT- Matches whole words: every word of `query` must appear in the field, in any order. A fragment of a word does not match, so `bat` does not find `battery`. This is the default.
CONTAINS- Matches when the text appears anywhere in the field, including inside a word (`bat` finds `battery`), ignoring case.
FUZZY- Matches with small typos. The tolerance increases with the length of `query`.
PREFIX- Matches when the field starts with the text, ignoring case.
Input types
Product Filter
categorySlug that matches no Category, or an attribute code the Project
can't filter on, returns an empty page.categorySlugString | Slug of a Category for the session's locale. Returns only Products assigned to that Category. |
onSaleBoolean | Whether to return only Products with a discounted price for the session ( true),
or only Products without one (false). Decided per variant, like priceMin:
true can return a Product whose Product.price isn't discounted, and
false can return a Product that has a discounted variant. |
priceMinFloat | Lowest price to include, in major units of the session's currency, for example
50 for £50.00. Discounted prices are compared per variant, as described on
ProductSortField.PRICE, so a Product can match while Product.price is
outside the range. |
priceMaxFloat | Highest price to include, in major units of the session's currency. Compared like
priceMin. |
attributesArray of AttributeFilterInput | Filters on the Product's attributes. Accepts any value of the attribute, including
values that
Facet.options doesn't list.Also accepts the Project's searchable text attributes, which have no facet. A localized text attribute is matched on its value for the session's locale. |
attributeRangesArray of AttributeRangeFilterInput | Numeric range filters on the Product's attributes, by the same code as
attributes. |
Attribute Filter Input
ProductFilter.attributes
must all match.codeString | Identifier of the attribute, as reported in Facet.code, for example
variants.attributes.finish. |
operator | Matching mode for Can be values. Defaults to EXACT.EXACT, FUZZY, PREFIX, WILDCARD, or EXISTS |
valuesArray of String | Values to match. A Product matches when it has any of them. An empty list applies no
filter. Ignored when operator is EXISTS. |
Attribute Range Filter Input
AttributeFilterInput.codeString | Identifier of the attribute, as reported in Facet.code. |
minFloat | Lowest value to include. |
maxFloat | Highest value to include. |
Product Sort
Query.products and Query.search.sort, passing sort: {}, and passing sort: {field: RELEVANCE}
return the same order. Products that sort equally are always returned in the same
order, so paging doesn't repeat or skip a Product.field | Field to sort by. Defaults to Can be RELEVANCE.RELEVANCE, PRICE, NAME, or NEWESTDefault: RELEVANCE |
direction | Direction of the sort. Omit it to use the default direction of Can be field, listed on
each ProductSortField value. Set it only to reverse that default.ASC, or DESC |