Skip to navigation

Backorders let customers purchase products that are currently out of stock, up to a configurable limit per location. When backorders are enabled, BigCommerce tracks backordered quantities separately from on-hand inventory, giving you visibility into fulfillment obligations and the ability to set limits on how many units can be backordered.

This guide covers the API endpoints, GraphQL fields, Stencil context variables, and events involved in creating, adjusting, querying, and displaying backorders across the product detail page, cart, checkout, and order confirmation.

Physical products only

Backorder messaging applies to physical products. Digital products cannot be backordered — the inventory service reports them as unavailable for backorder regardless of their backorder_limit setting.

Tracking backorders in orders

Use the V2 Orders API to include backordered quantities when creating or updating an order. The quantity_backordered field tracks how many units of a line item are backordered.

PUT /stores/{store_hash}/v2/orders/{order_id}

{
"products": [
{
"id": 8,
"quantity": 10,
"quantity_backordered": 3
}
]
}

You can also supply quantity_backordered when sending a POST request to create an order. The field is returned in the response when the order has backordered items.

Orders also return two related fields:

FieldLevelDescription
backorder_messageOrder product (line item)The backorder message shown to the customer for this line item at the time the order was placed. null when the line item has no backordered quantity.
backorder_shipping_expectation_messageOrderThe shipping expectation message shown to the customer when the order contains a backordered item. null when the order has no backordered items.

Error response for unavailable quantities

If a customer attempts to order more than the available stock plus the backorder limit, the API returns a 409 error with details about the constraint:

[
{
"status": 409,
"message": "Quantities of one or more products are out of stock or did not meet quantity requirements.",
"details": {
"errors": [
{
"type": "OutOfStock",
"message": "Insufficient stock of variant(id: 74), available stock: 10, available quantity for backorder: 45. order(id: ), channel(id: 1), location(id: 1).",
"variant_id": 74,
"location_id": 1,
"available_quantity": 10,
"available_quantity_for_backorder": 45
}
]
}
}
]

Adjusting backorder inventory

Use the V3 Inventory Adjustments endpoints to set or modify the qty_backordered value for items at specific locations.

Absolute adjustments

Set backorder quantities to exact values.

PUT /stores/{store_hash}/v3/inventory/adjustments/absolute

{
"reason": "Absolute adjustment reason",
"items": [
{
"location_id": 1,
"variant_id": 1,
"quantity": 1,
"qty_backordered": 0
},
{
"location_id": 2,
"variant_id": 3,
"quantity": 1
},
{
"location_id": 3,
"sku": "sku-4",
"qty_backordered": 0
},
{
"location_id": 1,
"sku": "sku-5",
"quantity": 1,
"qty_backordered": 0
},
{
"location_id": 1,
"product_id": 111,
"quantity": 7,
"qty_backordered": 0
}
]
}

Relative adjustments

Increment or decrement backorder quantities relative to their current values.

POST /stores/{store_hash}/v3/inventory/adjustments/relative

{
"reason": "Relative adjustment reason",
"items": [
{
"location_id": 1,
"variant_id": 1,
"quantity": 1,
"qty_backordered": -1
},
{
"location_id": 2,
"variant_id": 3,
"quantity": 1
},
{
"location_id": 3,
"sku": "sku-4",
"qty_backordered": -3
},
{
"location_id": 1,
"sku": "sku-5",
"quantity": -1
}
]
}

Configuring backorder limits

Use the V3 Inventory endpoints to read current backorder levels and set the backorder_limit for items at a location.

Get inventory at a location

GET /stores/{store_hash}/v3/inventory/locations/{location_id}/items

{
"data": [
{
"identity": {
"sku": "RE-130",
"variant_id": 78,
"product_id": 130
},
"available_to_sell": 10,
"total_inventory_onhand": 12,
"qty_backordered": 0,
"settings": {
"safety_stock": 2,
"is_in_stock": true,
"warning_level": 2,
"bin_picking_number": "1",
"backorder_limit": 33
}
}
],
"meta": {}
}

Get inventory across all locations

GET /stores/{store_hash}/v3/inventory/items

