Shopify Price Tracker & Stock Monitor (Price Drops, Restocks)
Pricing
from $0.80 / 1,000 products
Shopify Price Tracker & Stock Monitor (Price Drops, Restocks)
Watch any list of Shopify stores. Get every product's price, compare-at price, and stock by variant, and on every later run only what changed: price drops and rises, stock-outs, restocks, new and removed products. Public product feed, no login. From $0.80 per 1,000 products.
Pricing
from $0.80 / 1,000 products
Rating
0.0
(0)
Developer
Upward Enterprises
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Shopify Price Tracker & Stock Monitor
$1 per 1,000 products ($0.80 on the Gold tier), $0.002 per changed product, $0.005 per store checked. First run of a store and any store that cannot be read are free.
Give it a list of Shopify stores. It returns every product's current price, compare-at price, and stock, variant by variant, and on every run after the first it tells you exactly what changed: price drops and rises, stock-outs, restocks, new products, removed products. Schedule it daily or hourly and pipe the changes to Slack, Google Sheets, Airtable, or a webhook.
It reads the public product feed every Shopify store publishes. No login, no HTML scraping, no bot tricks: one polite request a second per store, with a named User-Agent. Stores that refuse automated access are reported as blocked, not worked around.
What you get
All rows land in one dataset with a kind field: product, change, or store. Product rows come first for each store, then its change rows, then its store summary. The Console views Products and Changes pick the useful columns for each kind; filter on kind to keep one kind, for example ?clean=true&view=changes and then keep rows where kind is change.
Product rows (kind: "product"), one per product:
{"kind": "product","store": "allbirds.com","productId": "6540182913104","handle": "mens-wool-runners","title": "Men's Wool Runners","vendor": "Allbirds","productType": "Shoes","tags": ["men", "wool"],"url": "https://allbirds.com/products/mens-wool-runners","price": 98,"priceMax": 110,"compareAtPrice": 120,"onSale": true,"available": true,"variantCount": 14,"availableVariantCount": 11,"options": ["Size", "Color"],"imageCount": 6,"image": "https://cdn.shopify.com/s/files/.../wool-runner.jpg","description": "Our original everyday sneaker, made with soft merino wool ...","createdAt": "2024-03-01T09:00:00-08:00","updatedAt": "2026-09-08T10:12:44-07:00","publishedAt": "2024-03-02T09:00:00-08:00","checkedAt": "2026-09-09T18:00:00.000Z","variants": [{ "id": "39400", "title": "8 / Natural Grey", "sku": "WR-8-NG", "price": 98, "compareAtPrice": 120, "available": true, "options": ["8", "Natural Grey"], "grams": 620, "updatedAt": "2026-09-08T10:12:44-07:00" }],"changes": [ { "change": "price_down", "variantTitle": "8 / Natural Grey", "from": 110, "to": 98, "deltaPct": -10.91 } ]}
available is true when any variant is in stock, false when every variant reports out of stock, and null when the store does not publish availability. description is the first 500 characters of the product description as plain text.
Change rows (kind: "change"), one per change since your last run of the same snapshot:
{"kind": "change","store": "allbirds.com","productId": "6540182913104","handle": "mens-wool-runners","title": "Men's Wool Runners","url": "https://allbirds.com/products/mens-wool-runners","variantId": "39400","variantTitle": "8 / Natural Grey","sku": "WR-8-NG","change": "price_down","from": 110,"to": 98,"delta": -12,"deltaPct": -10.91,"detectedAt": "2026-09-09T18:00:00.000Z"}
change | Meaning |
|---|---|
price_down, price_up | A variant's price moved. from, to, delta, deltaPct are filled in. |
out_of_stock, back_in_stock | A variant's availability flipped. from and to are booleans. |
compare_at_change | The strike-through price changed (a sale started or ended). |
new_product, removed_product | A product appeared in or vanished from the store. Product-level rows have no variant fields. |
new_variant, removed_variant | A size or color was added or dropped. |
Store rows (kind: "store"), one per store, after its other rows:
{"kind": "store","store": "allbirds.com","origin": "https://allbirds.com","inputStore": "allbirds.com","status": "ok","message": null,"products": 294,"variants": 2857,"changes": 3,"pages": 2,"complete": true,"firstRun": false,"removedProducts": [ { "productId": "6540182913104", "handle": "mens-wool-runners", "title": "Men's Wool Runners" } ],"checkedAt": "2026-09-09T18:00:00.000Z","durationMs": 4120}
status | Meaning |
|---|---|
ok | The feed was read. complete says whether the whole catalog was seen (false when the product cap stopped paging). |
partial | Some products were read, then a later page failed. Rows for the products read are delivered; removals are not reported and the baseline is not updated. |
blocked | The store refuses automated access (401, 403, 430, a long rate-limit, or a bot challenge page). |
not_shopify | No product feed at this address: not a Shopify storefront, or the feed is disabled. |
duplicate | This address resolves to a store already checked in the same run. |
error | Network failure or a server error after a retry. |
message carries the reason for anything other than a clean ok. If a store answers from a different host than you typed (a www. redirect, a new domain), store and origin show the host that answered and inputStore what you typed; the snapshot is kept under the host that answered.
Input
| Field | What it does |
|---|---|
| Stores to watch | Domains or URLs, one per line. Any page of the store works. |
| What to deliver | Products and changes (default), products only, or changes only. In products-only mode, removed products are listed on the store row instead of as change rows. |
| Max products per store | Paging stops after this many. Default 2,000. If a store has more products than this, additions and removals cannot be told apart from products beyond the cap, so those are not reported; raise the limit to cover the whole catalog. |
| Include variants | Attach every variant with its own price, SKU, and availability. Default on. |
| Snapshot name | Which memory to compare against; kept on your account as a key-value store named shopify-price-monitor-<name>. Give each schedule its own name. Lower-case letters, digits, and hyphens; other characters become hyphens. Do not run two schedules on the same name at the same time. |
| Reset snapshot | Forget the remembered prices for these stores and start a new baseline; no change rows this run. |
| Delay between requests | Default 1,000 ms per page. Faster bursts get rate-limited by many stores. |
The first run for a store is the baseline: product rows (in the two modes that deliver them) and no change rows. Every later run compares against the remembered prices, which live compressed in a key-value store on your own Apify account under the snapshot name. Before reporting a product as removed, the Actor checks its page once more, so a product that merely moved between feed pages is not reported.
Pricing
| Event | Free and Bronze | Silver | Gold and above |
|---|---|---|---|
| Product | $0.001 | $0.0009 | $0.0008 |
| Changed product | $0.002 | $0.0018 | $0.0016 |
| Store checked | $0.005 | $0.0045 | $0.004 |
A changed product is billed once per run however many of its variants moved; the extra variant rows are delivered free and marked billed: false. So a run can never cost more than about twice its catalog: a store-wide sale on a 300-product store is at most $0.60. A store's first, baseline run and any store that could not be read (blocked, not Shopify, duplicate, error) are free. Watching five stores with 300 products each once a day, changes only, costs $0.025 a day plus $0.002 per changed product; on a quiet day that is under a cent. Delivering all 1,500 product rows too adds $1.50 a run. Set a maximum total charge on the run to cap spend; the Actor stops cleanly when it is reached and never delivers rows it could not bill. A run that stops early does not overwrite a store's baseline.
Use cases
- Competitor price tracking for a DTC brand: a daily changes-only run into a Slack channel.
- Resellers and arbitrage: watch for restocks and price drops across a set of suppliers.
- Catalog snapshots: a weekly products run into a spreadsheet for merchandising reviews.
- AI agents: ask "what did competitor X change this week" through the Apify MCP server and get rows, not screenshots.
Limits and honesty
- Prices come from the store's public feed in the store's own currency; the feed does not include currency codes or customer-specific pricing.
- Stores behind a bot wall are reported as
blocked. The Actor does not retry with a browser identity. - Stores that have disabled the product feed, or that are not on Shopify, are reported as
not_shopify. - Very large catalogs: memory use is about 1 KB per product, so 50,000 products per store fits the default memory.
- At the end of each run the Actor reports run counts (rows delivered, events charged, duration, status) to its maintainer's dashboard. It never sends your input, your results, or anything about your account.
About
Built and maintained by Upward Enterprises Ā· AI & API Services (Iowa, USA). Public-data tools for people and AI agents, with pay-per-record pricing and no keys to manage.
Changelog
- 0.1 (2026-09-10): first release.