Shopify Products Scraper: Store Catalog, Prices & Variants
Pricing
$0.80 / 1,000 product returneds
Shopify Products Scraper: Store Catalog, Prices & Variants
Shopify product scraper that exports any Shopify store's full catalog from its public /products.json feed: titles, vendors, types, tags, prices, sale prices, variants, SKUs, availability, images and URLs. No browser or proxies: fast and cheap. Great for price monitoring.
Pricing
$0.80 / 1,000 product returneds
Rating
0.0
(0)
Developer
Ryan Sofranko
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Features
Share
What does Shopify Products Scraper do?
Shopify product scraper that exports any Shopify store's full catalog from its public /products.json feed: titles, vendors, types, tags, prices, sale prices, variants, SKUs, availability, images and URLs. No browser or proxies: fast and cheap. Great for price monitoring.
📖 Step-by-step tutorial: https://dev.to/scrape-smith/how-to-export-any-shopify-stores-product-catalog-and-prices-to-csv-1k1m
Popular searches this actor answers: Shopify scraper, Shopify product scraper, Shopify products.json, Shopify price monitoring, export Shopify catalog, ecommerce competitor research.
Try it free: the input is prefilled, so just click Start and you get real results in seconds for a fraction of a cent.
What data does it return?
Real rows from a test run with the example input (truncated):
| title | vendor | productType | minPrice | currency | onSale | anyAvailable |
|---|---|---|---|---|---|---|
| Women's Allbirds Flip Flop - Dusty Pink | Allbirds | Shoes | 50 | USD | False | True |
| Men's Canvas Runner NZ - Deep Navy Stripes (Blizzard Sole) | Allbirds | Shoes | 100 | USD | False | True |
| Women's Canvas Runner NZ - Deep Navy Stripes (Blizzard Sole) | Allbirds | Shoes | 100 | USD | False | True |
| Men's Cruiser Terry - Warm White (Warm White Sole) | Allbirds | Shoes | 115 | USD | False | True |
| Men's Cruiser Slip On - Natural Black (Blizzard Sole) | Allbirds | Shoes | 100 | USD | False | True |
Full JSON for one row:
[{"store": "https://www.allbirds.com","productId": 7340901859408,"title": "Women's Allbirds Flip Flop - Dusty Pink","handle": "womens-allbirds-flip-flop-dusty-pink","url": "https://www.allbirds.com/products/womens-allbirds-flip-flop-dusty-pink","vendor": "Allbirds","productType": "Shoes","tags": ["allbirds::carbon-score => undefined","allbirds::cfId => color-a4d5d0f6620dc304306f503bf67bc5f9","allbirds::complete => true","allbirds::edition => limited","allbirds::gender => womens","allbirds::hue => pink","allbirds::master => womens-allbirds-flip-flop","allbirds::material => sugar","allbirds::price-tier => tier-3","allbirds::silhouette => zeffer","loop::returnable => true","OOS DNS","shoprunner","WC WAVE 1 TRUCK #1-#16 7.30.2026","YBlocklist","YGroup_ygroup_womens-allbirds-flip-flop"],"createdAt": "2026-03-27T14:03:50-07:00","updatedAt": "2026-11-02T09:52:32-08:00","publishedAt": "2026-09-25T16:58:13-07:00","imageUrls": ["https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_LEFT.png?v=1774646345","https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_BACK.png?v=1774646345","https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_TD.png?v=1774646346","https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_SOLE.png?v=1774646346","https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_PAIR_3Q.png?v=1774646345"],"minPrice": 50,"maxPrice": 50,"onSale": false,"anyAvailable": true,"variantCount": 7,"maxDiscountPercent": null,"currency": "USD","market": "US","shopCurrency": "USD","rowKey": "https://www.allbirds.com|US|USD|7340901859408"}]
Output fields
| Field | Meaning |
|---|---|
store, productId, title, handle, url, vendor, productType, tags, createdAt, updatedAt, publishedAt, imageUrls | Product details from the feed. |
minPrice, maxPrice, variantCount, anyAvailable | Product rows: price range across variants, number of variants, whether any variant is in stock. |
variantId, variantTitle, sku, price, compareAtPrice, available | Variant rows (includeVariants: true). compareAtPrice is the raw compare-at value (null when missing). |
onSale | true only when the compare-at price, parsed as a number, is strictly greater than the current price. Missing, empty, 0 or equal compare-at prices are not a sale. Product rows: true if any variant is on sale. |
discountPercent / maxDiscountPercent | Variant rows: (1 - price / compareAtPrice) × 100, one decimal, null when not on sale. Product rows: the largest variant discount. |
currency | ISO currency the prices in this row are in (the store's active storefront currency for the market the feed was served in). |
market | 2-letter country of the Shopify market the prices belong to. |
shopCurrency | The store's base currency from /meta.json (can differ from currency when a market converts prices). |
rowKey | Stable join key: store|market|currency|productId (plus |variantId on variant rows). Join daily runs on rowKey so a market or currency change shows up as a new key, not as a price drop. |
Download results as JSON, CSV, Excel, XML or HTML, call it via the Apify API, or connect it to Zapier, Make, n8n, Google Sheets and AI agents (Apify MCP server).
Use cases
- Competitor price monitoring and sale (compare-at) tracking
- Dropshipping and product research across many stores
- Catalog migration or backup
- Market research on brands, product types and tags
- Feeding product data to AI agents or dashboards
How to use Shopify Products Scraper
- Open the actor and keep the prefilled example, or replace it with your own input.
- Click Start and wait for the run to finish.
- Export the dataset or fetch it via API.
Input
| Field | Description |
|---|---|
storeUrls | Shopify store homepages, one per line, e.g. https://www.allbirds.com or gymshark.com. Works on any store running on Shopify that has not disabled its public /products.json feed. |
maxProductsPerStore | Maximum products exported per store (each product, or each variant when includeVariants is on, is one billed row). Example: 100. |
includeVariants | false = one row per product with min/max price. true = one row per variant (size/color) with its own SKU, price and availability. |
country | Optional 2-letter country code (e.g. US, CA, GB) to pin the Shopify market, so prices come back in that market's currency. Leave empty for the store's default market. |
Example input:
{"storeUrls": ["https://www.allbirds.com"],"maxProductsPerStore": 20}
Pricing
Pay per event: $0.0008 per product row. 1,000 products = $0.80. Apify platform usage is included. Set a max charge per run to cap cost.
| Example job | Approx. cost |
|---|---|
| 20 products from one store | $0.016 |
| 1,000 products | $0.80 |
| 10,000 variant rows | $8.00 |
FAQ
How do I know if a site is a Shopify store?
Open https://store.com/products.json in a browser. If you see JSON, this actor works.
Which currency are the prices in?
Shopify serves /products.json prices in the visitor's market, so a store with Shopify Markets can return USD to one visitor and CAD to another. Every row carries currency and market; set country to pin a market for consistent day-to-day monitoring.
Can I get stock levels?
Shopify's public feed shows availability (in stock / out of stock) per variant, not exact quantities.
Do I need proxies or login?
No. The feed is public and the actor uses plain HTTP requests.
Is it legal to use this data?
The actor only reads public, official endpoints. You are responsible for using the data in line with the source's terms and applicable laws (e.g. GDPR for personal data).
API example
curl -X POST "https://api.apify.com/v2/acts/scrape-smith~shopify-products-feed/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"storeUrls": ["https://www.allbirds.com"], "maxProductsPerStore": 20}'
Changelog
- 0.2 (2026-11-02):
onSaleis now a strict numeric check on every row (variant rows get it too); addeddiscountPercent/maxDiscountPercent,currency,market,shopCurrencyandrowKey; new optionalcountryinput to pin a market. Existing fields are unchanged. Thanks to a reader on dev.to for the suggestion. - 0.1 (2026-10-22): first public release.