Competitor Price, Stock, and Changelog Monitor
Pricing
from $2.13 / 1,000 change rows
Competitor Price, Stock, and Changelog Monitor
Watch competitor stores and SaaS sites and get only what changed since your last run: price, sale price, and stock changes per product, new and removed products, plan price changes on a pricing page, and new changelog entries. Shopify, WooCommerce, and any pricing page. Clay ready.
Pricing
from $2.13 / 1,000 change rows
Rating
0.0
(0)
Developer
Mamba Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 hours ago
Last modified
Categories
Share
Watch a list of competitor stores and SaaS sites and get back only what changed since your last run. For a store you get price, sale price (compare at price), and stock changes per product variant, plus new and removed products. For a SaaS site you get plan and price changes on its pricing page and new entries on its changelog. The first run of a site records a baseline; every later run with the same state key compares against it. Rows are flat, so they export to CSV or drop into a Clay table.
Features
- Only the changes. Each run compares every site with the state saved by the last run. You get one site row per site, with the number of changes found, and one row per change. A site where nothing moved returns a free
no_changerow. - Stores without a scraper per site. Shopify stores are read from their public product feed (
/products.json) and WooCommerce stores from their public Store API, so every variant's price, compare at price, and stock comes from the store's own data. Other stores work from product page URLs you list, read from the schema.org Product data on the page. - SaaS pricing pages. Plan names and their prices are read from the pricing page the site links to. A plan added, removed, or repriced is one row with the old and new text. When prices move and no plan name can be read, one
pricing_page_changerow lists the old and new prices on the page. - Changelogs. The changelog page the site links to is read, through its RSS or Atom feed when it declares one. Every entry not seen before is one row with its title, date, and link.
- Filters. Choose what to watch (prices, stock, products, plans, changelog), set a minimum price change in percent, and cap change rows per site.
- Schedules. Save the input as a task with a
state_key, schedule it daily or weekly, and each run returns only the new changes.
How it reads sites
Pages and feeds are fetched directly, the way a browser would, and robots.txt is read for every host and checked before every request; a page robots.txt disallows is never requested. A host that refuses a direct request is retried through the Apify proxy. No login, no API key, and no other developer's actor. The saved state lives in a key-value store in your own Apify account.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
sites | array | Domains or URLs, up to 200. A URL with a path is read as that page: pricing, changelog, or product | |
site_type | string | auto | auto, shopify, woocommerce, or saas |
watch | array | all five | Any of prices, stock, products, plans, changelog |
product_urls | array | Product pages on a store that is not Shopify or WooCommerce | |
pricing_urls | array | Pricing pages, when the homepage does not link to one | |
changelog_urls | array | Changelog pages, when the homepage does not link to one | |
max_products | string | 250 | Products read per store, up to 5000 |
min_price_change_pct | string | 0 | Report a price change only at or above this percent |
max_changes_per_site | string | 200 | Change rows per site per run, up to 1000 |
include_snapshot | string | false | true to also return every current variant, plan, and changelog entry on a site's first check |
state_key | string | Names the saved state; one key per schedule | |
reset_state | string | false | true to record a new baseline for every site |
max_charge_usd | string | Stop before a row would pass this amount | |
proxy_mode | string | auto | auto (direct, then the Apify proxy for a host that refuses), direct, or residential. A reliability choice |
Every field accepts text, as Clay sends it: "true", "250", a comma separated list, or a JSON array.
Output
One row layout for every row type, so no column is lost between them. Key fields:
| Field | Rows | Example |
|---|---|---|
row_type | all | site_baseline, site_check, change, snapshot, site_error |
site, site_type | all | deathwishcoffee.com, shopify |
change_type | change | price_change, compare_at_price_change, out_of_stock, back_in_stock, new_product, removed_product, plan_added, plan_removed, plan_price_change, pricing_page_change, changelog_entry |
product_title, variant_title, sku, item_id, page_url | store changes | Death Wish Ground Coffee, 16 oz |
old_value, new_value, old_price, new_price, price_change_pct, in_stock | changes | 19.99, 17.99, -10.01, true |
plan_name | plan changes | Business |
changelog_title, changelog_date | changelog entries | Stacked pull requests, 2026-10-07 |
products_tracked, variants_tracked, plans_tracked, changelog_entries_tracked | site rows | 148, 424, 4, 30 |
previous_check_at, changes_found | site check, changes | |
row_status, error_reason, billable_events_json | all | ok, null, {"change-row":1} |
The run summary (key-value store record RUN_SUMMARY) lists baselines, changes by type, unreadable sites, requests, and the hosts that were moved to the proxy.
Pricing
Pay per event. You pay only these events; the Apify platform and proxy costs of your run are paid by Mamba Labs.
| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
Change row (change-row), one change since the last run | $0.0025 | $0.002375 | $0.00225 | $0.002125 |
Site check (site-check), the first check of a site and any later check that finds a change | $0.003 | $0.00285 | $0.0027 | $0.00255 |
Snapshot row (snapshot-row), only with include_snapshot on | $0.001 | $0.00095 | $0.0009 | $0.00085 |
Actor start (apify-actor-start), once per run | $0.0005 | $0.0005 | $0.0005 | $0.0005 |
Free rows: no_change rows for a site where nothing moved since the last run, and site_error rows for a site that could not be read. On the Apify free plan the actor stops at 1.50 USD of evaluation a month (about 600 change rows); any paid Apify plan removes that cap.
Example: a daily run over 20 competitor sites where 4 sites changed, with 15 changes in all, costs 4 site checks ($0.012) plus 15 change rows ($0.0375), $0.0500 with the actor start. The 16 unchanged sites are free.
Usage examples
Apify Console or API
{ "sites": ["deathwishcoffee.com", "linear.app"], "state_key": "competitors-weekly" }
{ "sites": ["allbirds.com"], "watch": ["prices", "stock"], "min_price_change_pct": "5", "max_products": "1000", "state_key": "allbirds-daily" }
{ "sites": ["https://www.notion.com/pricing", "https://linear.app/changelog"], "watch": ["plans", "changelog"] }
Clay
Add an HTTP API or Apify column that sends a competitor domain in sites with a state_key per row, and read change_type, old_value, new_value, and price_change_pct from the change rows.
Scheduled monitoring
Save the input as an Apify task with a state_key and schedule it. Each run returns one row per site and only what changed since the run before; the first run of each new site returns its baseline row.
MCP
The MCP server @mambalabsdev/mcp-competitor-price-stock-changelog-monitor exposes this actor as a tool for Claude and other MCP clients.
Error handling
| Situation | What you get |
|---|---|
| A site refuses every route, or robots.txt disallows the pages | One free site_error row with row_status blocked and the reason |
| No catalog, pricing page, or changelog found | One free site_error row with row_status error |
| One page of a site cannot be read this run | The other parts are compared; the row says partial, and the unread part keeps its saved state for the next run |
A store has more products than max_products | The products read are compared; removed products are not reported for that store |
| The state store cannot be opened | Every site reads as a first check, and the run summary says so |
| Max charge reached | The run stops before the next billable row; the site's state is not saved, so its changes come back on the next run |
Limitations
- A change is only seen if it is still there when the actor runs. A price that moves and moves back between two runs is not reported.
- The Shopify product feed carries no currency, so Shopify rows leave
currencyempty and use the store's display currency. - Pricing pages that draw their prices with scripts after the page loads, or put prices in images, give no plan rows. Such a page reads
partialwith a note. - Plan names are read from the page headings; a page that renames a plan reads as one plan removed and one added.
- Changelog entries are matched by title. An entry whose title is edited reads as a new entry.
- You are responsible for how you use the data and for the terms of the sites you watch.
More from Mamba Labs
Built by Mamba Labs.