> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Backorders

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](/developer/api-reference/rest/admin/management/orders/update-order) 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}`

```json
{
  "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:

| Field                                    | Level                     | Description                                                                                                                                             |
| ---------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `backorder_message`                      | Order 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_message` | Order                     | The 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:

```json
[
  {
    "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](/developer/api-reference/rest/admin/management/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`

```json
{
  "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`

```json
{
  "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](/developer/api-reference/rest/admin/management/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`

```json
{
  "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`

```json
{
  "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`

```json
{
  "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](/developer/api-reference/rest/admin/management/settings).

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`

```json
{
  "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`

```json
{
  "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**.

| Setting                                                                            | What 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_message`                                                           | A 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_prompt`             | An availability prompt next to the stock level on the product detail page                                       |
| `show_default_shipping_expectation_prompt` / `default_shipping_expectation_prompt` | A 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`

```graphql
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

```graphql
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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```

| Type                                 | Field                   | GraphQL type | Description                                                                                  |
| ------------------------------------ | ----------------------- | ------------ | -------------------------------------------------------------------------------------------- |
| `ProductInventory`                   | `isStockTracked`        | `Boolean!`   | Whether this product has inventory tracking. Use to decide whether backorder UI is relevant. |
| `Aggregated` / `AggregatedInventory` | `availableOnHand`       | `Long!`      | Physical on-hand quantity across locations.                                                  |
| `Aggregated` / `AggregatedInventory` | `unlimitedBackorder`    | `Boolean!`   | Whether unlimited backorder is enabled.                                                      |
| `Aggregated` / `AggregatedInventory` | `availableForBackorder` | `Long`       | Remaining backorder capacity. `null` if unlimited.                                           |
| `InventoryByLocations`               | `backorderMessage`      | `String!`    | 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`:

```graphql
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
          }
        }
      }
    }
  }
}
```

| Field                               | GraphQL type | Description                              |
| ----------------------------------- | ------------ | ---------------------------------------- |
| `stockPosition.quantityOnHand`      | `Int!`       | Units from this line item ready to ship. |
| `stockPosition.quantityBackordered` | `Int!`       | Units on backorder.                      |
| `stockPosition.quantityOutOfStock`  | `Int!`       | Units that exceeded backorder capacity.  |
| `stockPosition.backorderMessage`    | `String`     | Per-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:

```graphql
query OrderWithBackorder($filter: OrderFilterInput) {
  site {
    order(filter: $filter) {
      entityId
      backorderShippingExpectationMessage
      consignments {
        shipping {
          edges {
            node {
              lineItems {
                edges {
                  node {
                    entityId
                    name
                    quantity
                    backorderedQuantity
                    backorderMessage
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```

| Field                                 | GraphQL type | Description                                         |
| ------------------------------------- | ------------ | --------------------------------------------------- |
| `backorderShippingExpectationMessage` | `String`     | Order-level shipping expectation message.           |
| `backorderedQuantity`                 | `Int!`       | Units on backorder for this line item.              |
| `backorderMessage`                    | `String`     | Backorder message at the time the order was placed. |

## Backorder messaging on the Storefront REST cart and checkout APIs

Both the [Storefront Cart API](/developer/api-reference/rest/storefront/carts) and the [Storefront Checkout API](/developer/api-reference/rest/storefront/checkouts) 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`

```json
{
  "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`

```json
{
  "cart": {
    "lineItems": {
      "physicalItems": [
        {
          "id": "a01b7d1e-1111-4d1e-8f1a-2222bcaa9e00",
          "quantity": 8,
          "stockPosition": {
            "quantityOnHand": 5,
            "quantityBackordered": 3,
            "quantityOutOfStock": 0,
            "backorderMessage": ""
          }
        }
      ]
    }
  }
}
```

| Field                               | Description                                                        |
| ----------------------------------- | ------------------------------------------------------------------ |
| `stockPosition.quantityOnHand`      | Units from this line item ready to ship.                           |
| `stockPosition.quantityBackordered` | Units on backorder.                                                |
| `stockPosition.quantityOutOfStock`  | Units that exceeded backorder capacity.                            |
| `stockPosition.backorderMessage`    | Per-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](/developer/docs/overview/api-fundamentals/api-accounts#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 key                        | Source                                       | Description                                   |
| --------------------------------- | -------------------------------------------- | --------------------------------------------- |
| `availableOnHand`                 | `product.available_on_hand`                  | Physical on-hand quantity                     |
| `availableForBackorder`           | `product.available_for_backorder`            | Remaining backorder capacity                  |
| `availableToSell`                 | `product.available_to_sell`                  | Total sellable quantity (on-hand + backorder) |
| `unlimitedBackorder`              | `product.unlimited_backorder`                | Whether backorder limit is unlimited          |
| `showQuantityOnBackorder`         | `product.show_quantity_on_backorder`         | Display setting: show backordered quantity    |
| `showBackorderAvailabilityPrompt` | `product.show_backorder_availability_prompt` | Display setting: show availability prompt     |
| `backorderAvailabilityPrompt`     | `product.backorder_availability_prompt`      | The availability prompt text                  |
| `showBackorderMessage`            | `product.show_backorder_message`             | Display setting: show per-variant message     |
| `backorderMessages`               | `backorder_messages`                         | Map of backorder message objects              |
| `quantityBackorderedMessage`      | `products.quantity_backordered` lang key     | Template: "\{qty} will be backordered"        |
| `quantityMaxMessage`              | `products.quantity_max` lang key             | Template: "Max purchasable is \{qty}"         |
| `quantityMaxPicklistMessage`      | `products.quantity_max_picklist` lang key    | Template: "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`:

```handlebars
{{!-- 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](https://github.com/bigcommerce/cornerstone) repository:

| File                                              | What it does                                                                                              |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `templates/components/products/product-view.html` | Reads `product.backorder_availability_prompt` on the product detail page.                                 |
| `templates/components/cart/totals.html`           | Reads `cart.inventory_settings.default_shipping_expectation_prompt` in cart totals.                       |
| `assets/js/theme/common/product-details-base.js`  | Reads `backorder_availability_prompt` from the product attributes AJAX response during variant selection. |

## Catalyst reference implementation

[Catalyst](https://github.com/bigcommerce/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**

| File                                                              | What it does                                                                                                                                                                                         |
| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `core/app/[locale]/(default)/product/[slug]/page.tsx`             | Fetches 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.tsx` | Renders the availability prompt and dynamically computes "N will be on backorder" based on quantity input vs. on-hand stock.                                                                         |

**Cart**

| File                                        | What it does                                                                                                                    |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `core/app/[locale]/(default)/cart/page.tsx` | Fetches `stockPosition` on physical items. Builds per-line-item `inventoryMessages` with backordered quantity and message text. |
| `core/vibes/soul/sections/cart/client.tsx`  | Renders backorder messages per line item in the cart UI.                                                                        |

**Product cards**

| File                                                 | What it does                                                                                                        |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `core/data-transformers/product-card-transformer.ts` | `getInventoryMessage()` extracts the backorder message for products with zero on-hand but backorder capacity.       |
| `core/components/product-card/fragment.ts`           | GraphQL fragment fetching `availableForBackorder`, `unlimitedBackorder`, `availableOnHand`, and `backorderMessage`. |

**GraphQL fragments**

| File                                                      | What it fetches                                                                                         |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `core/components/product-variants-inventory/fragment.ts`  | Variant-level `backorderMessage` from `inventory.byLocation` for product detail page variant switching. |
| `core/app/[locale]/(default)/product/[slug]/page-data.ts` | `InventorySettingsQuery` for store-level display settings.                                              |

## Querying backorder data with Admin GraphQL

Use the [Admin GraphQL API](/developer/api-reference/graphql/admin/queries/client) to query inventory data including backorder fields at the product and variant level.

```graphql
{
  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](/developer/docs/integrations/webhooks/event-reference/inventory-and-location-events) for the full list of related webhook events.