Docs
Storefront
GraphQL Storefront API
Inventory
Inventory queries

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.

Example request: Get aggregate inventory for a base 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:

Example JSON Response
{
  "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:

Example JSON Response
{
  "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:

Example JSON Response
{
  "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.

Example request: Get aggregate inventory for a variant
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 on is_in_stock and availableToSell values. The is_in_stock value is set by the Inventory API or in the product section of the control panel.
  • isInStock is TRUE if is_in_stock is TRUE and available_to_sell is more than zero.
Example request: Get a location's inventory for a variant
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.

Example request: Get inventory for a variant
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.

Example request: Get inventory for a variant
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:

Example request: Get inventory for a variant
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
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
Did you find what you were looking for?