Shopify Variant Scraper: Price, SKU & Stock avatar

Shopify Variant Scraper: Price, SKU & Stock

Pricing

from $0.44 / 1,000 product variants

Go to Apify Store
Shopify Variant Scraper: Price, SKU & Stock

Shopify Variant Scraper: Price, SKU & Stock

Scrape any public Shopify store into one row per product variant: SKU, variant title, options, price, compare-at price, discount percent, availability, barcode, weight, images, vendor, product type, tags and description. Batch many stores, filter by collection, vendor, price or sale status.

Pricing

from $0.44 / 1,000 product variants

Rating

0.0

(0)

Developer

Axiora Solutions

Axiora Solutions

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Share

Shopify Scraper — Product Variants, Prices, SKUs & Stock

Shopify scraper that turns any public store into one row per product variant — its own SKU, options, price, compare-at price, discount and availability — because that is the level real pricing and inventory work happens at. It reads the store's own public product feed, so there is no API key, no app install and no store password needed. Leave the prefilled allbirds.com and kith.com in place and click Start to see it work.

What you get

  • 🧬 One row per product variant — sku, barcode, option1/2/3, optionNames, variantTitle and position, so a shoe with eight sizes in three colours becomes 24 rows.
  • 💱 Pricing fields you can act on — price, compareAtPrice, isOnSale, discountPercent, productMinPrice and productMaxPrice, all computed from the merchant's own data.
  • 📦 available — the true purchasable boolean from the feed, with no invented inventory quantities.
  • 🏷️ Product context on every row — productTitle, productHandle, productUrl, vendor, productType, tags, publishedAt and ageDays.
  • 🔁 Change detection built in — a stable variantUid plus a productHash covering title, price, compare-at price and availability.
  • 🛟 Honest errors, not blank runs — a blocked or non-Shopify store becomes an ok: false row with a specific reason.

Quick start

  1. Add one or more store domains to Shopify stores — a bare domain like allbirds.com, a full URL or a myshopify.com address all work.
  2. Optional: narrow the scope with Collection handles or Product handles, and cap the run with Max products per store and Max variants for the whole run.
  3. Paste the minimal input below (or keep the prefilled stores) and click Start.
  4. Review the Variants, Pricing & discounts and Catalogue export dataset tabs, then export or connect through the API.
{
"stores": ["allbirds.com"],
"maxProductsPerStore": 50
}

Example output

One dataset row — a single variant of one product:

{
"ok": true,
"errorCode": null,
"variantUid": "allbirds.com:4578213:31889234",
"store": "allbirds.com",
"storeName": "Allbirds",
"currency": "USD",
"collection": "mens-shoes",
"productId": "4578213",
"productHandle": "wool-runner-go",
"productTitle": "Wool Runner Go",
"productUrl": "https://allbirds.com/products/wool-runner-go",
"productType": "Shoes",
"vendor": "Allbirds",
"tags": ["new", "mens"],
"publishedAt": "2026-09-12T10:00:00.000Z",
"ageDays": 20,
"variantId": "31889234",
"variantTitle": "US 10 / Natural Black",
"sku": "WRG-10-NB",
"barcode": "0190000123456",
"option1": "US 10",
"option2": "Natural Black",
"option3": null,
"optionNames": { "Size": 1, "Color": 2 },
"position": 7,
"price": 125,
"compareAtPrice": 145,
"isOnSale": true,
"discountPercent": 13.8,
"available": true,
"requiresShipping": true,
"taxable": true,
"grams": 600,
"featuredImageUrl": "https://cdn.shopify.com/s/files/1/0001/wrg.jpg",
"imageCount": 6,
"productMinPrice": 125,
"productMaxPrice": 145,
"variantCount": 24,
"productHash": "ba71f4c2e90d5538",
"scrapedAt": "2026-10-02T12:00:00.000Z"
}

What this Shopify scraper returns

  • 🧬 Variant-level rows — sku, barcode, option1/2/3, price, compareAtPrice, discountPercent, available, grams, weight, variant image and position. Plus optionNames, so you always know whether option1 means Size or Colour for that specific product.
  • 🏷️ Discount maths done for you — isOnSale and discountPercent are computed from the merchant's own compare-at price, not estimated.
  • 💱 Real currency, or honest null — Shopify's public product feed does not include a currency, so the Actor reads it from the storefront. If the store does not expose it, currency is null. Prices are never relabelled with a guessed currency.
  • 📦 No invented stock numbers — Shopify's public feed publishes a purchasable boolean and nothing else. You get available. No fabricated inventory_quantity.
  • 🔀 Three ways in — whole catalogue, specific collection handles, or an exact list of product handles when you track a known SKU set.
  • 🎯 Filters that cut your bill — in-stock only, on-sale only, price range, vendor, product type, tags and publishedAfter all run before rows are written, so filtered variants are never charged.
  • 🔁 Change detection — variantUid is stable and productHash covers title, price, compare-at price and availability. Diff two scheduled runs and you have a price-and-stockout feed.
  • 🛟 One blocked store never fails the run — a password-protected store, a non-Shopify site or a 403 becomes an ok: false row with a specific reason.

Running on Apify adds scheduling, webhooks, monitoring, API and SDK access, and one-click export to JSON, CSV, Excel, Google Sheets and 20+ integrations.

