WooCommerce & Shopify Price and Stock Change Monitor avatar

WooCommerce & Shopify Price and Stock Change Monitor

Pricing

from $0.50 / 1,000 product checkeds

Go to Apify Store
WooCommerce & Shopify Price and Stock Change Monitor

WooCommerce & Shopify Price and Stock Change Monitor

Monitor WooCommerce and Shopify stores for price, sale and stock changes, new and removed products. Outputs only the changes, with old and new values, ready for webhooks, n8n and Make.

Pricing

from $0.50 / 1,000 product checkeds

Rating

0.0

(0)

Developer

Uniano

Uniano

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

18 hours ago

Last modified

Categories

Security

Limited permissions

Share

Price & Stock Change Monitor: only what changed, with old and new value

Track competitor prices, sales and stock on WooCommerce and Shopify stores and get only what changed since the last run: old value, new value, product link, SKU and currency. No full catalogue dumps to diff yourself, no spreadsheets to compare.

Schedule it daily (or hourly) and send the changes to Slack, Google Sheets, n8n, Make or Zapier.

Quick start

  1. Add store URLs. Paste a store home page, a category or collection, or single product links. WooCommerce and Shopify are detected automatically.
  2. Run once. The first run saves a baseline of every product, so the dataset shows one Baseline saved row per store.
  3. Schedule it. Add a schedule (for example, daily at 06:00) with the same input. Every next run lists only what changed. Add a webhook to get the changes in n8n, Make, Zapier or a Slack message.

A second run looks like this:

Example output: sale started, sold out, back in stock and price changes on the Shopify Dawn demo store

What it detects

Change typeExample
price_changed25.00 → 19.99 (−20.04 %)
sale_started / sale_ended8.00 → 6.00 when a sale starts
sale_price_changed / regular_price_changedsale price or the crossed-out price changes during a sale
stock_status_changedout_of_stock → in_stock (back in stock), in_stock → backorder
stock_quantity_changed3 → 1 (WooCommerce stores that show the remaining quantity)
product_added / product_removeda new product appears, a product disappears
currency_changedthe store switched currency

Use cases

  • Competitor price tracking: see every price move of your competitors the morning after it happens.
  • Stock alerts: know when a competitor sells out (a chance to raise your price) or when a product is back in stock.
  • MAP monitoring: watch your own SKUs at resellers' WooCommerce/Shopify stores and catch prices below the minimum advertised price. Use the SKU filter and "minimum price change".
  • New product launches: get product_added for every new item in a competitor's catalogue or collection.

How it works

  1. You enter store URLs (whole catalogue), category/collection URLs, or single product URLs.
  2. The Actor detects the platform and reads the store's public product feed: WooCommerce Store API (/wp-json/wc/store/v1/products) or Shopify /products.json. These are JSON endpoints that the platforms publish for storefronts; no login and no HTML scraping.
  3. First run = baseline. The current state is saved in a named key-value store and the dataset gets one summary item per store, not hundreds of "new product" rows.
  4. Every next run compares the store with the saved snapshot and writes only the changes, plus one summary per store.
  5. Optionally, one JSON payload with all changes is POSTed to your webhook.

Schedule the Actor in Apify (Schedules → e.g. every day at 06:00). Keep the same input and the same "Snapshot store name" so each run compares with the previous one.

Input

FieldWhat it does
Store or product URLshttps://store.com (whole catalogue), https://store.com/product-category/hoodies/, https://store.com/collections/sale, https://store.com/product/blue-hoodie/, https://store.com/products/blue-hoodie. Mix stores and platforms freely.
Max products per storeUpper limit per store and run (default 1,000). Shopify variants count as products.
Categories / collectionsOnly check products in these WooCommerce categories (slug or ID) or Shopify collections (handle).
SKUsOnly check these SKUs (case-insensitive).
Change types to reportLeave empty for all.
Minimum price change (%)Ignore small price moves, e.g. 2 %.
Webhook URLReceives one JSON POST per run with all changes.
Report all products on the first runOutput every product as product_added on the first run instead of a silent baseline.
Include unchanged productsAlso output the full current state of every product (type: "unchanged").
Reset baselineStart over with a new baseline.
Snapshot store nameSeparate watchlists, e.g. competitors-de and resellers-map.

Example input:

{
"startUrls": [
{ "url": "https://competitor-one.com" },
{ "url": "https://competitor-two.myshopify.com/collections/sale" },
{ "url": "https://reseller.com/product/blue-hoodie/" }
],
"maxProductsPerStore": 2000,
"minPriceChangePercent": 1,
"webhookUrl": "https://your-n8n.example.com/webhook/price-changes"
}

Output

Every dataset item has a type: change, summary, error (or unchanged if enabled). Two table views are ready in the Output tab:

  • Changes: what changed, product, before and now (with currency), store and product link. Each store's block ends with its summary row.
  • Run summary: the result per store and, if a store could not be read, what went wrong and how to fix it.

Every item also carries the same ready-to-show text fields for your own reports: label ("Price ↓ 20.04%", "Back in stock", "Baseline saved"), productName, oldDisplay / newDisplay ("25.00 EUR", "In stock"), storeName, message and productUrl. They are empty strings where they do not apply (for example, productName on a summary), never null; on summary and error items productUrl links to the store.

A change item:

