Query Inventory with the GraphQL Storefront API
The GraphQL Storefront API allows you to fetch inventory for products and variants in your store location(s). The queries can show online availability for products or availability at location(s). You can filter by product or variant when fetching inventory.
Default behavior: By default, Stencil's native storefront and GraphQL's Get Stock by Locations queries support stock levels from only the default location. Aggregated stock includes stock from only the default location; queries for stock at each location return stock from only the default location.
Alternate behavior: Upon request, your store can have the following features:
- Stock per location
- Stock aggregated, or summed, from all locations
Contact the Support team (opens in a new tab) if you want the alternate behavior on your storefront. Stencil storefront pages will then reflect these features, including home, Category, and Product details pages. You will need to customize default themes to have these features on Elastic Search, Cart, Checkout, and Orders pages. For example, you can build a custom checkout on a headless storefront.
In the alternate behavior, aggregated stock calculations include only stock from active locations. To check if a location is active, use the Get locations endpoint.
Below are examples of queries that allow you to fetch inventory for storefront location(s).
For a general overview of the GraphQL Storefront API usage and capabilities, see GraphQL Storefront API Overview.
Fetch aggregate inventory for products
This query returns the aggregate inventory level for each product.
query {
site {
products {
edges {
node {
entityId
name
inventory {
aggregated { // By default, includes inventory from only the default location
availableToSell
warningLevel
}
}
}
}
}
}
}
In the example response, Example Product 1 has an aggregate inventory of 11.
You can filter by product so that only the inventory for certain products will be returned. To do so, use the entity IDs of the products you wish to return. For example, in the example response, Example Product 1 has an entityId of 113. You can make a new request that filters for this product by using entityId 113. See GraphQL Playground for documentation.
How inventory settings affect product inventories returned
The products returned depend on a store's inventory settings for out-of-stock products. If a merchant decides to hide out-of-stock products completely, out-of-stock products will not be returned. In the following example, Example Product 2s are out-of-stock and therefore, only (in-stock) Example Product 1 is returned:
{
"data": {
"site": {
"products": {
"edges": [
{
"node": {
"entityId": 113,
"name": "Example Product 1",
"inventory": {
"aggregated": {
"availableToSell": 20,
"warningLevel": 5
}
}
}
}
]
}
}
}
}
The inventory levels for products depend on a stores's inventory settings for displaying stock levels. If a merchant decides to not show stock levels, inventory levels will return null
as shown here:
{
"data": {
"site": {
"products": {
"edges": [
{
"node": {
"entityId": 113,
"name": "Example Product 1",
"inventory": {
"aggregated": null
}
}
},
{
"node": {
"entityId": 115,
"name": "Example Product 2",
"inventory": {
"aggregated": null
}
}
}
]
}
}
}
}
Similarly, if a merchant decides to only show stock levels for a product when stock is low, inventory levels for products that aren't low or aren't out of stock will return null
. In the following example, Example Product 1 returns null
because it is not low or out of stock:
{
"data": {
"site": {
"products": {
"edges": [
{
"node": {
"entityId": 113,
"name": "Example Product 1",
"inventory": {
"aggregated": null
}
}
},
{
"node": {
"entityId": 115,
"name": "Example Product 2",
"inventory": {
"aggregated": {
"availableToSell": 0,
"warningLevel": 0
}
}
}
}
]
}
}
}
}
Fetch aggregate inventory for variants
This query returns the aggregate inventory level for each variant. In this example, the query returns data for only one product by specifying the product's entityId.
query {
site {
products (entityIds:[113]) {
edges {
node {
entityId
name
variants {
edges {
node {
entityId
sku
inventory {
aggregated { // By default, includes inventory from only the default location
availableToSell
warningLevel
}
}
}
}
}
}
}
}
}
}
Fetch inventory for variants at each location
This query returns the inventory level for a specified variant. In this example, the query returns data for only one product and only one variant by specifying the product's entityId and the variant's entityId.
- The
isInStock
field is calculated based onis_in_stock
andavailableToSell
values. Theis_in_stock
value is set by the Inventory API or in the product section of the control panel. isInStock
is TRUE ifis_in_stock
is TRUE andavailable_to_sell
is more than zero.
query {
site {
products (entityIds:[113]) {
edges {
node {
entityId
name
variants (entityIds:[95]) {
edges {
node {
entityId
sku
inventory {
byLocation { // By default, returns only the default location
edges {
node {
locationEntityId
locationEntityCode
locationEntityTypeId
locationDistance {
value
lengthUnit
}
availableToSell
warningLevel
isInStock
}
}
}
}
}
}
}
}
}
}
}
}
As shown in the example response, locations are identified by a unique ID (locationEntityId
) and code (locationEntityCode
).
The location type ID (locationEntityTypeId
) is the location type, either PHYSICAL
or VIRTUAL
.
The location's code and type can be customized using Locations API.
How inventory settings affect variant inventories returned
The following examples show how variant inventories are affected when a merchant decides to hide out-of-stock options.
The query returns variant inventories if a variant has stock in at least one location.
query {
site {
products (entityIds:[113]) {
edges {
node {
entityId
name
variants (entityIds: [95]) {
edges {
node {
entityId
sku
inventory {
aggregated {
availableToSell
warningLevel
}
byLocation { // By default, returns only the default location
edges {
node {
locationEntityId
locationEntityCode
locationEntityTypeId
locationDistance {
value
lengthUnit
}
availableToSell
warningLevel
isInStock
}
}
}
}
}
}
}
}
}
}
}
}
If a variant is out of stock at all locations, the variant is not returned. In the following example, variant entityId: 95
is out of stock at all locations, but variant entityId: 96
has stock in at least one location.
query {
site {
products (entityIds:[113]) {
edges {
node {
entityId
name
variants (entityIds:[95,96]) {
edges {
node {
entityId
sku
inventory {
aggregated {
availableToSell
warningLevel
}
byLocation { // By default, returns only the default location
edges {
node {
locationEntityId
locationEntityCode
locationEntityTypeId
locationDistance {
value
lengthUnit
}
availableToSell
warningLevel
isInStock
}
}
}
}
}
}
}
}
}
}
}
}
The following example shows the returned response if you query for variants whose inventories are zero at all locations:
query {
site {
products (entityIds:[113]) {
edges {
node {
entityId
name
variants (entityIds:[95,96]) {
edges {
node {
entityId
sku
inventory {
aggregated {
availableToSell
warningLevel
}
byLocation {
edges {
node {
locationEntityId
locationEntityCode
locationEntityTypeId
locationDistance {
value
lengthUnit
}
availableToSell
warningLevel
isInStock
}
}
}
}
}
}
}
}
}
}
}
}