--- title: Manage inventory quantities and states description: Learn how to maintain accurate inventory quantities and transition products to different inventory states. source_url: html: https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states?itcat=partnersblog&itterm=editions md: https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states.md?itcat=partnersblog&itterm=editions --- ExpandOn this page * [Requirements](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#requirements) * [Inventory object relationships](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#inventory-object-relationships) * [Step 1: Retrieve IDs for inventory locations and inventory items](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#step-1-retrieve-ids-for-inventory-locations-and-inventory-items) * [Step 2: Query inventory quantities](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#step-2-query-inventory-quantities) * [Step 3: Manage inventory quantities](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#step-3-manage-inventory-quantities) * [Next steps](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#next-steps) # Manage inventory quantities and states This guide shows you how to use the GraphQL Admin API to sync and maintain accurate inventory quantities, and transition products to different inventory states. *** ## Requirements * Your app can make [authenticated requests](https://shopify.dev/docs/api/admin-graphql#authentication) to the GraphQL Admin API. * Your app has the `read_inventory` and `write_inventory` [access scopes](https://shopify.dev/docs/api/usage/access-scopes). Learn how to [configure your access scopes using Shopify CLI](https://shopify.dev/docs/apps/build/cli-for-apps/app-configuration). * Your store has existing [products](https://shopify.dev/docs/api/admin-graphql/latest/objects/Product). * You're familiar with the different [inventory states](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps#inventory-states). * You're using API version 2023-01 or higher. To [schedule changes to inventory quantities](#schedule-changes-to-inventory-quantities), you need to use API version 2024-01 or higher. *** ## Inventory object relationships Before you begin managing inventory quantities and states, it's helpful to understand the relationships between inventory objects. The following diagram illustrates the relationships between inventory objects in the GraphQL Admin API: ![The relationships between inventory objects in the GraphQL Admin API.](https://cdn.shopify.com/shopifycloud/shopify-dev/production/assets/assets/images/apps/fulfillments/inventory-management-apps/inventory-object-relationships-DC3ZFbQx.png) | API object | Description | | - | - | | [ProductVariant](https://shopify.dev/docs/api/admin-graphql/latest/objects/ProductVariant) | Contains merchandising information, such as price, description, and images. Think of this as the product information that you might want a customer to see. All product variants have a 1:1 relationship with their associated inventory item. | | [InventoryItem](https://shopify.dev/docs/api/admin-graphql/latest/objects/InventoryItem) | Contains information about the physical product, such as its SKU. Think of this as the backend information used for managing inventory, shipping, and fulfillments. Inventory items are associated with one or many inventory levels. An inventory item has an inventory level for each location where the item is stocked. | | [InventoryLevel](https://shopify.dev/docs/api/admin-graphql/latest/objects/InventoryLevel) | The actual `quantities` of an item that are in a specific [inventory state](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps#inventory-states). Inventory levels connect one inventory item to one location. Each inventory level holds the available quantity for its inventory item at the associated location. | | [Location](https://shopify.dev/docs/api/admin-graphql/latest/objects/Location) | A geographical location where a merchant does business, such as a retail store or warehouse. Locations can have many inventory levels. Each location has one inventory level for each inventory item that the location stocks. | *** ## Step 1: Retrieve IDs for inventory locations and inventory items You can use the [`locations`](#locations-query) query to retrieve the IDs of inventory locations and inventory items. To retrieve inventory at fulfillment service app locations, you need to use the [`shop`](#shop-query) query instead of the `locations` query. An inventory level represents the quantities of an inventory item that's associated with a location. An inventory item represents the goods that are available to be shipped to a customer. You'll use the IDs for inventory levels and inventory items to query inventory quantities in [the next step](#step-2-query-inventory-quantities). ### `locations` query The following example shows how to retrieve the first three locations and their associated inventory levels. The response returns a set of parameterized global IDs. Note The [`InventoryLevel`](https://shopify.dev/docs/api/admin-graphql/latest/objects/InventoryLevel) object has a global ID that contains parameters because the `InventoryLevel` object is associated with the [`InventoryItem`](https://shopify.dev/docs/api/admin-graphql/latest/objects/InventoryItem) object. For example, if the `InventoryLevel` object's ID is 69407473686 and the `InventoryItem` object's ID is 32889739542550, then the global ID resolves to the following structure: `gid://shopify/InventoryLevel/69407473686?inventory_item_id=32889739542550`. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL query ```graphql query { # Retrieves the first three locations on a shop. locations(first: 3) { edges { node { # The ID of the location. id # Retrieves the first three inventory levels associated with each location. inventoryLevels(first: 3) { edges { node { id } } } } } } } ``` ## JSON response ```json { "data": { "locations": { "edges": [ { "node": { "id": "gid://shopify/Location/35239591958", "inventoryLevels": { "edges": [ { "node": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32889739542550" } }, { "node": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32897608581142" } }, { "node": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32897615691798" } } ] } } }, { "node": { "id": "gid://shopify/Location/52187463702", "inventoryLevels": { "edges": [ { "node": { "id": "gid://shopify/InventoryLevel/86381920278?inventory_item_id=37774670364694" } }, { "node": { "id": "gid://shopify/InventoryLevel/86381920278?inventory_item_id=41360314695702" } } ] } } }, { "node": { "id": "gid://shopify/Location/35259777046", "inventoryLevels": { "edges": [ { "node": { "id": "gid://shopify/InventoryLevel/69427953686?inventory_item_id=32904089010198" } }, { "node": { "id": "gid://shopify/InventoryLevel/69427953686?inventory_item_id=37734050430998" } }, { "node": { "id": "gid://shopify/InventoryLevel/69427953686?inventory_item_id=37774670364694" } } ] } } } ] } } } ``` ### `shop` query The following example shows how to retrieve the first three fulfillment service app locations and their associated inventory levels. The response returns a set of parameterized global IDs. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL query ```graphql query { shop { # Retrieves inventory at fulfillment service app locations fulfillmentServices { location { # The ID of the location. id # Retrieves the first three inventory levels associated with each location inventoryLevels(first: 3) { edges { node { id } } } } } } } ``` ## JSON response ```json { "data": { "locations": { "edges": [ { "node": { "id": "gid:\/\/shopify\/Location\/35239591958", "inventoryLevels": { "edges": [ { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/69407473686?inventory_item_id=32889739542550" } }, { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/69407473686?inventory_item_id=32897608581142" } }, { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/69407473686?inventory_item_id=32897615691798" } } ] } } }, { "node": { "id": "gid:\/\/shopify\/Location\/52187463702", "inventoryLevels": { "edges": [ { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/86381920278?inventory_item_id=37774670364694" } }, { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/86381920278?inventory_item_id=41360314695702" } } ] } } }, { "node": { "id": "gid:\/\/shopify\/Location\/35259777046", "inventoryLevels": { "edges": [ { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/69427953686?inventory_item_id=32904089010198" } }, { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/69427953686?inventory_item_id=37734050430998" } }, { "node": { "id": "gid:\/\/shopify\/InventoryLevel\/69427953686?inventory_item_id=37774670364694" } } ] } } } ] } } } ``` ### `shop` query The following example shows how to retrieve the first three fulfillment service app locations and their associated inventory levels. The response returns a set of parameterized global IDs. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL query ```graphql query { shop { # Retrieves inventory at fulfillment service app locations fulfillmentServices { location { # The ID of the location. id # Retrieves the first three inventory levels associated with each location inventoryLevels(first: 3) { edges { node { id } } } } } } } ``` ## JSON response ```json { "data": { "shop": { "fulfillmentServices": [ { "location": { "id": "gid://shopify/Location/35239591958", "inventoryLevels": { "edges": [ { "node": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32889739542550" } }, { "node": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32897608581142" } }, { "node": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32897615691798" } } ] } } }, { "location": { "id": "gid://shopify/Location/67861446678", "inventoryLevels": { "edges": [] } } } ] } }, } ``` *** ## Step 2: Query inventory quantities You can use the following queries to retrieve inventory quantities: * [Query inventory quantities for an item at a specific location](#query-inventory-quantities-for-an-item-at-a-specific-location) * [Query inventory quantities for an item at multiple locations](#query-inventory-quantities-for-an-item-at-multiple-locations) ### Query inventory quantities for an item at a specific location You can use the [`inventoryLevel`](https://shopify.dev/docs/api/admin-graphql/latest/queries/inventoryLevel) query to retrieve inventory quantities for an item at a specific location. Each inventory level belongs to one inventory item and has one location. For every location where an inventory item can be stocked, there's an inventory level that represents the inventory item's quantities relating to that location. The following example query retrieves the quantity of an inventory item that's available at a specific location. The response shows 11 items that are available at the location. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL query ```graphql query { inventoryLevel(id:"gid://shopify/InventoryLevel/69407473686?inventory_item_id=32889739542550") { id # The quantities field takes an array of inventory states, which include the following: `incoming`, `on_hand`, `available`, `committed`, `reserved`, `damaged`, `safety_stock`, and `quality_control`. quantities(names: ["available"]) { name quantity } item { id } location { id } createdAt updatedAt canDeactivate } } ``` ## JSON response ```json { "data": { "inventoryLevel": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32889739542550", "quantities": [ { "name": "available", "quantity": 11 } ], "item": { "id": "gid://shopify/InventoryItem/32889739542550" }, "location": { "id": "gid://shopify/Location/35239591958" }, "createdAt": "2020-05-11T23:37:38Z", "updatedAt": "2020-08-28T05:57:20Z", "canDeactivate": false } } } ``` ### Query inventory quantities for an item at multiple locations You can use the [`inventoryItem`](https://shopify.dev/docs/api/admin-graphql/latest/queries/inventoryItem) query to retrieve inventory quantities for an item at multiple locations. The following example query retrieves the quantity of an inventory item that are available, on-hand, reserved, and committed at the first five locations. The response shows 72 available items, 101 on-hand items, 0 reserved items, and 29 committed items at the locations. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL query ```graphql { inventoryItem(id: "gid://shopify/InventoryItem/32889739542550") { # Retrieves the first five inventory levels. inventoryLevels(first: 5) { edges { node { # The quantities field takes an array of inventory states, which include the following: `incoming`, `on_hand`, `available`, `committed`, `reserved`, `damaged`, `safety_stock`, and `quality_control`. quantities(names: ["available", "on_hand", "reserved", "committed"]) { name quantity } } } } } } ``` ## JSON response ```json { "data": { "inventoryItem": { "inventoryLevels": { "edges": [ { "node": { "quantities": [ { "name": "available", "quantity": 72 }, { "name": "on_hand", "quantity": 101 }, { "name": "reserved", "quantity": 0 }, { "name": "committed", "quantity": 29 } ] } } ] } } } } ``` *** ## Step 3: Manage inventory quantities You can use the following mutations to manage inventory quantities: * [Set inventory quantities on hand](#set-inventory-quantities-on-hand): Explicitly set the quantity of inventory that's in the `available` or `on-hand` state. * [Adjust inventory quantities](#adjust-inventory-quantities): Add or remove quantities of inventory that are in the `available` state. * [Move inventory quantities between states](#move-inventory-quantities-between-states): Transition inventory quantities between the `available` state and the `reserved`, `damaged`, `safety_stock`, and `quality_control` states, or between unavailable states (`reserved`, `damaged`, `safety_stock`, and `quality_control`). * [Schedule changes to inventory quantities](#schedule-changes-to-inventory-quantities): Create a scheduled change that states the dates associated with upcoming changes to inventory quantities. Note You can't use the Admin API to adjust or move inventory quantities in the `committed` state. Inventory quantities in the `committed` state are only affected by the creation and fulfillment of a merchant's orders. ### Set inventory quantities on hand The `on_hand` state represents the total number of units that are physically stocked at a location. The `on_hand` state equals the sum of inventory quantities in the following states: * `available` * `committed` * `reserved` * `damaged` * `safety_stock` * `quality_control` You set inventory in the `on_hand` state to maintain an accurate count of physical inventory. For example, you might need to set inventory in the `on_hand` state in the following scenarios: * Inventory was received outside of a purchase order * A stocktake was completed and inventory needs to be adjusted accordingly You can use the [`inventorySetQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventorySetQuantities) mutation to set available and on-hand inventory quantities at a location to a given value. In the `reason` field in the mutation's input, you can specify one of the following reasons for adjusting inventory quantities: | Reason | Description | | - | - | | `correction` | Used to correct an inventory error or as a general adjustment reason. | | `cycle_count_available` | Used to specify an adjusted inventory count due to a discrepancy between the actual inventory quantity and previously recorded inventory quantity. | | `damaged` | Used to remove units from inventory count due to damage. | | `movement_created` | Used to specify that an inventory transfer or a purchase order has been created. | | `movement_updated` | Used to specify that an inventory transfer or a purchase order has been updated. | | `movement_received` | Used to specify that an inventory transfer or a purchase order has been received. | | `movement_canceled` | Used to specify that an inventory transfer or a purchase order has been canceled. | | `other` | Used to specify an alternate reason for the inventory adjustment. | | `promotion` | Used to remove units from inventory count due to a promotion or donation. | | `quality_control` | Used to specify that on-hand units that aren't sellable because they're currently in inspection for quality purposes. | | `received` | Used to specify inventory that the merchant received. | | `reservation_created` | Used to reserve, or temporarily set aside unavailable units. | | `reservation_deleted` | Used to remove the number of unavailable units that have been reserved. | | `reservation_updated` | Used to update the number of unavailable units that have been reserved. | | `restock` | Used to add a returned unit back to available inventory so the unit can be resold. | | `safety_stock` | Used to specify that on-hand units are being set aside to help guard against overselling. | | `shrinkage` | Used when actual inventory levels are less than recorded due to theft or loss. | The following example shows how to set the on-hand inventory quantity to 102. The response shows the delta of incrementing the on-hand inventory quantity by 1 because the previous inventory count in the `on_hand` state was 101. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation { inventorySetQuantities(input: { # Whether or not to ignore the `compareQuantity` field. This is false by default. ignoreCompareQuantity: "false", # The reason for adjusting the inventory quantity. reason: "correction", # A freeform URI that represents why the inventory change happened. This can be the entity adjusting inventory quantities or the Shopify resource that's associated with the inventory adjustment. For example, a unit in a draft order might have been previously reserved, and a merchant later creates an order from the draft order. In this case, the referenceDocumentUri for the inventory adjustment is the order ID. referenceDocumentUri: "gid://shopify/Order/1974482927638", # The input that's required to set the inventory quantity. quantities: [ { # The ID of the inventory item. inventoryItemId: "gid://shopify/InventoryItem/32889739542550", # The ID of the location where the inventory is stocked. locationId: "gid://shopify/Location/35239591958", # The quantity of inventory to set. quantity: 102 # The last known quantity of the item at the location. compareQuantity: 101 } ] } ) { inventoryAdjustmentGroup { id changes { name delta quantityAfterChange } reason referenceDocumentUri }, userErrors { message code field } } } ``` ## JSON response ```json { "data": { "inventorySetQuantities": { "inventoryAdjustmentGroup": { "id": "gid://shopify/InventoryAdjustmentGroup/32766566924310", "changes": [ { "name": "available", "delta": 1, "quantityAfterChange": null } ], "reason": "Inventory correction", "referenceDocumentUri": "gid://shopify/Order/1974482927638" }, "userErrors": [] } } } ``` ### Adjust inventory quantities You can use the [`inventoryAdjustQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryAdjustQuantities) mutation to increment or decrement the total amount of inventory that's in the `available`, `damaged`, `quality_control`, `reserved`, or `safety_stock` state at a location. For example, a merchant might need to adjust inventory quantities in the following cases: | State that needs adjustments | Use cases | | - | - | | `available` | * Inventory was received outside of a purchase order. * Inventory needs to be adjusted in alignment with a completed stocktake. | | `damaged` | - Inventory can't be sold due to damage. - Inventory isn't usable due to physical deterioration. | | `quality_control` | * Inventory isn't meeting a specified quality grade. * Inventory is being measured to meet quality standards. | | `reserved` | - Inventory that is on hold for a customer. - Inventory is being sent to a warehouse, but is not yet available. - Inventory is allocated to an order by a third-party logistics provider that Shopify is unaware of, which means that the inventory isn't in the `committed` state. | | `safety_stock` | * Inventory has an extra quantity that's being stored in a warehouse. * Inventory is being set aside to insure against fluctuations in demand. | The following example shows how to increase the quantity of available inventory units by 2 at a location. The response shows the delta of incrementing the available inventory quantity by 2. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation { inventoryAdjustQuantities(input: { # The inventory state to receive an adjustment. name: "available", # The reason for adjusting the inventory quantity of the specified state. reason: "correction", # A freeform URI that represents why the inventory change happened. This can be the entity adjusting inventory quantities or the Shopify resource that's associated with the inventory adjustment. For example, a unit in a draft order might have been previously reserved, and a merchant later creates an order from the draft order. In this case, the referenceDocumentUri for the inventory adjustment is the order ID. referenceDocumentUri: "gid://shopify/Order/1974482927638", # The adjustments to the inventory quantity. changes: [{ # The ID of the inventory item. inventoryItemId: "gid://shopify/InventoryItem/32889739542550", # The ID of the location where the inventory item is stocked. locationId: "gid://shopify/Location/35239591958", # The inventory adjustment. A positive number (for example, 2) indicates an increase in inventory quantities. A negative number (for example, -2) indicates a decrease in inventory quantities. delta: 2, }]}) { inventoryAdjustmentGroup { createdAt reason app { id } changes { name delta quantityAfterChange } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "inventoryAdjustQuantities": { "inventoryAdjustmentGroup": { "createdAt": "2022-11-18T00:59:15Z", "reason": "Inventory correction", "app": { "id": "gid://shopify/App/1830279" }, "changes": [ { "name": "available", "delta": 2, "quantityAfterChange": null } ] }, "userErrors": [] } } } ``` #### Using reference​Document​Uri for inventory traceability The `referenceDocumentUri` field is a freeform URI that indicates why and what caused an inventory change to happen. It's a powerful way to enable complete audit trails for inventory adjustments. `referenceDocumentUri` transforms inventory adjustments from a "black box" into a transparent system where you can trace every change back to its source. > **Note**: The main difference between a URL and a URI is that a URL specifies the location of a resource on the internet, while a URI can be used to identify any type of resource. All URLs are URIs, but not all URIs are URLs. In this context, you can use either URLs (like `https://myapp.com/order/12345`) or other URI formats (like `gid://myapp/Order/12345`). `referenceDocumentUri` is accepted on the GraphQL Admin API's [`inventoryAdjustQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryAdjustQuantities), [`inventorySetQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventorySetQuantities), and [`inventoryMoveQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryMoveQuantities) mutations. ##### Why use reference​Document​Uri? Using `referenceDocumentUri` provides the following for merchants: * Complete audit trail: Trace every inventory change back to the system and document that initiated it. * Context for changes: Understand not just what changed, but why it changed by linking to the specific business document or transaction. * Compliance requirements: Satisfy regulatory requirements with traceable inventory adjustments. * Quick troubleshooting: Instantly identify which system made each adjustment during discrepancy investigations. Using `referenceDocumentUri` provides the following for app devs: * Brand visibility: Your app name appears directly in the Shopify admin inventory history * Reduced support tickets: Merchants can self-serve by understanding which system made adjustments * Clear accountability: Connect each inventory change to its originating business logic, making it easier to debug and explain app behavior ##### Format specification While the `referenceDocumentUri` field accepts various formats including URLs, our preferred format is the Global ID (GID) format. For example: `gid://warehouse-app/PurchaseOrder/PO-2024-001` ```text gid://[namespace]/[entity]/[id] ``` You can add optional query parameters to include additional context like location, user, or timestamp: ```text gid://[namespace]/[entity]/[id]?location=west&user=12345 ``` ###### Where your URI appears The `referenceDocumentUri` is visible in two key places: 1. **Inventory adjustment history** - Merchants see your URI in the adjustment history page, providing immediate context for each change 2. **Analytics reports** - The new inventory adjustment reports in Analytics > Reports include your URI for comprehensive tracking ###### Benefits of using GID format * **Enhanced popover experience**: When using GID format (e.g., `gid://appName/PurchaseOrder/123456789`), Shopify automatically parses it to display a meaningful title in the adjustment history popover * **Consistent structure**: Uniform format across all your integrations * **Clear identification**: Namespace and entity are immediately recognizable * **Future-ready**: Better support for upcoming features and integrations ###### Examples of accepted formats * `gid://my-wms-app/PurchaseOrder/PO-2024-001` (Preferred GID format) * `gid://3pl-system/CycleCount/CC-2024-0125` (Preferred GID format) * `gid://pos-app/Transaction/TXN-STORE1-98765?location=west` (Preferred GID format with query parameter) * `gid://erp/StockAdjustment/ADJ-2024-001` (Preferred GID format) * `https://myapp.com/order/12345` (URL format - also accepted) * `id://appChange/12345` (Custom ID format - also accepted) ###### GID format validation regex (if using GID format) ```javascript const validGidFormat = /^gid:\/\/[^\/]+\/[^\/]+\/[^\/?]+(\?.*)?$/; const isValidGid = validGidFormat.test(yourUri); ``` ##### Integration examples Here are example `referenceDocumentUri` formats for common integration types: WMS (Warehouse Management System) Integration: * Purchase orders: `gid://warehouse-app/PurchaseOrder/PO-2024-001` * Stock transfers: `gid://warehouse-app/Transfer/TR-2024-1234` * Stock adjustments: `gid://warehouse-app/Adjustment/ADJ-2024-567` 3PL (Third-Party Logistics) Integration: * Cycle counts: `gid://3pl-system/CycleCount/CC-2024-0125` * Receiving: `gid://3pl-system/Receipt/REC-2024-789` * Returns processing: `gid://3pl-system/Return/RET-2024-012` POS (Point of Sale) Integration: * Sales transactions: `gid://pos-app/Transaction/TXN-STORE1-98765` * Stock takes: `gid://pos-app/StockTake/ST-STORE1-2024-03` * Transfers between stores: `gid://pos-app/Transfer/XFER-ST1-ST2-456` ERP Integration: * Sync jobs: `gid://erp-connector/SyncJob/SYNC-2024-11-21-001` * Stock adjustments: `gid://erp/StockAdjustment/ADJ-2024-001` * Manufacturing orders: `gid://erp/ManufacturingOrder/MO-2024-789` For complete mutation examples, see the [inventoryAdjustQuantities](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryAdjustQuantities), [inventorySetQuantities](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventorySetQuantities), and [inventoryMoveQuantities](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryMoveQuantities) reference documentation. ##### Best practices 1. Prefer GID format for consistency: While other formats are accepted, using GID format provides consistency and future compatibility 2. Use meaningful namespaces: Choose a namespace that clearly identifies your app or system (e.g., `warehouse-app`, `erp-connector`) 3. Use descriptive entity types: Make it clear what type of document caused the adjustment (e.g., `PurchaseOrder`, `CycleCount`, `StockTransfer`) 4. Include relevant metadata in IDs: Consider including dates, locations, or user information: * `gid://inventory-manager/SafetyStock/SS-2024-11-21-loc-456` * `gid://wms/Adjustment/ADJ-2024-11-21-user-123` 5. Maintain consistency: Use the same format across all your integrations for easier troubleshooting 6. Document your URIs: Keep internal documentation of your URI patterns for support teams ##### Migrating existing integrations To add `referenceDocumentUri` to your existing integrations: 1. Audit current usage: Review your existing inventory adjustment code to identify where `referenceDocumentUri` is missing or incorrectly formatted 2. Plan your namespace: Choose a consistent namespace for your app (avoid generic names like "app" or "system") 3. Update incrementally: You don't need to update all your code at once. Start with new features and high-volume adjustments 4. Common migration patterns to GID format (recommended but not required): ```javascript // Old: No referenceDocumentUri referenceDocumentUri: undefined // Using URLs (still supported) referenceDocumentUri: "https://myapp.com/order/12345" // Recommended: Convert to GID format for consistency referenceDocumentUri: "gid://myapp/Order/12345" // Old: Using the app ID directly referenceDocumentUri: "gid://shopify/App/123456" // Recommended: Use meaningful references referenceDocumentUri: "gid://myapp/StockAdjustment/ADJ-2024-001" ``` 5. Test thoroughly: Verify that your new URIs are accepted by the API and appear correctly in merchant inventory histories For examples of using `referenceDocumentUri` with inventory mutations, see: * [inventoryAdjustQuantities examples](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryAdjustQuantities#examples) * [inventorySetQuantities examples](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventorySetQuantities#examples) * [inventoryMoveQuantities examples](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryMoveQuantities#examples) ### Move inventory quantities between states You can use the [`inventoryMoveQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryMoveQuantities) mutation to transition inventory quantities between the `available` state and the `reserved`, `damaged`, `safety_stock`, and `quality_control` states, or between unavailable states (`reserved`, `damaged`, `safety_stock`, and `quality_control`). For example, a merchant might need to move inventory quantities between states in the following cases: | From state | To state | Description | | - | - | - | | `available` | `reserved` | Inventory is currently being inspected or repaired. Use draft orders instead of moving inventory manually. If a merchant is using Shopify POS and needs to set inventory aside for a customer, then you should use a draft order rather than manually moving inventory to the `reserved` state. | | `available` | `damaged` | A third-party logistics provider finds and reports damaged inventory. | | `available` | `safety_stock` | Inventory is being set aside to insure against fluctuations in demand. | | `available` | `quality_control` | Inventory is being measured to meet quality standards. | | `reserved` | `available` | A stocktake was completed and inventory needs to be adjusted accordingly. | | `damaged` | `available` | A previously damaged inventory unit that was set aside has been repaired. | | `safety_stock` | `available` | Extra inventory is available to help with fluctuations in demand. | | `quality_control` | `available` | An inventory unit has met quality standards and is ready to be sold. | Note Inventory quantities in a `reserved`, `damaged`, `safety_control`, or `quality_control` state display as **Unavailable** to merchants that are tracking inventory in the Shopify admin. The following example shows how to move a quantity of 2 inventory units from the `available` to the `reserved` state. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation { inventoryMoveQuantities(input: { # The reason for moving a certain quantity of inventory units to a different state. reason: "correction", # A freeform URI that represents why the inventory change happened. This can be the entity adjusting inventory quantities or the Shopify resource that's associated with the inventory adjustment. For example, a unit in a draft order might have been previously reserved, and a merchant later creates an order from the draft order. In this case, the referenceDocumentUri for the inventory adjustment is the order ID. referenceDocumentUri: "uri://example.com/some/external/reference", # The movement of quantities between inventory states changes: [{ inventoryItemId: "gid://shopify/InventoryItem/32889739542550", from: { # The state that you want to move the inventory quantities from. Valid values: `available`, `reserved`, `damaged`, `safety_stock`, or `quality_control`. name: "available", # The location where the inventory is stocked. locationId: "gid://shopify/Location/35239591958", } to: { # The state that you want to move the inventory quantities to.Valid values: `available`, `reserved`, `damaged`, `safety_stock`, or `quality_control`. name: "reserved", # The ID of the location where the inventory is stocked. locationId: "gid://shopify/Location/35239591958", # A freeform URI that represents what changed the inventory quantities. This reference can't be a Shopify global ID (for example, "gid://shopify/Order/123"). This field is used only inside the `from` and / or `to` input when the quantity name isn't "available". ledgerDocumentUri: "uri://example.com/some/external/reference" } # The quantity of inventory units that you want to move to a different state. quantity: 2 }]}) { inventoryAdjustmentGroup { createdAt reason app { id } changes { name delta quantityAfterChange } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "inventoryMoveQuantities": { "inventoryAdjustmentGroup": { "createdAt": "2022-11-18T21:06:46Z", "reason": "Inventory correction", "app": { "id": "gid://shopify/App/1830279" }, "changes": [ { "name": "available", // The available inventory quantity is decremented by 2. "delta": -2, // This field always returns `null` immediately after running the mutation. The value of this field is available only after all written adjustments and moves have been processed. "quantityAfterChange": null }, { "name": "reserved", // The reserved inventory quantity is incremented by 2. "delta": 2, // This field always returns `null` immediately after running the mutation. The value of this field is available only after all written adjustments and moves have been processed. "quantityAfterChange": null } ] }, "userErrors": [] } } } ``` ### Schedule changes to inventory quantities You can schedule changes to inventory quantities using the [`InventorySetScheduledChanges`](https://shopify.dev/docs/api/admin-graphql/2024-01/mutations/InventorySetScheduledChanges) mutation. This involves defining the dates associated with upcoming changes to inventory quantities. For example, if an app user creates a purchase order and adds incoming quantities for a specified inventory item at a location, then they can also create a scheduled change that states the date that the quantities are expected to be transitioning from `incoming` to `available`. Information about scheduled changes to inventory quantities can help merchants make better buying or selling decisions. Note The [`InventorySetScheduledChanges`](https://shopify.dev/docs/api/admin-graphql/2024-01/mutations/InventorySetScheduledChanges) mutation won't automatically change inventory quantities. To change inventory quantities, you still need to use other inventory mutations, such as [`InventoryAdjustQuantitites`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryAdjustQuantities), [`inventorySetQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventorySetQuantities), or [`inventoryMoveQuantities`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/inventoryMoveQuantities). The following example shows how to create a scheduled change that defines the date that quantities are expected to be transitioning from `incoming` to `available`. ## POST https\://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation inventorySetScheduledChanges { inventorySetScheduledChanges(input: { # The reason for moving a certain quantity of inventory units to a different state. reason: "correction", items: [ { # The ID of the inventory item. inventoryItemId: "gid://shopify/InventoryItem/32889739542550", # The ID of the location where the inventory is stocked. locationId: "gid://shopify/Location/35239591958", # A freeform URI that represents what changed the inventory quantities. This reference can't be a Shopify global ID (for example, "gid://shopify/Order/123"). This field is used only inside the `from` and / or `to` input when the quantity name isn't "available". ledgerDocumentUri: "uri://example.com/some/external/reference", # An array that defines the date that the quantities are expected to be transitioning from one state to another. For example, from `incoming` to `available`. scheduledChanges: [ { expectedAt: "2023-12-11T23:37:38Z" fromName: "incoming", toName: "available" } ] } ], # A freeform URI that represents why the inventory change happened. This can be the entity adjusting inventory quantities or the Shopify resource that's associated with the inventory adjustment. For example, a unit in a draft order might have been previously reserved, and a merchant later creates an order from the draft order. In this case, the referenceDocumentUri for the inventory adjustment is the order ID. referenceDocumentUri: "uri://example.com/some/external/reference" }) { scheduledChanges { expectedAt fromName toName quantity ledgerDocumentUri inventoryLevel { id item { variant { id displayName } } location { name id } } } userErrors { message field } } } ``` ## JSON response ```json { "data": { "inventorySetScheduledChanges": { "scheduledChanges": [ { "expectedAt": "2023-12-11T23:37:38Z", "fromName": "incoming", "toName": "available", "quantity": 4, "ledgerDocumentUri": "uri://example.com/some/external/reference", "inventoryLevel": { "id": "gid://shopify/InventoryLevel/69407473686?inventory_item_id=32889739542550", "item": { "variant": { "id": "gid://shopify/ProductVariant/31365818744854", "displayName": "French Bulldog on a swing" } }, "location": { "name": "180 Switchmen Street", "id": "gid://shopify/Location/35239591958" } } } ], "userErrors": [] } }, "extensions": { "cost": { "requestedQueryCost": 14, "actualQueryCost": 14, "throttleStatus": { "maximumAvailable": 1000.0, "currentlyAvailable": 986, "restoreRate": 50.0 } } } } ``` *** ## Next steps * Learn about other [types of fulfillment apps](https://shopify.dev/docs/apps/build/orders-fulfillment) that you can create to integrate into order management, fulfillment, and returns workflows. *** * [Requirements](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#requirements) * [Inventory object relationships](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#inventory-object-relationships) * [Step 1: Retrieve IDs for inventory locations and inventory items](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#step-1-retrieve-ids-for-inventory-locations-and-inventory-items) * [Step 2: Query inventory quantities](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#step-2-query-inventory-quantities) * [Step 3: Manage inventory quantities](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#step-3-manage-inventory-quantities) * [Next steps](https://shopify.dev/docs/apps/build/orders-fulfillment/inventory-management-apps/manage-quantities-states#next-steps)