If you need to retrieve specific item data using a product ID in Shopify, the best method depends on where you are working. Use the Admin REST API for a simple single-product fetch, use the GraphQL Admin API for flexible or batched queries, and only use Liquid workarounds in themes when you cannot call an API.
I have run into this exact problem many times while building Shopify apps and internal merchant tools. A merchant has a numeric product ID, or a workflow outputs a product reference, and the next step is always the same: get the title, variants, images, tags, inventory-related fields, or metafields for that one product without messing about with handles or manual exports.
The problem is that Shopify still treats this differently depending on whether you are in Liquid, Shopify Flow, REST, or GraphQL. That is why a lot of older tutorials feel incomplete. In this guide, I will show the current best-practice options in 2026, explain the difference between numeric IDs and GraphQL GIDs, and give you working examples you can actually use.
What is the best way to retrieve product data by product ID in Shopify?
The best way to retrieve product data by product ID in Shopify is to use the Admin API. REST is simplest for one product, while GraphQL is better for multiple products, selective fields, and app development.
If you are building a private tool, custom app, or backend integration, I would start with the Shopify Admin REST API for a single fetch and switch to the Admin GraphQL API when I need better efficiency. In my experience building Shopify apps, GraphQL scales better once you need more than one product or want to avoid over-fetching data.
| Method | Best for | ID format | Pros | Limitations |
|---|---|---|---|---|
| Admin REST API | Fetching one product by numeric ID | Numeric ID | Simple, predictable, easy to test | Less efficient for complex or batched queries |
| Admin GraphQL API | Apps, automations, multiple products, selective fields | GraphQL GID | Flexible, efficient, modern | Slightly steeper learning curve |
| Shopify Flow | No-code workflows inside Shopify | Usually query/filter based | Good for automation | Not as direct as writing API code |
| Liquid | Theme-only workarounds | Numeric ID in loops | No external app required | Limited and inefficient |
| Storefront API | Public storefront product data | GraphQL GID | Useful for headless storefronts | Cannot access private admin-only fields |
How do Shopify product IDs actually work?
Shopify product IDs come in two common formats: a numeric legacy ID and a GraphQL global ID called a GID. You need the right format for the API you are using.
This trips people up all the time. A product might have a numeric ID like 8258451439839, but GraphQL expects something like gid://shopify/Product/8258451439839. Shopify documents this in its guide to global IDs, and it matters because the wrong format will return nothing or throw an error.
As a rule of thumb, REST uses numeric IDs and GraphQL uses GIDs. If you are passing data between systems, convert carefully and keep track of which format you store.
| ID type | Example | Used in |
|---|---|---|
| Numeric product ID | 8258451439839 |
REST API, Liquid comparisons, admin URLs |
| GraphQL GID | gid://shopify/Product/8258451439839 |
Admin GraphQL API, Storefront GraphQL API |
How do I find a Shopify product ID?
You can find a Shopify product ID in the admin URL, via the product JSON, or through the API. The admin URL is usually the quickest option.
Open a product in your Shopify admin and look at the URL in your browser. In most cases, the product ID appears after /products/. This is the numeric ID you would use with the REST Admin API.
You can also inspect product data via API responses or JSON outputs when available. If you are working with feeds and identifiers more broadly, my guides on finding your product feed RSS URL and getting UPC codes for your Shopify store are useful companion reads.
Where can I find the GraphQL product GID?
You can find the GraphQL product GID by querying the product through GraphQL or by converting the numeric ID into the GID format. The pattern is consistent and easy to generate.
If your numeric ID is 8258451439839, the GID is simply gid://shopify/Product/8258451439839. In app code, I often generate this string directly when I already have the numeric ID and need to call GraphQL next.
How do I retrieve a product by ID with the Shopify REST Admin API?
The Shopify REST Admin API lets you fetch a single product by numeric ID with a simple GET request. This is the fastest route for one known product.
If your use case is straightforward, REST is still very practical. You send a request to the product endpoint, include an access token with the read_products scope, and Shopify returns the full product object. That includes title, body_html, vendor, product_type, tags, images, options, and variants.
Shopify has shifted more developer attention towards GraphQL, but for a one-off product lookup, I still find REST easier to debug. It is especially handy when building internal scripts or support tools for merchants.
REST endpoint for a single product
The REST endpoint for a single product is GET /admin/api/{version}/products/{product_id}.json. Replace the version and product ID with your own values.
GET https://your-store.myshopify.com/admin/api/2024-04/products/8258451439839.json
REST example in JavaScript
This JavaScript example fetches a product using its numeric Shopify product ID. It returns the full product object if the ID exists and your token has permission.
const productId = '8258451439839';
const response = await fetch(`https://your-store.myshopify.com/admin/api/2024-04/products/${productId}.json`, {
method: 'GET',
headers: {
'X-Shopify-Access-Token': 'your-access-token',
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();
console.log(data.product);
What data does the REST product endpoint return?
The REST product endpoint returns a full product object, including title, handle, images, variants, and other core catalogue fields. It is comprehensive, which is useful but sometimes more data than you need.
If all you want is a title and one image URL, REST can feel a bit heavy compared with GraphQL. Still, for support scripts and merchant tooling, that extra payload is often acceptable because implementation time matters too.
How do I retrieve a product by ID with the Shopify GraphQL Admin API?
The Shopify GraphQL Admin API is the best option for modern app development. It lets you request only the fields you need and can fetch single or multiple products efficiently.
In my own apps, I default to GraphQL when performance and flexibility matter. It reduces payload size, makes batching possible, and fits better with the direction Shopify has clearly taken across its platform. Shopify's Admin GraphQL docs are the right starting point if you want the official field reference: product query docs and products query docs.
Using productByIdentifier for a single product
productByIdentifier is a clean way to retrieve a single product by ID in newer GraphQL API versions. It is ideal when you already know the exact product identifier.
query {
productByIdentifier(identifier: {id: "gid://shopify/Product/8258451439839"}) {
id
title
handle
featuredImage {
url
}
variants(first: 10) {
nodes {
id
title
price
}
}
}
}
This is one of the most useful updates for this topic because it aligns closely with what merchants and developers actually want to do: fetch one product by a known identifier without awkward search patterns.
Using nodes to retrieve multiple products by ID
The nodes query is one of the best ways to fetch multiple products when you already have a list of GraphQL IDs. It is efficient and easy to map over in app code.
query Products($ids: [ID!]!) {
nodes(ids: $ids) {
... on Product {
id
title
handle
}
}
}
{
"ids": [
"gid://shopify/Product/8258451439839",
"gid://shopify/Product/8258451440000"
]
}
If you are processing exports, bundle data, or collection relationships, this pattern is much better than sending one request per product. It is one of the reasons GraphQL is usually the better long-term choice.
Using products query with an ID filter
You can also query products using a search filter such as id:123456789. This works, but I usually prefer direct identifier-based queries when I already know the exact product.
query {
products(first: 20, query: "id:8258451439839") {
nodes {
id
title
handle
}
}
}
This approach is handy in Shopify Flow-style logic or when you are composing more advanced searches. Shopify documents query filters and syntax here: search syntax.
Can I retrieve product data by ID in Shopify Flow?
Yes, you can retrieve product data by ID in Shopify Flow using the Get product data action and product queries. This is the best no-code option for merchants on plans that support Flow.
This matters because some search results for this keyword are really about Shopify Flow, not custom development. Shopify's own documentation explains the Get product data action, including query configuration, sorting, and result limits.
If I were building a merchant automation that tags products, checks stock conditions, or updates records based on product IDs, I would first ask whether Flow can do it without custom code. Often it can, especially for straightforward admin automations.
When should I use Shopify Flow instead of code?
Use Shopify Flow when the task is an internal automation and you do not need a custom frontend or complex external integration. It is quicker to maintain and easier for merchants to understand later.
For example, if you need to retrieve products matching a set of IDs and then tag them or trigger follow-up actions, Flow may be enough. If you need to expose that data in a theme, external system, or app UI, code is usually the better route.
Can I get product data by ID in Shopify Liquid?
Yes, but only through workarounds. Shopify Liquid still does not provide a direct all_products[product_id] lookup.
This has been a limitation for years, and it still catches people out. In a Shopify theme, Liquid is not a full database query layer. It is a templating language with access to specific objects already in scope.
If you are editing a theme and only have a numeric product ID, your options are limited. You either loop through products you already have access to, use a handle-based lookup, or fetch data client-side via an API endpoint or app proxy.
Liquid workaround using collections.all.products
A common Liquid workaround is to paginate through collections.all.products and filter for the matching product ID. This can work for small catalogues, but it is not ideal for production.
{% paginate collections.all.products by 1000 %}
{% assign product_id = 123456789 | times: 1 %}
{% assign products_obj = collections.all.products | where: 'id', product_id %}
{% assign product = products_obj[0] %}
{% endpaginate %}
{{ product.title }}
I would only use this in edge cases or quick prototypes. On larger catalogues, it becomes brittle, and theme performance or maintainability can suffer. If you are working on product-page UX more broadly, my posts on the best PDP apps for Shopify and improving your product detail pages are more useful than forcing Liquid to do backend work it was never designed for.
Liquid workaround using handles
If you can convert the product ID to a handle beforehand, all_products[handle] is cleaner than looping through a collection. It is still not a direct ID lookup, but it is often the most practical theme-level option.
{{ all_products['your-product-handle'].title }}
The catch is obvious: you need the handle, not the ID. The all_products object also has usage limits, so I would not build anything ambitious around it.
What about retrieving product data from a variant ID instead?
If you only have a variant ID, you usually need to resolve the variant first and then get its parent product. The exact method depends on whether you are in GraphQL, REST, or Liquid.
This comes up a lot with subscriptions, bundle apps, and custom cart logic. In app development, I generally query the variant and request the linked product fields in the same GraphQL call. In Liquid, it is more awkward and often depends on what objects are already available on the page.
If your use case involves product options, hidden variants, or variant-based storefront logic, these related guides may help: how to hide product variants without deleting them and hiding variant images from the product page.
What permissions and rate limits do I need to watch?
To retrieve product data through the Admin API, you need the read_products scope. You also need to respect Shopify's API rate limits, especially if you are fetching many products.
The exact rate behaviour depends on the API. REST is simpler but stricter in practice for repeated requests, while GraphQL uses a cost-based model that is usually more efficient for well-structured queries. Shopify's platform evolves, so I always recommend checking the current versioned docs before shipping anything important.
From experience, the biggest practical mistake is not rate limits themselves. It is making too many small requests when one well-designed GraphQL query would do the job.
What are the most common mistakes when retrieving Shopify product data by ID?
The most common mistakes are using the wrong ID format, calling Liquid when you need an API, and forgetting permissions. These are easy to fix once you know what to check.
- Using numeric IDs in GraphQL without converting them to GIDs.
- Using GIDs in REST where Shopify expects a numeric ID.
- Trying to use all_products[ID] in Liquid, which still does not exist.
- Forgetting the read_products scope on your app or custom integration.
- Over-fetching data with REST when GraphQL would be cleaner.
- Assuming storefront APIs expose admin-only product data.
When I troubleshoot this for merchants or developers, I start with a simple checklist: What environment are you in? What ID format do you have? What exact fields do you need? Once those three answers are clear, the correct method is usually obvious.
Which method should you choose in real-world Shopify projects?
The right method depends on whether you are building a theme, an app, an automation, or a one-off script. For most developer use cases, Admin GraphQL is the best long-term option.
Here is the practical version of my recommendation:
- Use REST if you need one product fast and want the simplest implementation.
- Use GraphQL if you are building an app, need multiple products, or want only selected fields.
- Use Shopify Flow if the task is an internal automation and no-code is enough.
- Use Liquid only as a fallback when you cannot make an API call and the catalogue is small.
That advice reflects how I actually build. For merchant-facing features inside apps, I almost always choose GraphQL first. For quick internal tools, REST is still perfectly fine.
How do I retrieve specific item data using product ID in Shopify step by step?
If you want a simple process to follow, start by identifying your environment, then choose the matching API or workaround. The rest is just formatting the ID correctly and requesting the fields you need.
- Find the product ID in your Shopify admin or existing data source.
- Decide whether you are working in REST, GraphQL, Flow, or Liquid.
- If using GraphQL, convert the numeric ID to a GID.
- Make sure your app or integration has the read_products scope.
- Request only the fields you actually need where possible.
- Handle not-found responses and permission errors properly.
- If you are in a theme, avoid large catalogue loops unless there is no better option.
That is the process I would hand to a junior developer on a Shopify app project. It avoids the biggest mistakes and gets you to a working solution quickly.
Final thoughts on retrieving Shopify item data by product ID
Retrieving specific item data using a product ID in Shopify is straightforward once you choose the right tool. REST is simplest, GraphQL is most flexible, Flow is best for no-code automation, and Liquid should be a last resort.
The biggest thing to remember is that Shopify does not offer a native all_products[ID] Liquid shortcut, so theme-only solutions are always a compromise. If you are building anything beyond a quick workaround, I would strongly recommend using the Admin API and treating product IDs as backend data, not something to force through theme logic.
For official references, these are worth bookmarking: Shopify GIDs, GraphQL products query, REST Admin API, and Shopify Flow Get product data.