Blog
How to Access Shopify Store Data via Shadow APIs
Shopify's official APIs require store owner approval and OAuth credentials. Shadow APIs -- the internal endpoints every Shopify storefront calls -- let you access product catalogs, pricing, inventory status, and collection data from any public store without authentication.
How to Access Shopify Store Data via Shadow APIs
Shopify powers over 4 million online stores. If you are building a price comparison tool, competitive intelligence platform, or market research product, you need data from these stores. But Shopify's official API model makes this surprisingly difficult.
The Storefront API requires the store owner to create credentials for you. The Admin API requires even deeper access. For a tool that needs to monitor thousands of stores across different merchants, getting individual OAuth tokens from each one is not realistic.
There is a better path. Every Shopify store's frontend makes internal API calls to render product pages, collection listings, and search results. These shadow APIs return clean JSON and work across any public Shopify store.
The Problem with Current Approaches
Official APIs Require Store Owner Cooperation
Shopify's API model is designed for apps that a merchant installs into their own store. The flow requires:
- Register as a Shopify Partner
- Create a public or custom app
- Request specific API scopes
- Each merchant must individually authorize your app
- Handle OAuth token refresh and scope changes
For competitive intelligence or market research, asking your competitors to install your app and grant API access is not a viable strategy.
Scraping Shopify Stores Is Fragile
Shopify stores use dozens of different themes, each with different HTML structures. A scraper built for one store's product page will break on another store using a different theme. Even stores on the same theme can customize their templates extensively.
Shopify also deploys Cloudflare-level bot protection on high-traffic stores, and their checkout and inventory pages have additional anti-automation measures.
The products.json Endpoint Is Limited
Many developers know about the /products.json endpoint that most Shopify stores expose. But it has significant limitations:
- Paginated to 250 products maximum per page
- Missing inventory quantities on most stores
- No collection or category data
- No search functionality
- Rate limited to approximately 2 requests per second
- Some stores disable it entirely
Shadow APIs: The Alternative
Every modern Shopify storefront is a JavaScript application that fetches data from internal API endpoints. When a customer browses a store, their browser calls these endpoints to load product details, filter collections, run searches, and check inventory. These are the shadow APIs.
Unlike the limited products.json endpoint, shadow APIs expose the full data model: variant-level inventory, metafields, rich product descriptions, recommendation engines, and real-time pricing. They work consistently across all Shopify stores because they are part of Shopify's platform infrastructure, not theme-specific code.
What Unbrowse Discovers on Shopify Stores
When Unbrowse indexes a Shopify store through normal browsing, it captures endpoints like:
| Endpoint Pattern | Data Returned | Format |
|---|---|---|
/api/2024-01/graphql.json |
Full product catalog with variants | JSON (GraphQL) |
/recommendations/products.json |
Related product recommendations | JSON |
/search/suggest.json |
Search suggestions and results | JSON |
/cart.js |
Current cart state and inventory check | JSON |
/collections/{handle}.json |
Collection products with filters | JSON |
/variants/{id}.json |
Individual variant with inventory | JSON |
The GraphQL Storefront endpoint is particularly powerful -- it supports complex queries across products, collections, and metafields in a single request.
How It Works
# Install Unbrowse
npx unbrowse setup
# Browse any Shopify store to discover its APIs
npx unbrowse go "https://shop.example.com/collections/all"
# Resolve product data from any indexed Shopify store
npx unbrowse resolve "products from shop.example.com under $50"
Once indexed, Unbrowse routes requests through the shadow API:
import Unbrowse from 'unbrowse';
const ub = new Unbrowse();
const result = await ub.resolve(
'shopify store products at allbirds.com'
);
console.log(result.data);
// {
// products: [
// {
// title: "Tree Runner",
// price: "98.00",
// variants: [
// { size: "9", available: true, inventory_quantity: 42 },
// { size: "10", available: true, inventory_quantity: 18 }
// ],
// collections: ["mens-shoes", "runners"],
// ...
// }
// ]
// }
Performance: Browser vs Shadow API
| Metric | Browser Automation | Shadow API (Unbrowse) |
|---|---|---|
| Latency per request | 3-6 seconds | 150-300ms |
| Memory usage | 500MB+ (headless Chrome) | ~5MB |
| Cost per 1,000 requests | $5.30 (compute + proxy) | $0.05 |
| Cross-store compatibility | Varies by theme | Universal |
| Data format | HTML (theme-dependent) | Structured JSON |
| Inventory data available | Rarely (hidden in DOM) | Yes |
For a price monitoring tool tracking 5,000 products across 50 stores, shadow APIs complete a full sweep in under 3 minutes. Browser automation would take over 4 hours and require maintaining 50 different scraping configurations.
When to Use This Approach
Shadow APIs via Unbrowse are ideal when:
- You need data across multiple stores. No per-store OAuth required. Browse once, call the API forever.
- You need inventory-level data. Shadow APIs expose variant-level availability and quantity that HTML scraping often misses.
- You are building competitive intelligence. Monitor competitor pricing, new product launches, and stock levels programmatically.
- You want theme-independent extraction. Shadow APIs work identically regardless of which Shopify theme a store uses.
This approach is less suitable for accessing private admin data (orders, customers, analytics) which genuinely requires store owner authorization.
Getting Started
# 1. Install
npm install -g unbrowse
# 2. Set up
unbrowse setup
# 3. Index any Shopify store
unbrowse go "https://gymshark.com/collections/all"
# 4. Query products via shadow API
unbrowse resolve "gymshark leggings under $60"
The first browse session captures the store's API patterns. Subsequent queries resolve in milliseconds, and the discovered endpoints work for any product or collection on that store.
FAQ
Is this legal?
You are accessing data that the store publicly serves to every visitor's browser. Shadow API calls replicate what your browser does when you visit a product page -- they request the same JSON endpoints with the same public access level. There is no authentication bypass or access control circumvention involved.
How is this different from scraping?
Scrapers download HTML pages and parse them with CSS selectors or XPath. Shadow APIs call the store's own internal endpoints directly and receive structured JSON. No browser rendering, no theme-dependent parsing, no JavaScript execution required.
Do shadow APIs work on Shopify Plus stores?
Yes. The internal API infrastructure is consistent across all Shopify plans. Shopify Plus stores may have additional custom endpoints from their headless commerce setup, which Unbrowse also discovers.
What about stores with password protection?
Stores behind a Shopify password page require authentication to access any content, including shadow APIs. This approach only works with publicly accessible storefronts.