Shopify Products Scraper - Store Catalog avatar

Shopify Products Scraper - Store Catalog

Pricing

from $0.97 / 1,000 products

Go to Apify Store
Shopify Products Scraper - Store Catalog

Shopify Products Scraper - Store Catalog

Scrape the catalogue of a Shopify store. Each product row has the title, link, vendor, type, tags, description, lowest and highest price and stock flag, with every variant's SKU, price and compare-at price, plus image URLs. Optional paid sort. $1.00 per 1,000 products.

Pricing

from $0.97 / 1,000 products

Rating

5.0

(1)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

3

Monthly active users

4 days ago

Last modified

Share

Give it a Shopify store's address and get its catalogue back, one row per product: title, handle, link, vendor, product type, tags, description, lowest and highest price, stock flag, and every variant with its own SKU, price, compare-at price and availability, plus the image URLs.

It reads the public catalogue feed a Shopify store publishes, so there is nothing to apply for and no key to hold. The limit worth knowing up front: it returns published products only, and inventory counts are not in that feed. You get a yes or no on stock, never a number.

InputShopify store URLs or bare domains
OutputOne row per product with variants nested: title, vendor, type, tags, price range, stock flag, SKUs and images
CeilingWhatever the store publishes, capped by maxItems per store
Account neededNone
Price$1.00 per 1,000 products on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 5,000. The optional sort adds $0.06 per 1,000 products it reads and leaves out

🔍 What Shopify Products Scraper does

Paste stores, one per line. A bare domain, a full URL, or any page on the store: each one is reduced to the store itself and the catalogue is walked from the top, 250 products at a time, until it runs out or hits your cap.

If a store answers on www but not on the bare domain, or the other way round, both are tried before it gives up.

Sorting is a paid option. Shopify serves its catalogue in the store's own order and will not sort it on request. So to sort, the run reads up to 10,000 products of each store, keeps the first ones by your order, up to maxItems, and leaves the rest out. Cheapest and dearest go by the lowest and highest variant price, newest by when the product was created.

Optional Notion delivery. Pick a Notion connector and every product is also written as a page into your workspace when the run finishes. The dataset is written either way.

📋 What data you get from each Shopify product

What you getField
The store, product id, title, handle and linkstore, productId, title, handle, url
Vendor, product type and the store's own tagsvendor, productType, tags
The product copy as plain textdescription
When it was created and publishedcreatedAt, publishedAt
Lowest and highest variant pricepriceMin, priceMax
Whether any variant is in stock, and how many variants there areavailable, variantCount
Each variant's name, SKU, price, compare-at price and stock flagvariants
Full-size image URLsimages

▶️ How to scrape a Shopify store's products

  1. Open Shopify Products Scraper and click Try for free.
  2. Paste your stores into Shopify store URLs, one per line.
  3. Set Max products per store to what you actually need.
  4. Click Start.
  5. Download the dataset as JSON, CSV or Excel.

Leave the store box empty and you get one BAD_INPUT row, uncharged, telling you so.

💰 How much does it cost to scrape Shopify products?

$1.00 per 1,000 products on the Free plan. Paid plans pay a little less: $0.99 on Starter, $0.98 on Scale and $0.97 on Business. On the free plan, the $5 Apify gives you each month covers about 5,000 products.

One row is one product, however many variants hang off it. Diagnostic rows are not charged, so a store that will not answer produces nothing to pay for.

A sort adds one charge of its own: each product it reads and leaves out costs $0.06 per 1,000 on the Free plan, a little less on paid plans. Without a sort, nothing changes.

One thing to watch: the store list is taken as written. List the same shop twice and it is read twice and charged twice, so de-duplicate before you paste.

📥 What you give it

{
"storeUrls": ["https://www.gymshark.com", "allbirds.com"],
"maxItems": 1000
}
FieldDefaultWhat it is
storeUrlsnoneBare domains, full URLs, or any page on the store, one per line. The form opens with two example stores.
maxItems1000How many products to take per store before moving on. You are charged per product returned, so this is your spend cap.
sortBynonePaid option: price-asc (cheapest first), price-desc (dearest first) or newest. Empty keeps the store's own order.
notionConnectornoneOptional. Authorise a Notion connector once under Settings, then pick it here to have the products written into your workspace.
notionParentIdnoneOptional. The Notion data source id to write into. Leave it empty and the pages are created privately in your workspace.
proxyConfigurationoffOptional, and not needed for a normal run. Only fill this in if you want the run to go out through servers of your own.

📤 What you get back

A real product row from a run in September 2026. The tags, description and images are cut short here.

