Shopify Store Monitor - Product, Price & Stock Change Scraper
Pricing
from $0.50 / 1,000 change or product rows
Shopify Store Monitor - Product, Price & Stock Change Scraper
Monitor competitor Shopify stores: new and removed products, price drops and increases, sales (compare-at price) started or ended, and sold-out / back-in-stock variants since the last run. Reads the public products.json feed; headless stores fall back to myshopify.com. Optional full product export.
Pricing
from $0.50 / 1,000 change or product rows
Rating
0.0
(0)
Developer
Ivora Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
16 hours ago
Last modified
Categories
Share
Shopify Store Monitor: Product, Price & Stock Change Scraper
Watch competitor Shopify stores and get only what changed since your last run: new products, removed products, price drops and increases, sales that started or ended (compare-at price), and items that sold out or came back in stock. It's built for e-commerce brands, agencies, dropshippers and deal hunters who check rival stores by hand today.
- Works on any standard Shopify store through its public
products.jsonfeed. No login, no API key, no browser. - Monitor mode (default) compares each run with the last one. A daily schedule turns it into a competitor alert feed.
- A free summary row per store gives catalog size, sold-out and on-sale counts, price range, top vendors and product types, newest launches and change counts.
- An optional full catalog export gives every product with its variants, prices, SKUs and stock flags.
Sample output
Change rows from a real local test run (Oct 2026, store allbirds.com), shortened:
[{"type": "change", "changeType": "priceChange", "store": "Allbirds", "title": "Men's Canvas Runner NZ - Deep Navy Stripes (Blizzard Sole)","direction": "down", "oldPrice": 125.0, "newPrice": 100.0, "changePct": -20.0, "variantsChanged": 13, "currency": "USD","url": "https://allbirds.com/products/mens-canvas-runner-nz"},{"type": "change", "changeType": "compareAtChange", "store": "Allbirds", "title": "Women's Wool Runner Mizzles - Natural Black (Natural Black Sole)","direction": "saleStarted", "variantChanges": [{"title": "5", "sku": "AB006ZW050", "oldCompareAtPrice": null, "newCompareAtPrice": 125.0, "price": 99.0}, …]},{"type": "change", "changeType": "stockChange", "store": "Allbirds", "title": "Women's Canvas Runner NZ - Deep Navy Stripes (Blizzard Sole)", "direction": "productBackInStock","variantsBackInStock": [{"title": "6.5", "sku": "A12500W065"}, …]}]
(The test changed the saved baseline to produce these rows; on a live schedule they appear when the store really changes.)
How it works
- For each store, the Actor reads
https://<store>/products.json?limit=250&page=1…until the catalog ends. Shopify's public feed allows up to 25,000 products. The default safety cap is 10,000, which you can raise. - If that feed is missing, it tries
/collections/all/products.json. Then it looks in the homepage for the store's permanent*.myshopify.comdomain, which often still serves the feed for headless stores (Hydrogen, Next.js…). - It saves a compact copy of the catalog in a named key-value store (
stateStoreName). The next run compares against it:- New products are product IDs not seen before.
- Removed products are products missing from a complete read. Each one is double-checked on
/products/<handle>.js, because feeds can shift while being read. If a suspicious number is missing, removal detection is skipped for that run. - Price changes are listed per product, with every changed variant, old and new price and change %.
- Sale started / ended / changed comes from the compare-at price moving above or below the price.
- Sold out / back in stock compares the
availableflag per variant, with a product-level direction such asproductSoldOut. - Variants added / removed covers new sizes and colours or dropped ones.
- If a store answers HTTP 403/429 (some block cloud IPs), the Actor retries it through Apify residential proxy automatically. That path reads at most 5,000 products per store.
Paste a collection URL (https://store.com/collections/sale) to monitor just that collection. "Removed" then means it left the collection.
Input example
{"stores": ["allbirds.com", "https://www.gymshark.com", "https://colourpop.com/collections/lips"],"mode": "changes","firstRunBehavior": "baseline","changeTypes": ["newProduct", "priceChange", "compareAtChange", "stockChange", "removedProduct"],"minPriceChangePct": 5,"productKeywords": [],"stateStoreName": "competitors-daily"}
| Option | What it does |
|---|---|
mode | changes (monitor, default) or allProducts (every product every run, like a catalog scraper) |
firstRunBehavior | baseline (default) only stores the catalog on the first run. outputProducts also outputs current products, newest first |
productRowsLimit | Caps product rows per store (first run / allProducts). 0 = all |
changeTypes | Which change rows you want. All changes are still counted in the summary |
minPriceChangePct | Ignore small price moves |
productKeywords | Output only products whose title, vendor, type or tags match. The whole catalog is still tracked |
includeVariants, includeDescription | Extra detail on product rows |
Output
changerows (charged):changeType(newProduct,priceChange,compareAtChange,stockChange,variantsChange,removedProduct),direction, old/new values and per-variant details. Each row also has product context: title, vendor, product type, URL, image, currency, current price, availability and on-sale flag.productrows (charged, only when you ask for them): product ID, handle, title, vendor, type, tags, URL, image, price min/max, compare-at min/max, on sale, max discount %, available, variants count and in-stock count, published/created/updated dates, and variants (title, SKU, price, compare-at price, available).summaryrows (free, one per store): products, variants, available / sold-out / on-sale counts, price min/median/max, top vendors and product types, newest products, changes since the last run, feed source, proxy used and notes.errorrows (free) with a code and a hint:not_shopifyfeed_closed(a Shopify store with the feed disabled)password(store closed or not launched)collection(collection not found)blockedunreachable
Honest limits
- Prices are in the store's base currency, as published in the feed (the currency comes from the store's
/meta.json). Market-specific prices or discounts applied at checkout aren't visible. - Stock is in/out only. Shopify's public feed exposes
available, not inventory quantities. - Not every Shopify store works. In our Apify cloud test (Oct 2026), 12 of 13 well-known brand stores were read directly, with no proxy (Allbirds, Gymshark, SKIMS, ColourPop, Fashion Nova, Brooklinen…). Some stores disable the feed, run a custom storefront (bombas.com refused even through the residential fallback), or block cloud IPs. Unsupported stores get a free error row and are not charged.
- Huge catalogs: above 25,000 products (Shopify's feed limit) or your
maxProductsPerStorecap, only part of the catalog is read, and removed-product detection is switched off for that store. - Product URLs are built as
https://<store>/products/<handle>. A few headless storefronts use different URL paths.
Pricing (pay per event)
| Event | Price |
|---|---|
| Actor start | $0.003 per run |
| Store checked (catalog read and compared) | $0.004 per store |
| Change row, or product row when requested | $0.0005 |
Summary and error rows are free. Stores that can't be read aren't charged.
Examples:
- 20 competitor stores checked daily with about 5 changes each: $0.003 + 20 × $0.004 + 100 × $0.0005 = $0.133 per day (about $4 per month).
- One-off export of a 1,000-product store (
allProducts): $0.003 + $0.004 + 1,000 × $0.0005 = $0.507. - First run with the default
baseline: $0.007 for one store, and you only get the summary row.
Daily alerts to Slack or email
- Fill in the input and click Save as a new task (one task per client or competitor set is a good pattern).
- In Schedules, create a schedule (for example every day at 08:00 in your time zone) and add the task.
- In the task's Integrations tab, add the Slack or Gmail integration to get a message when a run finishes, or a webhook on "Run succeeded". The webhook can pass the run to Zapier, Make, n8n or your own endpoint, which can read the rows from
https://api.apify.com/v2/datasets/{defaultDatasetId}/items?view=changes.
Monitor mode outputs only changes, so every scheduled run's dataset is your alert list. An empty changes view means nothing changed. Turn on Apify's run-failure notifications too, so you hear about a failed run instead of silence.
Related actors
This is part of a small competitor-intelligence suite by the same developer, with the same conventions throughout: pay per event, failed items never charged, and monitors that return only what changed since the last run.
- Google Ads Transparency Scraper & New Ads Monitor: what your competitors advertise on Google Search, Display and YouTube.
- LinkedIn Ad Library Scraper & New Ads Monitor: competitors' LinkedIn ads without login, including EU impressions and targeting.
- Bing Ads Library Scraper - Microsoft Ads Monitor (EU): Bing ads from Microsoft's official Ad Library (EU/EEA).
- Google Trends Scraper & API: interest over time, by region/city, top queries and Trending now.
- ATS Jobs Scraper & Hiring Monitor: new and closed jobs from Greenhouse, Lever, Ashby, Workday and 6 more job boards.
- App Store & Google Play Scraper: ratings, versions, chart and keyword ranks of iOS and Android apps.
- Google Hotels Scraper & Rate Monitor: hotel prices by booking site (Booking.com, Expedia, Agoda, own site) for any dates, with price-change alerts.
FAQ
Do I need a proxy? Usually not. The feed is public. The automatic residential fallback handles stores that block cloud IPs.
Will the store owner notice? The Actor reads the same public feed many apps use, at a polite pace (one request every ~0.5 s per store).
Can I track only some products? Yes. Use a collection URL, or productKeywords to filter output by title, vendor, type or tag.
Is it legal? It reads publicly available product data. You are responsible for how you use the data and for complying with applicable law and the store's terms.