Set stock levels from an external system

Overwrite available stock per item and location with inventorySetQuantities, using changeFromQuantity and an idempotency key as 2026-10 requires.

API
Admin GraphQL API
Operation
inventorySetQuantities
Access scope
write_inventory
Replaces (REST)
POST /admin/api/inventory_levels/set.json
API version
2026-10
Last checked

In short

To set stock from an ERP or warehouse system, call inventorySetQuantities with name available (or on_hand), a reason such as correction, and a list of quantities per inventory item and location. From 2026-04, each quantity needs changeFromQuantity (the value you expect Shopify to have, or null to skip the check) and the mutation needs an @idempotent key.

How to use it

  1. Look up the inventory item IDs (on each variant’s inventoryItem) and the location IDs once, and store them next to your SKUs.
  2. For each item, send the new quantity and the quantity you last saw as changeFromQuantity.
  3. Generate a new idempotency key (a UUID) per change and pass it with @idempotent. Retry a failed request with the same key.
  4. If userErrors returns CHANGE_FROM_QUANTITY_STALE, read the current level and decide again instead of forcing the value.

Code

inventory-set-quantities.graphql
mutation SetStock($input: InventorySetQuantitiesInput!, $idempotencyKey: String!) {
  inventorySetQuantities(input: $input) @idempotent(key: $idempotencyKey) {
    inventoryAdjustmentGroup {
      reason
      referenceDocumentUri
      changes {
        name
        delta
        quantityAfterChange
      }
    }
    userErrors {
      code
      field
      message
    }
  }
}
inventory-set-quantities.variables.json
{
  "idempotencyKey": "6f1c2b9e-3d4a-4f7e-9b1a-2c3d4e5f6a7b",
  "input": {
    "name": "available",
    "reason": "correction",
    "referenceDocumentUri": "gid://your-erp/StockSync/2026-11-02-0900",
    "quantities": [
      {
        "inventoryItemId": "gid://shopify/InventoryItem/1111111111",
        "locationId": "gid://shopify/Location/1234567890",
        "quantity": 12,
        "changeFromQuantity": 10
      },
      {
        "inventoryItemId": "gid://shopify/InventoryItem/1111111112",
        "locationId": "gid://shopify/Location/1234567890",
        "quantity": 0,
        "changeFromQuantity": 3
      }
    ]
  }
}
inventory-set-quantities.response.json
{
  "data": {
    "inventorySetQuantities": {
      "inventoryAdjustmentGroup": {
        "reason": "Inventory correction",
        "referenceDocumentUri": "gid://your-erp/StockSync/2026-11-02-0900",
        "changes": [
          {
            "name": "available",
            "delta": 2,
            "quantityAfterChange": null
          },
          {
            "name": "on_hand",
            "delta": 2,
            "quantityAfterChange": null
          },
          {
            "name": "available",
            "delta": -3,
            "quantityAfterChange": null
          },
          {
            "name": "on_hand",
            "delta": -3,
            "quantityAfterChange": null
          }
        ]
      },
      "userErrors": []
    }
  }
}

Written by Lintel. MIT license: free to use in your own store and in client work.

Limits and edge cases

  • name accepts only available or on_hand. Setting available also moves on_hand by the same delta.
  • reason must be one of Shopify’s values, such as correction, cycle_count_available, received or restock. referenceDocumentUri shows in the inventory history.
  • Use this only when your system is the source of truth. For relative changes, such as a sale in another channel, use inventoryAdjustQuantities.
  • Passing changeFromQuantity: null turns the check off; concurrent updates can then overwrite each other.

Questions

How do I update inventory in Shopify with GraphQL?
Use inventorySetQuantities to set an absolute number, or inventoryAdjustQuantities to add or remove units. Both work per inventory item and location.
What is changeFromQuantity?
The quantity you expect Shopify to have before your change. If it differs, the update is rejected, so a sale that happened in between isn’t lost.
Why do I get an idempotency key error?
From API version 2026-04 the mutation requires @idempotent(key: ...). Use a new key per change and the same key when retrying it.
Where do I find the inventory item ID?
Each variant has an inventoryItem with its own ID. Query productVariants or the variant by ID and select inventoryItem { id }.
  • Validated against the Admin or Storefront API schema for version 2026-10 on the date shown. Check the version in your request URL.
  • IDs and store addresses in the examples are placeholders. Replace them with your own.
  • Admin API calls need an access token from your app. Never put an Admin API token in a storefront or theme.
  • MIT license. Use the code in your own store or in client work.

Need this built, tested and maintained for your store? See API integrations.

Have something to build? Let’s talk it through.

Taking a limited number of projects at a time. Every brief is read by an engineer, not a salesperson.

Gencer KarakayaShopify Engineer

An engineer reads your brief, and we reply by email.