How to use it

  1. Add store domains to Shopify stores.
  2. Leave Collection handles and Product handles empty for the full catalogue, or fill one of them to narrow the scope.
  3. Set Max products per store and Max variants for the whole run.
  4. Add filters if you want a smaller, cheaper dataset — Discounted variants only plus a Minimum price is the classic competitor-promo query.
  5. Click Start, then use the Variants, Pricing & discounts and Catalogue export dataset tabs.

Where do I find a collection or product handle?

They are the last path segment of the store URL. https://allbirds.com/collections/mens-shoes → handle mens-shoes. https://allbirds.com/products/wool-runner-go → handle wool-runner-go.

How much does it cost

Pricing is pay per event with one event:

EventWhat triggers itBilled
Product variantOne variant row written to the datasetper variant
Actor startOnce per run, platform feeper run

Billing is per variant, not per product, and the README says so up front because it is the one thing that will surprise you: a 200-product store with an average of 12 variants is ~2,400 billed rows, not 200. Use Max variants for the whole run to cap it exactly, and the filters to pay only for the rows you actually want.

Variants removed by filters are not billed. Stores that cannot be read are not billed. Compute, bandwidth and storage are included; there is no separate platform-usage charge on top.

Set Max cost per run in the run options for a hard ceiling. Higher Apify plans get progressively lower per-variant pricing through Apify Store tier discounts.

Evaluating? Set Max products per store to 5 on one store.

Example input

{
"stores": ["allbirds.com", "https://rothys.com"],
"collections": ["mens-shoes"],
"maxProductsPerStore": 100,
"maxVariantsTotal": 2000,
"includeDescription": false,
"onSaleOnly": true,
"minPrice": 50,
"tags": ["new"],
"publishedAfter": "90 days"
}

When a store refuses the feed

{
"ok": false,
"errorCode": "UNSUPPORTED_SOURCE",
"requestedInput": "example-store.com",
"error": {
"code": "UNSUPPORTED_SOURCE",
"message": "example-store.com returned 404 for its product feed. The store may be private, password-protected or on a different platform.",
"httpStatus": 404,
"hint": "This source or URL shape is not supported by this Actor. See the README for supported sources."
}
}

Use cases

  • Competitor price monitoring — schedule daily, diff productHash per variantUid, alert on changes.
  • Promotion tracking — onSaleOnly plus discountPercent tells you exactly what a competitor is discounting and by how much.
  • Stockout and assortment analysis — available per variant reveals which sizes and colours actually sell out.
  • New-arrival feeds — publishedAfter: "7 days" on a schedule.
  • Dropshipping and reselling — Catalogue export is a flat, import-ready product feed with SKUs and barcodes.
  • Brand compliance — scan many retailers for a vendor and compare advertised prices against MAP.
  • Lead qualification — pair with the Domain Contact Enricher to find which prospects run Shopify, then pull their catalogue size and price band.
ActorUse it for
Domain Contact EnricherDetect which of your prospects run Shopify, and get their contact details
Sitemap & Indexability AuditTechnical SEO health of the same storefronts
News & RSS Feed ScraperBrand and product news for the stores you track

Frequently asked questions

Which Shopify stores work?

Any store that leaves its standard public product feed enabled, which is the default. Stores that are password-protected, that have disabled the feed, or that sit behind an aggressive bot shield will return a clear UNSUPPORTED_SOURCE or ACCESS_DENIED row rather than silently returning nothing.

Why is currency sometimes null?

Because Shopify's public product feed genuinely does not contain it. The Actor reads the currency from the storefront page instead. When a store does not expose it there either, the field stays null — the alternative would be labelling prices with a currency we cannot verify, and a wrong currency in a pricing dataset is worse than a missing one.

Can I get inventory quantities?

No, and no scraper can from the public feed. Shopify publishes a purchasable boolean (available) and nothing more. Any tool that shows you a public store's stock count is either inferring it or making it up. Track available over scheduled runs to detect stockouts reliably.

Why do I get so many rows per product?

Because pricing and stock are per variant. This is the product's core design, and the pricing section above spells out the cost implication. If you only need one row per product, filter downstream on position: 1, or set a maxVariantsTotal that matches your budget.

Is there a product limit per store?

Shopify's public feed pages 250 products at a time and the Actor follows up to 200 pages for a full catalogue (20 per collection), so roughly 50,000 products per store is reachable. Max products per store is what actually bounds a run.

How do I detect price changes?

Schedule the Actor, keep variantUid as your key, and compare productHash between runs. A changed hash means the title, price, compare-at price or availability moved. That is far cheaper than storing and diffing every field.

Does it need a proxy?

Usually not. Enable datacenter proxy rotation if you see ACCESS_DENIED on a store that works in your browser. Residential groups also work but Apify bills them per gigabyte, so reach for datacenter first.

The Actor requests a public endpoint that merchants publish so their catalogue can be syndicated, and it identifies itself. Product and price data is business information, not personal data. You remain responsible for how you use it, including any contractual obligations you have with the brands involved.

Something looks wrong — how do I report it?

Open the Issues tab on this Actor page with the store domain and the field you expected.


Runnable examples and how-to guides for these Actors: github.com/batow133/axiora-apify-actors