{
"type": "change",
"label": "Price ↓ 20.04%",
"changeType": "price_changed",
"store": "https://shop.example.com",
"storeName": "shop.example.com",
"platform": "woocommerce",
"productId": "10",
"variantId": null,
"productName": "Blue Hoodie",
"productUrl": "https://shop.example.com/product/blue-hoodie/",
"sku": "HOOD-BLUE",
"currency": "EUR",
"field": "price",
"oldValue": 25,
"newValue": 19.99,
"priceDiff": -5.01,
"priceDiffPercent": -20.04,
"direction": "down",
"price": 19.99,
"regularPrice": 19.99,
"salePrice": null,
"onSale": false,
"stockStatus": "in_stock",
"stockQuantity": null,
"oldDisplay": "25.00 EUR",
"newDisplay": "19.99 EUR",
"message": "",
"detectedAt": "2026-11-03T06:00:12.000Z",
"previousCheckAt": "2026-11-02T06:00:09.000Z",
"watchKey": "t_5b0c2f1e9a7d43c8b1e2f0aa"
}

A summary item (one per store and run):

{
"type": "summary",
"label": "7 changes",
"store": "https://shop.example.com",
"storeName": "shop.example.com",
"platform": "woocommerce",
"platformName": "WooCommerce",
"productName": "",
"productUrl": "https://shop.example.com",
"oldDisplay": "",
"newDisplay": "",
"status": "changes_detected",
"isBaseline": false,
"productsChecked": 7,
"changesDetected": 7,
"changesByType": { "price_changed": 1, "sale_ended": 1, "sale_started": 1, "stock_status_changed": 1, "stock_quantity_changed": 1, "product_added": 1, "product_removed": 1 },
"capReached": false,
"budgetReached": false,
"errors": 0,
"message": "7 changes since 2026-11-02 06:00 UTC (7 products checked)."
}

status is baseline_created, changes_detected, no_changes or failed. Stores that cannot be read produce an error item with a code (NOT_A_SUPPORTED_STORE, API_BLOCKED, API_DISABLED, RATE_LIMITED, HTTP_ERROR, NETWORK_ERROR, …) and a hint. The other stores in the run are processed normally.

Webhooks, n8n, Make, Zapier

With a Webhook URL, the Actor POSTs once per run when something changed or a store or product could not be read (for example, a store started blocking requests). Turn on "Send webhook even without changes" to get it after every run:

{
"event": "store_change_monitor.run_finished",
"schemaVersion": 1,
"text": "Store Change Monitor: 3 changes in 2 stores.\n• Blue Hoodie (shop.example.com): Price ↓ 20.04%, 25.00 → 19.99 EUR\n…",
"actorRunId": "…",
"runUrl": "https://console.apify.com/actors/runs/…",
"datasetUrl": "https://console.apify.com/storage/datasets/…",
"checkedAt": "2026-11-03T06:00:00.000Z",
"totals": { "stores": 2, "productsChecked": 340, "changes": 3, "errors": 0 },
"summaries": [ … ],
"errors": [ … ],
"changes": [ … ],
"changesTruncated": false
}

The changes items are the same as in the dataset (up to 500 per payload; the dataset always has all of them). text is a ready-made plain-text summary (up to 10 change lines and a link to the run) that you can drop into a Slack, Telegram, Teams or email step as is. runUrl and datasetUrl link to the run in Apify Console. schemaVersion changes only if the payload shape changes in an incompatible way.

  • n8n: Webhook node → Slack node with {{$json.body.text}}, or "Split Out" on changes → Google Sheets / IF changeType = price_changed and priceDiffPercent < −10.
  • Make / Zapier: "Custom webhook" trigger, then iterate over changes.
  • You can also use Apify's own integrations (Slack, Google Drive, email) on the dataset.

Pricing

Pay per event, you only pay for what is checked and found:

  • $0.50 per 1,000 products checked (Shopify: per variant)
  • $1.00 per 1,000 changes detected

Examples: a store with 500 products checked daily costs about 500 × 30 × $0.0005 = $7.50 per month plus changes. 10 changes a day add about $0.30 per month. The first (baseline) run is billed only for products checked.

Set a maximum cost per run in the run options. The Actor stops cleanly at your limit. If the limit cuts the change list, the snapshot is not advanced, so the remaining changes are reported in the next run.

Limits (please read)

  • Only WooCommerce and Shopify stores whose public product feed is enabled. Some stores disable the WooCommerce Store API or protect /products.json. You then get an API_BLOCKED or API_DISABLED error item, not wrong data.
  • No bypassing: the Actor does not log in, use proxies to evade blocks, solve CAPTCHAs or scrape HTML. It identifies itself with an honest User-Agent and waits between requests.
  • Shopify stock is in/out of stock only. Shopify's public feed does not expose quantities.
  • WooCommerce variable products are tracked at product level (lowest variation price and overall stock status), not per variation.
  • WooCommerce quantities appear only if the store shows them (e.g. "3 in stock" or low-stock notices).
  • Product cap: when "Max products per store" is reached, removed products are not reported for that store, because the rest of the catalogue was not read.
  • 0 products returned by a store that had products before is treated as a temporary problem: nothing is reported as removed, and you get an EMPTY_CATALOGUE error item.
  • Prices are what the public feed shows (usually the guest price incl./excl. tax as configured by the store). Customer-group or logged-in prices are not visible.

FAQ

Why didn't my first run output any products? The first run saves the baseline: you see one Baseline saved row per store. Run it again or add a schedule, and the next run lists only the changes. Turn on "Report all products on the first run" or "Include unchanged products" if you need a full list.

Can I monitor single products? Yes. Use product links in the standard format: WooCommerce /product/<slug>/ or ?p=<id>, Shopify /products/<handle>. Links of the same store are checked together.

Does it collect personal data? No. Only product data (name, URL, SKU, prices, stock) is read. No customers, reviews or orders.

Where is the snapshot? In the named key-value store from the input (default store-change-monitor-snapshots), one record per store and filter set. Changing filters starts a new baseline for that combination.

Found a bug or a store that should work but doesn't? Please open an issue with the store URL.