Shopify Price, Stock & Catalog Monitor — Batch + Diff
Under maintenancePricing
from $1.00 / 1,000 change events
Shopify Price, Stock & Catalog Monitor — Batch + Diff
Under maintenanceCompetitor price tracking for Shopify stores: batch of store domains, diff mode returns only CHANGE EVENTS (price, stock, new/removed products) plus a free per-store summary every run. Public /products.json feed — no login, no browser. Not affiliated with Shopify.
Pricing
from $1.00 / 1,000 change events
Rating
0.0
(0)
Developer
Johnn Mottin
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
You found out your competitor cut prices three days after your customers did. Price-monitoring SaaS starts at $99/month and sells by the seat; generic "page change" watchers can't tell a price drop from a banner swap. This Actor watches the public /products.json feed of any standard Shopify store and returns only the change events: price changes (with old/new/Δ%), restocks and sell-outs, new products, removed products, new variants. No login, no browser, no LLM.
Not affiliated with, sponsored by, or endorsed by Shopify Inc. or any store monitored. All data comes from each store's public /products.json feed and remains subject to that store's terms.
Who it's for:
- Merchants and dropshippers: track competitor stores daily — "these 3 of my 20 rivals cut prices last night" straight to Slack, Sheets or your CRM via Apify integrations.
- Brands and suppliers: watch resellers for MAP violations (price below the floor) and stock-outs.
- Analysts / agencies: catalog velocity (launches, delistings) across a niche, without maintaining scrapers.
How it works
You provide store domains (e.g. gymshark.com). Default mode is monitor: the first run of each store creates a free baseline; every later run diffs the live catalog against the saved state and writes one record per change event. Every monitor run also writes one free STORE_SUMMARY record per store — so a day with no changes still yields "monitored: 631 products checked, 0 changes", which is exactly what a monitor is for. snapshot mode is a one-off full catalog export instead.
You are only charged for change events (or snapshot products) actually written — the free per-store summaries, filtered events and everything discarded by caps cost you nothing.
Input
Copy-paste ready (daily competitor watch):
{"stores": ["gymshark.com", "colourpop.com"],"mode": "monitor","minPriceDeltaPct": 0}
| Field | Type | Default | Description |
|---|---|---|---|
stores | array | required | 1–50 domains or URLs; protocol/www/path stripped automatically |
mode | string | monitor | monitor (change events + free summaries) or snapshot (full export) |
collectionHandle | string | – | Watch a single collection (e.g. best-sellers) instead of the whole catalog |
eventTypes | array | all 5 | Any of PRICE_CHANGE, STOCK_CHANGE, NEW_PRODUCT, REMOVED_PRODUCT, NEW_VARIANT |
minPriceDeltaPct | number | 0 | Ignore price changes smaller than this absolute % — filtered events are free |
maxProductsPerStore | integer | 5000 | Safety cap per store (250/page until the catalog ends) |
maxResults | integer | 5000 | Global cap on charged records. If it truncates a store, that store's diff state is not advanced — nothing is silently lost |
pageDelayMs | integer | 500 | Polite pacing between pages of the same store (floor 250 ms, deliberate) |
Output
One dataset record per change event (recordType: "CHANGE_EVENT"), e.g.:
{"store": "gymshark.com","recordType": "CHANGE_EVENT","eventType": "PRICE_CHANGE","productId": "6806936649930","title": "Gymshark Training Straight Leg Leggings","url": "https://gymshark.com/products/gymshark-training-straight-leg-leggings","variantId": "39799616536778","variantTitle": "XS / Black","oldPrice": 42.0,"newPrice": 21.0,"priceDeltaPct": -50.0,"oldAvailable": true,"newAvailable": true,"detectedAt": "2026-07-30T13:00:00.000Z","previousCheckedAt": "2026-07-29T13:00:00.000Z"}
Plus one free STORE_SUMMARY per store per monitor run (status, productsChecked, variantsChecked, eventCounts, error when the store failed) and, in snapshot mode, one PRODUCT record per product (variants embedded, min/max price, availability).
STOCK_CHANGE events carry stockDirection: RESTOCK or OUT_OF_STOCK. Availability comes from the feed's per-variant available boolean — Shopify does not expose inventory counts publicly, so quantity is out of scope by honesty, not omission.
Schedule it (recommended — cloud, not your desktop)
Diff quality equals run cadence — daily is the intended cadence. Use Apify's own Schedules, not a local scheduler — configure it once and it runs in the cloud whether or not your machine is on.
- Save your input as a Task (Console → this Actor → Create task), e.g. your competitor store list in
monitormode. - Console → Schedules → Create schedule, add the Task, set the cron (e.g. daily 6am →
0 6 * * *). - Route the dataset to Slack, Sheets, your CRM or webhook via Apify integrations.
The first run of each store is a free baseline; every run after it returns only what changed.
Honest limits (read before relying on it)
- Standard Liquid storefronts only. Headless Shopify stores (Hydrogen/custom frontends — e.g. ruggable.com) do not expose
/products.jsonand become a controlledNOT_SHOPIFY_OR_HEADLESSstatus, never a fake result. Password-protected stores likewise (STORE_PASSWORD_PROTECTED); this Actor never logs in. - If a store blocks us (403/430), that is the answer. It becomes a
STORE_BLOCKEDstatus. No proxy rotation against an explicit block, no TLS tricks, no evasion — by design. - Diff quality equals run cadence. Two price changes between runs collapse into one event (oldest→newest). A daily schedule is the intended cadence.
- First run of a store is a baseline (free): state is saved, no events are possible yet.
- One unknown/unsupported store never kills the batch; the run fails only if no store answers (
ALL_STORES_FAILED). - Robots note: the sampled stores'
robots.txtdoes not disallow/products.json(verified 2026-07-30); pacing is polite and identified regardless. Monitoring respects each store's terms — you are responsible for how you use the data.
Ops notes
STATSkey in the run's key-value store: per-store summary (status, pages, products, events by type), HTTP counters, field-completeness health check, warnings.ERRORSon failure.- Diff state lives in the named key-value store
SHOPIFY-MONITOR-STATE, one key per store (+collection). Delete a key to force a fresh baseline for that store. - Typical cost drivers: pages fetched (250 products/page) + records written. A 2-store daily watch (~1,500 products) runs in well under a minute at 512 MB.
FAQ
Do I need a Shopify account or API key? No. The Actor reads each store's public /products.json feed without logging in.
What exactly am I charged for? Per record written to the dataset (Pay Per Event) — everything discarded by filters, windows or caps costs you nothing. The per-store STORE_SUMMARY records are free. The Pricing tab on this page is always the authoritative source for current rates and for any per-run fee.
Can I schedule it? Yes — that is the intended use. See "Schedule it" above.
Is this affiliated with Shopify? No. This is an unofficial community Actor, not affiliated with Shopify Inc. or any store monitored; all data comes from each store's public product feed and remains subject to that store's terms.