{
"data": [
{
"identity": {
"sku": "RE-130",
"variant_id": 79,
"product_id": 120,
"sku_id": 0
},
"locations": [
{
"location_id": 1,
"location_code": "BC-LOCATION-1",
"location_name": "Default location",
"available_to_sell": 10,
"total_inventory_onhand": 11,
"location_enabled": true,
"qty_backordered": 0,
"settings": {
"safety_stock": 1,
"is_in_stock": true,
"warning_level": 1,
"bin_picking_number": "1",
"backorder_limit": 33
}
}
]
}
],
"meta": {}
}

Update backorder limit

PUT /stores/{store_hash}/v3/inventory/locations/{location_id}/items

{
"settings": [
{
"identity": {
"sku": "SLCTBS-A9615491",
"variant_id": 1,
"product_id": 77
},
"backorder_limit": 100
}
]
}

backorder_limit accepts an integer or null. A null value means the item has no backorder limit — it can be backordered in unlimited quantity.

The available_to_sell value returned by the inventory endpoints reflects backorder capacity: available_to_sell = total_inventory_onhand - safety_stock + backorder_limit.

Backorder display settings

Backorder messaging introduces store-level display settings that control which backorder information is shown to shoppers — for example, whether the product detail page shows a backorder availability prompt, and what text that prompt uses. Read and update these settings with the V3 Settings API.

All display settings default to false (or, for the two message strings, a default value). Enable the ones you want shoppers to see; storefronts don’t display backorder messaging until you do.

GET /stores/{store_hash}/v3/settings/inventory

{
"data": {
"show_quantity_on_backorder": false,
"show_quantity_on_hand": false,
"show_backorder_message": false,
"show_backorder_availability_prompt": false,
"backorder_availability_prompt": "More available for backorder",
"show_default_shipping_expectation_prompt": false,
"default_shipping_expectation_prompt": "We ship available items right away, and backordered items as soon as they're in stock"
}
}

PUT /stores/{store_hash}/v3/settings/inventory

{
"show_quantity_on_backorder": true,
"show_backorder_message": true,
"show_backorder_availability_prompt": true,
"backorder_availability_prompt": "Available on backorder"
}

Only include the fields you want to change — omitted fields keep their current values. If the store’s backorder feature isn’t enabled, these fields are omitted from the response entirely. Backorders are enabled through the store control panel under Settings › Inventory.

SettingWhat the shopper sees
show_quantity_on_backorder”3 will be backordered” on the product detail page and in cart line items
show_quantity_on_hand”5 ready to ship” in cart line items
show_backorder_messageA per-variant backorder message (e.g. “Ships in 2–3 weeks”) on the product detail page, cart, and product cards
show_backorder_availability_prompt / backorder_availability_promptAn availability prompt next to the stock level on the product detail page
show_default_shipping_expectation_prompt / default_shipping_expectation_promptA shipping expectation message in cart totals when any item is backordered

Backorder messaging on the storefront

The Storefront GraphQL API (at {store_domain}/graphql) exposes the same display settings, plus backorder quantities and messages on products, variants, cart line items, and orders. These fields require a valid storefront token.

Display settings

Query path: site.settings.inventory

query InventorySettings {
site {
settings {
inventory {
showQuantityOnBackorder
showBackorderMessage
showBackorderAvailabilityPrompt
backorderAvailabilityPrompt
showDefaultShippingExpectationPrompt
defaultShippingExpectationPrompt
showQuantityOnHand
}
}
}
}

Use these booleans to decide which backorder UI elements to render. They mirror the merchant display settings above.

Product and variant inventory

query ProductBackorderData($productId: Int!) {
site {
product(entityId: $productId) {
inventory {
isStockTracked
aggregated {
availableToSell
availableOnHand
unlimitedBackorder
availableForBackorder
}
}
variants(first: 10) {
edges {
node {
entityId
inventory {
aggregated {
availableToSell
availableOnHand
unlimitedBackorder
availableForBackorder
}
byLocation {
edges {
node {
locationEntityId
backorderMessage
}
}
}
}
}
}
}
}
}
}
TypeFieldGraphQL typeDescription
ProductInventoryisStockTrackedBoolean!Whether this product has inventory tracking. Use to decide whether backorder UI is relevant.
Aggregated / AggregatedInventoryavailableOnHandLong!Physical on-hand quantity across locations.
Aggregated / AggregatedInventoryunlimitedBackorderBoolean!Whether unlimited backorder is enabled.
Aggregated / AggregatedInventoryavailableForBackorderLongRemaining backorder capacity. null if unlimited.
InventoryByLocationsbackorderMessageString!Per-location backorder message text (the merchant-configured message).

