Global Price & Stock Intelligence
Pricing
from $2.00 / 1,000 product checkeds
Global Price & Stock Intelligence
Track price and stock of product pages you are allowed to check. Reads schema.org/JSON-LD first, reports PRICE_UP, PRICE_DOWN, BACK_IN_STOCK, OUT_OF_STOCK with evidence, keeps price history and matches the same product across shops.
Pricing
from $2.00 / 1,000 product checkeds
Rating
0.0
(0)
Developer
PRIVATEX
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Security
Limited permissionsShare
Monitor the price and stock of product pages on any shop you are allowed to check. Each run tells you what changed since your previous run: PRICE_UP, PRICE_DOWN, BACK_IN_STOCK, OUT_OF_STOCK, MIXED, UNCHANGED. Every value shows where it came from.
Who needs it
- E-commerce teams watching competitor prices and stock on a schedule.
- Agencies running price checks for several clients, one monitor per client.
- Procurement analysts tracking supplier list prices and availability over time.
What it does
- Reads structured data first. It reads schema.org JSON-LD first, including
@graph,ProductGroupvariants, WooCommercepriceSpecificationandAggregateOffer. Then it tries microdata, then meta tags. Only when none of these exist does it read the page HTML, at lower confidence. - Shows its evidence. Every row has an
evidenceobject per field: the source (json-ld,microdata,metaorhtml), the path, the raw value and a confidence. - Compares with your previous run of the same
monitorNameand keeps a price history (default: 30 observations), with the lowest and highest price seen. - Matches the same product across shops by a valid GTIN, by brand + SKU, or by a
productKeyyou set. Prices are compared per currency only. - Parses prices in many formats:
1.234,56 €,$1,234.56,3.499 TL,1 299,00 zł,CHF 1'299.50. Currencies are reported as ISO codes and are never converted.
What it does NOT do
- It never treats a failed check as out of stock. A timeout, block, 404 or missing data gives
UNAVAILABLE, and your last good price and stock are kept. - It never bypasses blocking. It does not get around anti-bot challenges, CAPTCHAs or logins, and does not use proxies to evade blocks. A site that shows a challenge is skipped for the rest of the run, and the row says so.
- It does not guess. It never guesses stock counts from an "in stock" badge, invents a currency, or converts between currencies.
- It only reads pages. No checkout, no cart, no account pages, no POST requests.
Start in 60 seconds
- Press Start with the prefilled input. It checks three products on public scraping-practice sites (books.toscrape.com, scrapeme.live, webscraper.io).
- Run it again later with the same monitor name. The second run shows
UNCHANGEDor the changes. - Replace the URLs with product pages you are allowed to monitor.
To see every status without fetching anything, empty the URL list (Demo mode is ignored whenever product URLs are given). The demo uses fictional shops, is labelled SYNTHETIC_DEMO and charges no product events (only Apify's automatic $0.00005 start event applies to every run).
Example input
{"products": [{ "url": "https://scrapeme.live/shop/Bulbasaur/" },{ "url": "https://shop.example.com/p/kettle", "productKey": "KETTLE-17" }],"monitorName": "competitor-kettles","perHostDelaySecs": 2}
Example output row
This row is real: cloud run l7Xm4faI9YaIDvxXP, 2026-10-30, a public scraping-practice site.
{"status": "FIRST_SEEN","url": "https://scrapeme.live/shop/Bulbasaur/","title": "Bulbasaur","price": 63,"currency": "GBP","availability": "IN_STOCK","sku": "4391","matchBasis": "URL_ONLY","evidence": {"price": { "source": "json-ld", "path": "offers.price", "raw": "63.00", "confidence": 0.95 },"currency": { "source": "json-ld", "path": "offers.priceCurrency", "raw": "GBP", "confidence": 0.95 },"availability": { "source": "json-ld", "path": "offers.availability", "raw": "https://schema.org/InStock", "confidence": 0.95 }},"errorCode": null,"dataOrigin": "LIVE_FETCH"}
On the second run the same row had "status": "UNCHANGED", "previousPrice": 63 and a price history of 2 observations.
Statuses
| Status | Meaning |
|---|---|
FIRST_SEEN | First successful check in this monitor; it is stored as the baseline. |
UNCHANGED | Same price, currency and stock as the last successful check. |
PRICE_UP / PRICE_DOWN | The price changed. See previousPrice, priceChange and priceChangePct. |
BACK_IN_STOCK / OUT_OF_STOCK | Stock changed between in-stock and out-of-stock or discontinued. |
CURRENCY_CHANGED | The currency differs; prices are not compared. |
PRICE_MISSING | The page no longer shows a price. The old price stays in the history. |
MIXED | More than one change at once. changes lists them. |
UNAVAILABLE | This check failed (errorCode says why). The previous good data is kept. |
Error codes:
| Code | Meaning |
|---|---|
NOT_FOUND | The page doesn't exist (404). |
ACCESS_DENIED | The site refused access. |
ANTI_BOT_CHALLENGE | The site showed an anti-bot challenge; it is not bypassed. |
RATE_LIMITED | The site asked us to slow down. |
HOST_SKIPPED_AFTER_BLOCK / HOST_SKIPPED_AFTER_RATE_LIMIT | Skipped because the same site blocked or rate-limited an earlier request in this run. |
ROBOTS_DISALLOWED | The site's robots.txt disallows this URL. |
ROBOTS_UNREACHABLE | robots.txt couldn't be read, so the site is treated as disallowed. |
TIMEOUT | No answer in time. |
UNSUPPORTED_FORMAT | Not an HTML page. |
PAGE_TOO_LARGE | The page exceeds the size limit. |
EXTRACTION_UNCERTAIN | The page loaded but no price or availability was found. |
INPUT_INVALID | Not a valid public http(s) URL. |
RUN_LIMIT_REACHED | The run's time or charge limit was reached before this URL. |
Output
| Where | What |
|---|---|
| Dataset | One row per product URL, with every field above plus priceHistory, priceHistoryStats, matchKey, confidence, evidence and diagnostics. |
RESULTS_CSV | The main columns as CSV, with a UTF-8 BOM and formula-injection protection. |
MATCH_GROUPS | Products found on several shops, with the lowest price per currency. |
OUTPUT | Run summary: counts by status and error code, duplicates, invalid inputs and billing. |
Run statuses (OUTPUT.status):
SUCCEEDED: every product was checked.PARTIAL_RESULT: some failed or were skipped.FAILED: nothing could be checked. The run is marked failed and your monitor history is untouched.
Pricing
Pay per event:
| Event | Price | When it is charged |
|---|---|---|
product-checked | $0.002 | Once per product page that loaded and yielded a price or availability. |
apify-actor-start | $0.00005 | Once per run, by Apify. |
Examples: 100 products cost $0.20 per run; 1,000 products cost $2.00 per run. Platform usage is included.
These are not charged:
- failed, blocked, robots-disallowed and rate-limited checks;
- duplicate URLs;
- invalid inputs;
- demo runs.
The Actor respects your maximum cost per run. It only fetches as many products as the limit allows; the rest are listed in OUTPUT.counts.skippedForChargeLimit.
Politeness and limits
| Behaviour | Detail |
|---|---|
| robots.txt | Always respected (RFC 9309). This cannot be turned off. |
| Requests to one site | One at a time, with a delay (default 2 s). The site's Crawl-delay wins if it is longer. |
| Sites in parallel | Up to 3 by default. |
| 429 responses | A Retry-After of 30 s or less is honoured once. Otherwise the site is skipped for the rest of the run. |
| Page timeout | 30 s by default. |
| Page size | 8 MB maximum. |
| Products per run | 1,000 maximum. |
Privacy and security
- Only the public product pages you list are fetched.
- Private, internal, loopback and cloud-metadata addresses are refused, on the first request and after every redirect and DNS resolution. Oversized and compressed-bomb responses are cut off.
- Monitor history (prices, stock, timestamps; no page content) is stored in a key-value store named
price-stock-intelligence-statein your Apify account. - The Actor runs with limited permissions.
Scheduling and API
Create a task with your URLs and a fixed monitorName, then schedule it, for example daily. Use onlyChanges: true to get only changed products. Connect the dataset or OUTPUT to Slack, Sheets, Make, Zapier or your API client, and alert on PRICE_DOWN or BACK_IN_STOCK.
Known limitations
- Prices that appear only after JavaScript runs are not seen; no browser is used. These rows show
EXTRACTION_UNCERTAIN. - With several variants on one page, the lowest offer price is reported and
priceRangeis filled. - The HTML fallback takes the first price-styled element after the page title. On pages without structured data this can be wrong; such values have confidence 0.6 or lower and a
HTML_FALLBACK_PRICEdiagnostic. $,¥andkrare ambiguous. They are mapped to USD, JPY or SEK only when the page states no currency, and are flaggedCURRENCY_AMBIGUOUS.
Support
Use the Issues tab on this Actor's page.