Fulfillable location ID in Order API

Hi all,

I have a question regarding the REST API for Orders, or it is more a ‘feature request’ :wink:

It came to my attention that the fulfillable location is not in the JSON output of the API for an order.

So when an order is placed the unfulfilled items are listed in the order detail page. You can change the fulfillable location if you want. It would be very nice if it is possible to put this fulfillable location id in the JSON of the order (in the line_items section since an order can be fulfilled from 2 locations).

So when we fulfil the order through the API that we know what the current value is and we can just use this value directly in the fulfillment API request.

Thanks!

4 Likes

+1 for this!

Just got a request for it recently from a customer of one of our apps.

+1 ! Any update on this ?

In the graphql api there is the “DraftFulfillment” and we can get the location from “service.location” but the location name is different from the one shown on the order =/

Any update here?

Since its sortable and can be updated via UI, one would think it should be possible to access via API. Based on some research and checking the json payload, this doesn’t seemed solved yet, hoping I’m wrong.

1 Like

Is there a solution for this? Is this solved?

There has been a solution to this for awhile now. Either through the REST API (https://shopify.dev/docs/admin-api/rest/reference/inventory/inventorylevel?api[version]=2020-07), or the GraphQL API. You can get all of the information in one shot a lot easier through the GraphQL API in my opinion at least. So here’s an example where you can query the API for a product variant and see fulfillable quantities at up to 10 fulfillment locations.

{
  productVariant(id: "gid://shopify/ProductVariant/31512998182964") {
    title
    id
    product {
      title
    }
    inventoryItem {
      id
      inventoryLevels(first: 10) {
        edges {
          node {
            id
            available
            location {
              id
              name
              address {
                address1
                address2
                city
                province
                country
                phone

              }
            }
          }
        }
      }
    }
  }
}

Hmm I don’t believe this actually solves the current issue @Gregarican . If the specific Item has inventory at 2 locations both of these locations will appear in the Inventory Levels response. There doesn’t seem to be a way to get the location_id for what is selected from the dropdown.

If I’m mistaken, please let me know. I ran through the endpoints quickly with Postman to confirm. Product_variant → Inventory_item → Inventory_levels

So you actually tried the GraphQL example that I provided? It displays the id (i.e. - the location_id) and the name (i.e. - the display name, like in the Shopify web admin dropdown) in the results. I’ll paste the raw data for the GraphQL API response that I received when I tried it. You can install the Shopify GraphiQL App as an app on a production store, test store, development store, etc. and test out API requests. It’s pretty useful for learning how it works.

Specifically below, the

“location”: {
“id”: “gid://shopify/Location/203128”,
“name”: “Sawmill”,

is what you are looking for. In above, the 203128 is the location_id and Sawmill is the display name. Can’t be much plainer than that?

{
  "data": {
    "productVariant": {
      "title": "Default Title",
      "id": "gid://shopify/ProductVariant/31512998182964",
      "product": {
        "title": "\"Be Own Kind of Beautiful\" Cuff"
      },
      "inventoryItem": {
        "id": "gid://shopify/InventoryItem/33055390433332",
        "inventoryLevels": {
          "edges": [
            {
              "node": {
                "id": "gid://shopify/InventoryLevel/4232978?inventory_item_id=33055390433332",
                "available": 2,
                "location": {
                  "id": "gid://shopify/Location/203128",
                  "name": "Sawmill",
                  "address": {
                    "address1": "6280 Sawmill Road",
                    "address2": "",
                    "city": "Dublin",
                    "province": "Ohio",
                    "country": "United States",
                    "phone": ""
                  }
                }
              }
            },
            {
              "node": {
                "id": "gid://shopify/InventoryLevel/17069604926?inventory_item_id=33055390433332",
                "available": 0,
                "location": {
                  "id": "gid://shopify/Location/17431658558",
                  "name": "Easton",
                  "address": {
                    "address1": "3960 New Bond Street",
                    "address2": "",
                    "city": "Columbus",
                    "province": "Ohio",
                    "country": "United States",
                    "phone": ""
                  }
                }
              }
            },
            {
              "node": {
                "id": "gid://shopify/InventoryLevel/17069637694?inventory_item_id=33055390433332",
                "available": 0,
                "location": {
                  "id": "gid://shopify/Location/17431691326",
                  "name": "Weber",
                  "address": {
                    "address1": "1523 East 15th Street",
                    "address2": "",
                    "city": "Tulsa",
                    "province": "Oklahoma",
                    "country": "United States",
                    "phone": ""
                  }
                }
              }
            }
          ]
        }
      }
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 35,
      "actualQueryCost": 14,
      "throttleStatus": {
        "maximumAvailable": 1000,
        "currentlyAvailable": 986,
        "restoreRate": 50
      }
    }
  }
}

Appreciate the response @Gregarican , I used the rest endpoints for my test.

the solution you described returns all the locations that a specific product_variant has inventory at.

What we are looking for is how to get the location_id for the selected dropdown location by only using the API.

Example using the data you provided

If in the Shopify UI we had selected Sawmill from the dropdown of an unfulfilled order, how would we be able to determine that from the response? The return has 3 different locations.

We need some way to get ether the name of the location, which can then be used to find the location_id from all the locations of the shop, or we need a reference_location_id that directly points to the location that is used for the dropdown on the unfulfilled order.

Please let me know if any piece is unclear. Happy to dive into more details.

Cheers

I thought you were looking to retrieve all of the location ID’s and display names for a variant that’s stocked. If you are just looking to pull any/all locations with their ID’s and display names, then this is also something possible using the Shopify GraphQL API.

Here’s a query. First 10 locations with this information:

{
    locationsAvailableForDeliveryProfilesConnection (first: 10) {
        edges {
            node {
                id
                name
            }
        }
    }
}

And here was the response that I got back:

{
  "data": {
    "locationsAvailableForDeliveryProfilesConnection": {
      "edges": [
        {
          "node": {
            "id": "gid://shopify/Location/203128",
            "name": "Sawmill"
          }
        },
        {
          "node": {
            "id": "gid://shopify/Location/17431658558",
            "name": "Easton"
          }
        },
        {
          "node": {
            "id": "gid://shopify/Location/17431691326",
            "name": "Weber"
          }
        },
        {
          "node": {
            "id": "gid://shopify/Location/18763743294",
            "name": "Green Hills"
          }
        }
      ]
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 12,
      "actualQueryCost": 6,
      "throttleStatus": {
        "maximumAvailable": 1000,
        "currentlyAvailable": 994,
        "restoreRate": 50
      }
    }
  }
}

So translating this to the Shopify web admin, if I were to pull down Sawmill in the location dropdown, this would map to location_id 203128 in the API. Does this make more sense?

@Gregarican In our case we have 2 locations. Whenever a new order arrives, shopify is automatically assigning the location to be used for fulfillment which is great. However, we want to get this information using REST or GraphQL, wow do we do that? Also unlike @PatrickWatzeels we are not getting the drop down to update the location, is there some setting we need to do for this?

Hey @browntaped , Sounds like we are encountering the same issues regarding getting the specified location from the rest endpoint. Based on other forums, I don’t believe this is possible yet. https://community.shopify.com/c/Shopify-APIs-SDKs/Get-Location-Id-of-the-item-on-the-order-that-shopify-used-via/td-p/526033

In terms of the getting the dropdown to appear, you need to have multiple locations on your shop and you need to have more then 1 location on the item.

1 Like

@Lasvad Yes, you are right! multiple locations need to carry the inventory and for such products I am able to see the drop down. Thank you for the information.

With respect to getting the location, we have been spending lot of time in figuring out. Unfortunately shopify support has not been helpful and they keep referring us to the developer community and as you mentioned there seems to be no solution for this :disappointed_face:

From my end, I don’t know what other assistance I can offer. I provided two specific functional examples — one example listing all location ID’s and display names that can stock a specified product variant, another example listing any/all location ID’s defined for a shop along with their display names. These examples utilize the Shopify GraphQL API not the Shopify REST API. But nevertheless it’s a means to an end.

+1 for this feature.

1 Like

I posted about this myself here before finding this thread.

I think the original poster and others in this thread articulated it slightly better than myself. I really think this is quite a large hole in the fulfilment/inventory API implementations as it makes it very difficult or impossible to create or manage complex fulfillments from multiple locations from within an app.

It would be great if the community could get more clarity on how things like this can be achieved.

I still don’t understand what the gap is. Below is a GraphQL request example. I have an order that hasn’t been fulfilled. But should be pulled from the Sawmill location based on what the order shows in the Shopify web admin.

{
  order(id: "gid://shopify/Order/2645786329250") {
    lineItems(first: 10) {
      edges {
        node {
          fulfillmentService {
            location {
              id
              name
            }
          }
        }
      }
    }
  }
}
{
  "data": {
    "order": {
      "lineItems": {
        "edges": [
          {
            "node": {
              "fulfillmentService": {
                "location": {
                  "id": "gid://shopify/Location/203128",
                  "name": "Sawmill"
                }
              }
            }
          }
        ]
      }
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 33,
      "actualQueryCost": 6,
      "throttleStatus": {
        "maximumAvailable": 1000,
        "currentlyAvailable": 994,
        "restoreRate": 50
      }
    }
  }
}

If I look up the order in the Shopify web admin, the UI shows that its origin location is Sawmill. And that’s what the GraphQL response shows as well.

Okay so here’s an example with two locations. In this example Order there’s three line items, according to the page for this order the first two items are coming from Test Location 1 and the third item is coming from Test Location 2.

Using a similar query to yours, here’s the response:

{
  "id": "gid://shopify/Order/2672195043493",
  "lineItems": {
    "edges": [
      {
        "node": {
          "id": "gid://shopify/LineItem/5841433886885",
          "sku": "Tool - Ice 15mm Wrench",
          "quantity": 1,
          "fulfillmentService": {
            "location": {
              "id": "gid://shopify/Location/50193891493",
              "name": "Test Location 1"
            }
          }
        }
      },
      {
        "node": {
          "id": "gid://shopify/LineItem/5841433919653",
          "sku": "Tool - Park Balldriver 456",
          "quantity": 1,
          "fulfillmentService": {
            "location": {
              "id": "gid://shopify/Location/50193891493",
              "name": "Test Location 1"
            }
          }
        }
      },
      {
        "node": {
          "id": "gid://shopify/LineItem/5841433952421",
          "sku": "Aerospoke - Lime Green Front",
          "quantity": 1,
          "fulfillmentService": {
            "location": {
              "id": "gid://shopify/Location/50193891493",
              "name": "Test Location 1"
            }
          }
        }
      }
    ]
  }

The location in the response is always Test Location 1. What is the preferred method for getting the Location that Shopify is actually showing me in the admin?

This becomes even more challenging when a single line item has it’s quantities split across two locations.

I see what you mean now. My apologies for being dense, in that my examples included items which were only currently stocked at one particular location. Since our dummy data set is like our production set for the most part. Almost all serialized one-of-a-kind items. For a test I stocked that item at several locations and created an order in the Shopify web admin. As you can see it should be pulled from our Easton location per the UI.

Yet when I query this order in GraphQL, it shows one of the other stock site locations as the fulfillment point.

Unless I’m missing something, this definitely appears to be a bug. Can anyone from Shopify chime in with some insight or feedback?

No need to apologise, it’s counter intuitive. I think it’s clear that this is either a bug or an oversight in the API.

Or maybe Shopify intends us to handle this in a different way that isn’t well documented anywhere. Either way it would be nice to find out as myself and others have all had similar requests from clients that it appears (at least at this point) to be impossible to implement.