Cart line items

cart requires the cart’s entityId — without it, site.cart resolves to null:

query CartWithBackorder($cartId: String) {
site {
cart(entityId: $cartId) {
lineItems {
physicalItems {
entityId
name
quantity
stockPosition {
quantityOnHand
quantityBackordered
quantityOutOfStock
backorderMessage
}
}
digitalItems {
entityId
name
quantity
# stockPosition is present in the schema but digital products
# cannot be backordered, so these values will always be zero.
stockPosition {
quantityOnHand
quantityBackordered
quantityOutOfStock
backorderMessage
}
}
}
}
}
}
FieldGraphQL typeDescription
stockPosition.quantityOnHandInt!Units from this line item ready to ship.
stockPosition.quantityBackorderedInt!Units on backorder.
stockPosition.quantityOutOfStockInt!Units that exceeded backorder capacity.
stockPosition.backorderMessageStringPer-variant backorder message.

Orders

OrderFilterInput requires entityId (the order ID) — for a guest order, it also requires cartEntityId (the ID of the cart the order was placed from) to prove access to the order:

query OrderWithBackorder($filter: OrderFilterInput) {
site {
order(filter: $filter) {
entityId
backorderShippingExpectationMessage
consignments {
shipping {
edges {
node {
lineItems {
edges {
node {
entityId
name
quantity
backorderedQuantity
backorderMessage
}
}
}
}
}
}
}
}
}
}
FieldGraphQL typeDescription
backorderShippingExpectationMessageStringOrder-level shipping expectation message.
backorderedQuantityInt!Units on backorder for this line item.
backorderMessageStringBackorder message at the time the order was placed.

Backorder messaging on the Storefront REST cart and checkout APIs

Both the Storefront Cart API and the Storefront Checkout API return a stockPosition object on physical and digital line items, but only when explicitly requested — it is not returned by default. Since digital products cannot be backordered, stockPosition is only meaningful for physical items.

Storefront Cart API

Request stock position data with include=lineItems.physicalItems.stockPosition:

GET /carts/{cart_id}?include=lineItems.physicalItems.stockPosition

{
"lineItems": {
"physicalItems": [
{
"id": "00cf6889-2289-4666-bbf0-7e2d10504f6d",
"quantity": 8,
"stockPosition": {
"quantityOnHand": 5,
"quantityBackordered": 3,
"quantityOutOfStock": 0,
"backorderMessage": ""
}
}
]
}
}

Storefront Checkout API

Request stock position data with include=cart.lineItems.physicalItems.stockPosition:

GET /checkouts/{checkout_id}?include=cart.lineItems.physicalItems.stockPosition

{
"cart": {
"lineItems": {
"physicalItems": [
{
"id": "a01b7d1e-1111-4d1e-8f1a-2222bcaa9e00",
"quantity": 8,
"stockPosition": {
"quantityOnHand": 5,
"quantityBackordered": 3,
"quantityOutOfStock": 0,
"backorderMessage": ""
}
}
]
}
}
}
FieldDescription
stockPosition.quantityOnHandUnits from this line item ready to ship.
stockPosition.quantityBackorderedUnits on backorder.
stockPosition.quantityOutOfStockUnits that exceeded backorder capacity.
stockPosition.backorderMessagePer-variant backorder message. "" when no message is configured.

Like all Checkout API requests, this runs in the context of an active storefront session (same-origin cookie-based auth), not a bare bearer token — see Same-origin CORS authentication.

Stencil theme development

For Stencil theme developers, backorder messaging adds context variables to the product detail page, cart, and order templates.

Product detail page context variables

These {{inject}} variables push backorder data into jsContext on the product detail page:

