Product Price & Stock Monitor — Restock + Drop Alerts
Pricing
from $2.44 / 1,000 products
Product Price & Stock Monitor — Restock + Drop Alerts
Track the price and stock of product pages you list. It reads the store's own structured data (JSON-LD, Shopify, WooCommerce, microdata) and reports price moves, restocks, sales and title changes, with Slack or Discord alerts. $2.50 per 1,000 products checked, plus a fee per change found.
Pricing
from $2.44 / 1,000 products
Rating
5.0
(1)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
Give it product page URLs and get told when the price or stock moves: it checks each page on a schedule, remembers what it saw last time, and writes what changed. Price up or down, back in stock, out of stock, a sale starting or ending, or the title changing under the same link.
It reads the structured data a store publishes about its own products: JSON-LD, Shopify's product JSON, WooCommerce data, or microdata. No HTML selectors to break. The flip side is the honest limit: a store that publishes none of that returns nothing useful, and you get a row saying exactly that.
| Input | Product page URLs, with optional labels |
| Output | One row per product that is new or changed: current price, list price, sale flag, stock, title, and each change with its before and after |
| Ceiling | No fixed cap on the product list, so keep it to what a run can finish |
| Account needed | None from you |
| Price | $2.50 per 1,000 products checked, plus a fee for each change found. The free plan's $5 a month covers about 2,000 checks, fewer when changes are found |
🔍 What Product Price & Stock Monitor does
Each run fetches every product URL, pulls the structured record out of the page, and compares it against the baseline it saved last time. The baseline lives in a named key-value store on your own account, so it survives between scheduled runs.
Six kinds of change are detected, and you can switch each family off: price_change,
back_in_stock, out_of_stock, sale_started, sale_ended and title_change. A title change is
the one people forget to watch, and it is how you catch a listing that has been quietly swapped for a
different product under the same URL.
priceDropThresholdPct is worth understanding before you set it. At the default 0 every price move
is recorded. Set it to 5 and a drop smaller than 5% is not reported, and the baseline still moves
to the new price. So a product sliding 4% a run will never trip a 5% threshold, however far it falls
in total. Price rises are always recorded whatever you set. If you want to catch slow slides, leave
the threshold at 0 and filter on each change's pct yourself.
Alerts go out through webhookUrl. Slack and Discord formats are detected from the URL, and anything
else gets the full JSON payload, which is what Zapier, Make and n8n want.
📋 What data you get from each product you monitor
| What you get | Field |
|---|---|
| A stable key, your label and the URL | target, label, url |
| When it was checked, and how the data was read | checked_at, extraction_status, extraction_method, sync_status |
| The product right now: title, price, currency, list price, sale flag, stock and SKU | current |
| Each change, with its type and before and after values | changes, change_count |
| First time seen, or seen before with something different | is_new, is_changed |
| What went wrong, if anything | error |
▶️ How to scrape product prices and stock on a schedule
- Open Product Price & Stock Monitor and click Try for free.
- Put your product URLs into Products to monitor, one object each, with a
labelyou will recognise in an alert. - Turn Only new / changed since last run off for the first run so you can see the full shape.
- Run it once, check the rows, then turn it back on.
- Paste a Slack or Discord hook into Webhook URL and schedule it.
💰 How much does it cost to scrape product prices and stock?
$2.50 per 1,000 products checked, which is $0.0025 a product. Flat on every Apify plan, no volume tiers. On the free plan, the $5 Apify gives you each month covers about 2,000 checks, fewer in a run that finds changes. When something moves:
| Event | Price |
|---|---|
| Product checked | $0.0025 |
| Restock detected | $0.02 |
| Price, stock, sale-end or title change | $0.015 |
| Sale started | $0.015 |
| Page had no structured data | $0.001 |
| Run that found a change or delivered your webhook | $0.05 |
A product gets at most one change event per run, whatever moved. A URL that answers with an HTTP error is not charged at all, and the quiet-run notice row is free.
📥 What you give it
{"products": [{ "url": "https://www.adafruit.com/product/3055", "label": "Raspberry Pi 3" },{ "url": "https://www.allbirds.com/products/mens-wool-runners", "label": "Wool Runners" }],"priceDropThresholdPct": 0,"onlyNewSinceLastRun": true,"webhookUrl": ""}
| Field | Default | What it is |
|---|---|---|
products | none, required | One object per product: url is required, label is optional and is what appears in your alerts. The form opens with two examples. |
priceDropThresholdPct | 0 | Ignore price drops smaller than this percentage. Read the note above before raising it. |
onlyNewSinceLastRun | true | Emit only new or changed products. Turn it off to get every product's current state every run. |
trackPrice | true | Detect price moves, with the old value and the percentage. |
trackStock | true | Detect back in stock and out of stock. |
trackSalePrice | true | Detect a sale starting or ending, from the compare-at price where the store publishes one. |
trackTitle | true | Detect a title change under the same URL. |
notifyOnRestock | true | Send the webhook when something comes back in stock. |
notifyOnPriceDrop | true | Send the webhook on a price drop, respecting the threshold above. |
webhookUrl | none | Slack, Discord, or any endpoint that wants the JSON. |
proxyConfiguration | on, using Apify's own network | Most stores answer without it. Change it only if a storefront gates you by region. |
📤 What you get back
A real row from a run on 22 August 2026:
{"target": "snap-www.adafruit.com-fda349aa961c","label": null,"url": "https://www.adafruit.com/product/3055","checked_at": "2026-08-22T07:52:20.183033+00:00","extraction_status": "ok","extraction_method": "json-ld","sync_status": "ok","current": {"title": "Raspberry Pi 3 - Model B - ARMv8 with 1G RAM","price": 35,"currency": "USD","list_price": null,"on_sale": false,"availability_raw": "http://schema.org/InStock","in_stock": true,"sku": "3055"},"changes": [],"change_count": 0,"is_new": false,"is_changed": false,"error": null}
| Field | How to read it |
|---|---|
current | The product as it is right now. list_price and on_sale are filled in only where the store publishes a compare-at price. |
changes | One entry per detected move, each with a change_type and the before and after values. Empty when nothing moved. |
extraction_method | json-ld, shopify, woocommerce or microdata, so you can see which source the numbers came from. |
extraction_status | ok, no_structured_data when the page publishes none, or error when the store answered with an HTTP error. |
availability_raw | The store's own wording, kept beside the tidy in_stock boolean so you can check it. |
target | A stable key built from the URL. Use it to join runs together. |
🧾 Reading the output
| Row | How to spot it | Billed |
|---|---|---|
| A product | No _diagnostic key, and an extraction_status | when extraction_status is ok or no_structured_data |
| The run notice | _diagnostic: true and a status | no |
On a quiet run with onlyNewSinceLastRun on, the only row you get is the notice, which reads
status: "no_changes" and counts what was checked. That row is never billed.
Two things to know about status. A URL that answers with an HTTP error comes back with
extraction_status: "error" and is not charged. And a page that answers normally but carries no
structured data comes back as no_structured_data, billed at $0.001, which also covers a consent or
interstitial page that answered in place of the product, so check the URL in a browser if a store you
expect to work reports it.
💡 What people use it for
- Watching a sold-out item and getting a Slack ping the minute it is back, which is what
back_in_stockplusnotifyOnRestockis for. - Tracking another store's list prices across a few dozen product pages, with the threshold at
0so nothing is missed. - Catching a supplier quietly relisting a different item under the same URL, using
title_change. - Watching when seasonal sales start and end across a set of stores, with
sale_startedandsale_ended.
From a Shopify catalogue to restock alerts, in three steps:
- Run Shopify Products Scraper on the
store and keep the
urlof the products you care about. - Paste them into Products to monitor here, one
{"url": ..., "label": ...}each. - Put your Slack or Discord hook into
webhookUrland schedule the run.
🚧 What it does not do
- It needs the store to publish structured product data. No JSON-LD, Shopify, WooCommerce or microdata means no usable row.
- No HTML fallback. That is the design: selectors break silently and give you wrong prices.
- A price-drop threshold moves the baseline anyway, so a slow slide under the threshold is never
reported. Leave it at
0if that matters. - No product search or discovery. You supply the URLs.
- No variant-level tracking. It reads the product record the page publishes, not every size and colour.
- No stock counts, only in stock or not, because most stores publish only that.
- No screenshots and no price history chart. The history is whatever you keep from the rows.
- The product list has no cap in the schema, so a very long list can run out of time. Split it across several scheduled runs.
🧭 Which monitor do you need?
| If you want | Use |
|---|---|
| Restock and price-drop alerts on product pages you name | This one |
| Every product in a Shopify store's catalogue | Shopify Products Scraper |
| Which domains run Shopify, with each store's contact details | Shopify Store Leads |
| Target products with promotions and pickup stock | Target.com Product Scraper |
| Lowe's products with store price, stock and specs | Lowe's Product Scraper |
| Amazon products by keyword or ASIN, with the on-page reviews | Amazon Scraper |
❓ Questions people ask
Will the price monitor work on any store?
Only on stores that publish structured product data, which is most Shopify and WooCommerce shops and a lot of others. Test one URL before you build a list on it.
How does it remember the last price?
A named key-value store on your own account holds the baseline between runs. Nothing is kept on our side.
What happens the first time?
Every product is new, so you get a full snapshot and no change events. Changes start from the second run.
Can I get Slack alerts?
Yes, paste your Slack hook into webhookUrl and the format is picked up automatically. Discord too.
Why did a price drop not alert me?
Check priceDropThresholdPct. A drop under the threshold is suppressed, and the baseline still
moves.
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/structured-product-price-stock-monitor.
Either way the run happens on your Apify account at the same price.
Is monitoring public product pages legal?
They are public pages and the data is what the store publishes about itself. Apify's write-up on the legality of web scraping is a sensible starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and the product URL; the row's
extraction_status and extraction_method usually narrow it down on their own.