Skip to main content

Split line items across fulfillment orders

When there isn't enough inventory at one location to fulfill the total quantity of ordered items, Shopify automatically splits the item across multiple fulfillment locations at checkout. This process prevents inventory levels from falling below zero at any location when an order requires fulfillment from multiple locations.

This guide describes how to support API integrations to accommodate this behavior.


Anchor to How might my app be impacted?How might my app be impacted?

API integrations that read FulfillmentOrders might be affected by the behavior of split fulfillment orders. If an app is designed to handle orders as if each inventory item can only contain a single fulfillment order, then it might not account for the full quantity needed for fulfillment.


Anchor to How split orders occurHow split orders occur

Split allocation in an order can occur under the following circumstances:

  • The store has multiple fulfillment locations for inventory items.

  • Fulfillable inventory is set to sell only within configured zones, in the Shipping and delivery settings page in the Shopify admin.

    Note

    If this option isn't available in the Shopify admin, then it means it's enabled by default.

  • There are products or product variants where continue selling when out of stock is deactivated.

  • A checkout is completed containing one of the above products or product variants with a quantity that is greater than can be fulfilled from a single location, but less than or equal to what is available in all locations.

  • Inventory from multiple locations will be used to fulfil the required quantity, resulting in an order with multiple fulfillment orders for the product variant.


Anchor to Which API endpoints are impacted?Which API endpoints are impacted?

If your app executes any of the following GraphQL Admin API queries and mutations that produce FulfillmentOrder objects, then your app might be affected by split orders behavior:

Similarly, if your app calls any of the following REST Admin API endpoints that produce FulfillmentOrder data, then your app might be affected by split orders behavior:


Anchor to Testing your API integrationTesting your API integration

To validate your app's compatibility with split orders, you need to ensure it can handle API responses where a line item is divided across multiple fulfillment orders within a single order. The specifics will vary depending on the API endpoints you are using. The following sections provide examples for both a GraphQL Admin API request and a REST Admin API request.

Anchor to GraphQL Admin API: Split fulfillment orders resultGraphQL Admin API: Split fulfillment orders result

The following example shows a request for the fulfillmentOrders query, which returns FulFillmentOrder objects for a given order.

The example shows two possible responses:

  • Response 1: All inventory has been allocated to a single location, so there is only a single fulfillment order.
  • Response 2: Inventory has been split across two locations. There are two fulfillment orders for the same inventory item. Both the InventoryItemId and the variant.id are identical. The lineItem.id differs, as does the assignedLocation information. You need to ensure that your app handles the second response correctly.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query {
order(id: "gid://shopify/Order/13489390190614") {
id
fulfillmentOrders(first: 3) {
edges {
node {
lineItems(first: 10) {
edges {
node {
id
inventoryItemId
variant {
id
}
remainingQuantity
}
}
}
assignedLocation {
location {
id
}
name
city
}
}
}
}
}
}

Response 1

{
"data": {
"order": {
"id": "gid://shopify/Order/13489390190614",
"fulfillmentOrders": {
"edges": [
{
"node": {
"lineItems": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrderLineItem/39204000006166",
"inventoryItemId": "gid://shopify/InventoryItem/52759046619158",
"variant": {
"id": "gid://shopify/ProductVariant/50717824155670"
},
"remainingQuantity": 2
}
}
]
},
"assignedLocation": {
"location": {
"id": "gid://shopify/Location/102336593942"
},
"name": "Store Location",
"city": "Brighton"
}
}
}
]
}
}
},
"extensions": {
"cost": {
"requestedQueryCost": 29,
"actualQueryCost": 10
}
}
}

Response 2

{
"data": {
"order": {
"id": "gid://shopify/Order/13489390190614",
"fulfillmentOrders": {
"edges": [
{
"node": {
"lineItems": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrderLineItem/39204000006166",
"inventoryItemId": "gid://shopify/InventoryItem/52759046619158",
"variant": {
"id": "gid://shopify/ProductVariant/50717824155670"
},
"remainingQuantity": 1
}
}
]
},
"assignedLocation": {
"location": {
"id": "gid://shopify/Location/102336593942"
},
"name": "Store Location",
"city": "Brighton"
}
}
},
{
"node": {
"lineItems": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrderLineItem/39204000038934",
"inventoryItemId": "gid://shopify/InventoryItem/52759046619158",
"variant": {
"id": "gid://shopify/ProductVariant/50717824155670"
},
"remainingQuantity": 1
}
}
]
},
"assignedLocation": {
"location": {
"id": "gid://shopify/Location/102435913750"
},
"name": "Warehouse location",
"city": "Edinburgh"
}
}
}
]
}
}
},
"extensions": {
"cost": {
"requestedQueryCost": 29,
"actualQueryCost": 10
}
}
}

Anchor to REST Admin API: Split fulfillment orders resultREST Admin API: Split fulfillment orders result

The following example shows a request to the /orders/:order_id/fulfillment_orders REST Admin API endpoint, which returns fulfillment order data for a given order.

The example shows two possible responses:

  • Response 1: All inventory has been allocated to a single location, so there is only a single fulfillment order.
  • Response 2: Inventory has been split across two locations. There are two fulfillment orders for the same inventory item. Both the inventory_item_id, the variant_id, and the line_item_id (the order's line item ID) are identical. The line_item.id differs, as does the assigned_location information. You need to ensure that your app handles the second response correctly.

GET https

cURL request

curl -X GET "https://{shop}.myshopify.com/admin/api/{api_version}/orders/13489390190614/fulfillment_orders.json" -H "X-Shopify-Access-Token: {access_token}"

Response 1

{
"fulfillment_orders": [
{
"id": 14820250812438,
"order_id": 13489390190614,
"assigned_location_id": 102336593942,
"line_items": [
{
"id": 39204000006166,
"fulfillment_order_id": 14820250812438,
"quantity": 2,
"line_item_id": 39179185127446,
"inventory_item_id": 52759046619158,
"fulfillable_quantity": 2,
"variant_id": 50717824155670,
...
}
],
"assigned_location": {
"city": "Brighton",
"location_id": 102336593942,
...
},
...
}
]
}

Response 2

{
"fulfillment_orders": [
{
"id": 14820250812438,
"order_id": 13489390190614,
"assigned_location_id": 102336593942,
"line_items": [
{
"id": 39204000006166,
"fulfillment_order_id": 14820250812438,
"quantity": 1,
"line_item_id": 39179185127446,
"inventory_item_id": 52759046619158,
"fulfillable_quantity": 1,
"variant_id": 50717824155670,
...
}
],
"assigned_location": {
"city": "Brighton",
"location_id": 102336593942,
...
},
...
},
{
"id": 14820250845206,
"order_id": 13489390190614,
"assigned_location_id": 102435913750,
"line_items": [
{
"id": 39204000038934,
"fulfillment_order_id": 14820250845206,
"quantity": 1,
"line_item_id": 39179185127446,
"inventory_item_id": 52759046619158,
"fulfillable_quantity": 1,
"variant_id": 50717824155670,
...
}
],
"assigned_location": {
"city": "Edinburgh",
"location_id": 102435913750,
...
},
...
}
]
}


Was this page helpful?