Inject keySourceDescription
availableOnHandproduct.available_on_handPhysical on-hand quantity
availableForBackorderproduct.available_for_backorderRemaining backorder capacity
availableToSellproduct.available_to_sellTotal sellable quantity (on-hand + backorder)
unlimitedBackorderproduct.unlimited_backorderWhether backorder limit is unlimited
showQuantityOnBackorderproduct.show_quantity_on_backorderDisplay setting: show backordered quantity
showBackorderAvailabilityPromptproduct.show_backorder_availability_promptDisplay setting: show availability prompt
backorderAvailabilityPromptproduct.backorder_availability_promptThe availability prompt text
showBackorderMessageproduct.show_backorder_messageDisplay setting: show per-variant message
backorderMessagesbackorder_messagesMap of backorder message objects
quantityBackorderedMessageproducts.quantity_backordered lang keyTemplate: “{qty} will be backordered”
quantityMaxMessageproducts.quantity_max lang keyTemplate: “Max purchasable is {qty}“
quantityMaxPicklistMessageproducts.quantity_max_picklist lang keyTemplate: “Max for {name} is {qty}”

In add-to-cart.html, the {{#unless product.available_to_sell}} guard prevents the “Sold Out” alert from displaying when a product has backorder capacity — the Add to Cart button stays enabled even when on-hand stock is zero.

Cart context

Cart templates receive an inventory_settings object and a per-item stock_position:

{{!-- Display settings --}}
cart.inventory_settings.show_quantity_on_hand
cart.inventory_settings.show_quantity_on_backorder
cart.inventory_settings.show_backorder_message
cart.inventory_settings.show_default_shipping_expectation_prompt
cart.inventory_settings.default_shipping_expectation_prompt
{{!-- Per line item --}}
stock_position.quantity_on_hand
stock_position.quantity_backordered
stock_position.backorder_message
{{!-- Per bundled/picklist option --}}
linked_bundled_item.stock_position.quantity_on_hand
linked_bundled_item.stock_position.quantity_backordered
linked_bundled_item.stock_position.backorder_message

Where these variables are consumed

For the underlying Handlebars template markup and JavaScript call sites, see the public Cornerstone repository:

FileWhat it does
templates/components/products/product-view.htmlReads product.backorder_availability_prompt on the product detail page.
templates/components/cart/totals.htmlReads cart.inventory_settings.default_shipping_expectation_prompt in cart totals.
assets/js/theme/common/product-details-base.jsReads backorder_availability_prompt from the product attributes AJAX response during variant selection.

Catalyst reference implementation

Catalyst, BigCommerce’s headless storefront reference built on Next.js, has full backorder support. Use these files as working examples of how to consume the GraphQL fields documented above.

Product detail page

FileWhat it does
core/app/[locale]/(default)/product/[slug]/page.tsxFetches inventory data and display settings. Builds streamableBackorderDisplayData (backorder quantities, message) and streamableStockDisplayData (availability prompt, adjusted stock display).
core/vibes/soul/sections/product-detail/product-detail-form.tsxRenders the availability prompt and dynamically computes “N will be on backorder” based on quantity input vs. on-hand stock.

Cart

FileWhat it does
core/app/[locale]/(default)/cart/page.tsxFetches stockPosition on physical items. Builds per-line-item inventoryMessages with backordered quantity and message text.
core/vibes/soul/sections/cart/client.tsxRenders backorder messages per line item in the cart UI.

Product cards

FileWhat it does
core/data-transformers/product-card-transformer.tsgetInventoryMessage() extracts the backorder message for products with zero on-hand but backorder capacity.
core/components/product-card/fragment.tsGraphQL fragment fetching availableForBackorder, unlimitedBackorder, availableOnHand, and backorderMessage.

GraphQL fragments

FileWhat it fetches
core/components/product-variants-inventory/fragment.tsVariant-level backorderMessage from inventory.byLocation for product detail page variant switching.
core/app/[locale]/(default)/product/[slug]/page-data.tsInventorySettingsQuery for store-level display settings.

Querying backorder data with Admin GraphQL

Use the Admin GraphQL API to query inventory data including backorder fields at the product and variant level.

{
store {
products {
edges {
node {
id
inventory {
aggregated {
availableToSell
warningLevel
backorderLimit
onHand
qtyBackordered
}
}
variants {
edges {
cursor
node {
id
inventory {
aggregated {
availableToSell
warningLevel
backorderLimit
onHand
qtyBackordered
}
}
}
}
}
}
}
}
}
}

Webhooks

Subscribe to this webhook event to monitor backorder activity.

Stock level changed

Fires when a product or variant stock level changes at a location — including when backordered quantity changes:

store/channel/{channel_id}/inventory/product/stock_changed

See Inventory and location events for the full list of related webhook events.