{
"ok": true,
"store": "https://gymshark.com",
"productId": "6806502867146",
"title": "Gymshark Diffuse Sweat Headwrap - Black",
"handle": "gymshark-diffuse-sweat-headwrap-headwear",
"url": "https://gymshark.com/products/gymshark-diffuse-sweat-headwrap-headwear",
"vendor": "Gymshark | Be a visionary.",
"productType": "Unisex>Accessories>Headwear>headband",
"tags": ["accessories", "category:Headwear", "feature:sweat-wicking", "filter-colour:Black", "outlet", "over-50-off", "season:SS26", "..."],
"description": "A HEADWRAP THAT WORKS\nWe built the Diffuse Sweat Headwrap with the black community and all hair types in mind ...",
"createdAt": "2026-01-09T04:26:28-08:00",
"publishedAt": "2026-09-11T10:14:04-07:00",
"priceMin": 26,
"priceMax": 26,
"available": true,
"variantCount": 1,
"variants": [
{"title": "One Size", "sku": "I1C2W-BB2J-OS", "price": 26, "compareAtPrice": null, "available": true}
],
"images": ["https://cdn.shopify.com/s/files/1/0156/6146/files/Diffuse_Sweat_Headwrap_GS_Black_I1C2W_BB2J_6.jpg?v=1789139459", "..."]
}
FieldHow to read it
productId, handleShopify's own id and URL slug. productId is the key to join on between runs.
priceMin, priceMaxThe cheapest and dearest variant, as numbers. Equal when there is only one.
compareAtPriceInside variants: the crossed-out price, when the store set one. null otherwise, which is most of the time.
tagsThe store's own tags, exactly as they set them. Big retailers use these for internal bookkeeping, so expect noise.
createdAt, publishedAtWhen the product was made and when it went live. Useful for spotting new arrivals.
imagesFull-size image URLs. The files themselves stay on Shopify.

🧾 Reading the output

RowHow to spot itBilled
A productok is true and it has a productIdyes
A diagnosticok is false and it carries an errorCodeno

There is no sample row. Filter on ok == true and you have your products.

CodeWhat it means
BAD_INPUTNothing usable in the store box.
NOT_SHOPIFYThe catalogue feed did not answer. The row carries triedHosts so you can see what was attempted. A store that turned the feed off, or one behind a password, lands here too.
NO_RESULTSThe store answered with an empty catalogue.
RATE_LIMITED, SERVER_ERRORThe store asked for a slower pace, or its own server erred. Worth one re-run.
NETWORKThe store would not serve the request, or was unreachable.
NOT_SERVEDThis product was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED.
SORT_NOT_LIVEA sort was asked for while its price was not in force, so nothing was searched.
TIME_LIMITThe run got close to its time limit and stopped early. Every product delivered before that is in your dataset, and the row names the store it was reading and any it never reached. If nothing came back at all, the run is marked as failed.

💡 What people use it for

  • Pulling another store's full catalogue with prices and SKUs, then diffing it weekly on productId.
  • Watching compareAtPrice against price to see when a store actually discounts.
  • Spotting new arrivals by sorting on publishedAt, or with sortBy set to newest.
  • Building a supplier price list with variant SKUs already on the row.

From a store's catalogue to restock alerts, in three steps:

  1. Run this on the store and keep the url of the products you care about.
  2. Paste them into Products to monitor in Product Price & Stock Monitor, one {"url": ..., "label": ...} each.
  3. Put your Slack or Discord hook into its webhookUrl and schedule it.

🚧 What it does not do

  • No inventory numbers. The public feed carries a stock flag, not a quantity. available is all there is.
  • Published products only. Drafts, archived products and anything hidden from the storefront are not in the feed.
  • A collection URL scrapes the whole store. Any page you paste is reduced to the store itself, so /collections/sale returns the full catalogue, not the sale.
  • A store with the feed switched off comes back as NOT_SHOPIFY. Some shops turn it off, and password-protected stores answer the same way, so the verdict is not always about the platform.
  • A truncated catalogue can look complete. If a store stops answering partway through, that store ends quietly with the products it had. If a count looks short against what the shop shows, run it again.
  • Prices are the store's own currency, as the feed publishes them. There is no conversion and no currency field on the product row.
  • Duplicate store URLs are not merged. Two entries for one shop means two passes.
  • A sort covers at most 10,000 products per store. A bigger store is sorted on its first 10,000.
  • It is not an official Shopify tool. Dami's Studio is independent and is not affiliated with or endorsed by Shopify, or by any other company named on this page.

🧭 Which product scraper do you need?

If you wantUse
Products from a Shopify store's catalogueThis one
Which domains run Shopify, with each store's contact detailsShopify Store Leads
Restock and price-drop alerts on product pages you nameProduct Price & Stock Monitor
TikTok Shop products with prices and units soldTikTok Shop Scraper
Amazon products by keyword or ASIN, with the on-page reviewsAmazon Scraper
Export products, MOQ and suppliers on Alibaba.comAlibaba.com Scraper

❓ Questions people ask

Do I need a Shopify account or an API key?

No. The catalogue feed is public on every store that leaves it on.

Can I scrape just one Shopify collection?

Not here. Whatever page you paste, the whole store is read. Filter on productType or tags afterwards.

How many products can one run take?

As deep as the store goes. maxItems is your own cap, and it is also your spend cap.

Why do the tags look like nonsense?

Because they are the store's internal labels. Big retailers put dates, buckets and workflow markers in there alongside the useful ones.

Can I get it into Notion automatically?

Yes. Authorise a Notion connector in your Apify settings and pick it in Notion connector. The dataset is written either way.

Can I call it from code or connect it to an AI assistant?

Yes. The API tab has ready-made code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/shopify-products-scraper. Either way the run happens on your Apify account at the same price.

These are public product listings. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Send the store URL and the run ID; the errorCode and triedHosts on the diagnostic row usually name the problem on their own.