MAP Price Violation Monitor & Alerts
Monitor your product list across retailer sites and get alerted the moment a price drops below your MAP (minimum advertised price).
Monitor your product list across retailer sites and get alerted the moment a price drops below your MAP (minimum advertised price). Stateful: alerts only on new violations, deeper cuts and recoveries — never repeats. Works on Shopify, WooCommerce, BigCommerce, Magento and custom shops. GDPR-clean.
$3.00 / 1,000 · 100.0% success over 27 public runs in the last 30 days.
Run it on Apify → Free to try - runs bill per result on your own account.
What you give it
Every field is optional unless marked; sensible defaults do the rest.
| Field | Type | What it does | Default |
|---|---|---|---|
products |
array | REQUIRED. Your product list as JSON: one entry per retailer product page, each with url (the product page), mapPrice (your minimum advertised price), optional currency (ISO code, default USD) and optional label. Example: [{ "url": "https://shop.example.com/products/widget", "mapPrice": 129.95, "label": "Widget Pro" }]. Up to 500 products per run. Tip: the README has a copy-paste AI prompt that converts a pasted price list or spreadsheet into this JSON. | [{"url": "https://www.clarionsafety.com/products/safety-signs/hazardous-material-signs/chemical-hazard-signs/warning-corrosive-materials-sign-f1243", "mapPrice": 5, "currency": "USD", "label": "Demo \u2014 Warning sign F1243 (demo MAP $5)"}, {"url": "https://jococups.com/usa/product/12oz-joco-cup/", "mapPrice": 19, "currency": "USD", "label": "Demo \u2014 JOCO Cup 12oz (demo MAP $19)"}, {"url": "https://monin.com/us/vanilla-syrup", "mapPrice": 10, "currency": "USD", "label": "Demo \u2014 Monin Vanilla 750 ml (MAP $10)"}] |
alertOn |
string | What counts as an alert. 'violations' alerts when a product newly drops below its MAP or an existing violation cuts deeper. 'violations-and-recoveries' additionally alerts when a violating product returns to or above MAP. | violations |
emitBaseline |
boolean | On the first run for a product, push its current price as a baseline item (flagged isBaseline, charged at the low baseline price). Turn off to seed silently: the first run then records state without pushing items. | True |
resetState |
boolean | Discard everything this monitor remembers and start over: the next run is a fresh baseline for every product. Use after large catalog or MAP policy changes. | False |
maxItems |
integer | Upper bound on items pushed per run. Alerts are pushed before baseline snapshots, so a low cap never hides a violation. Transitions that do not fit alert on the next run. | 500 |
stateStoreName |
string | Named key-value store holding what the monitor has already seen. Use a different name per independent monitor (e.g. one per brand) so their memories never mix. | map-monitor-state |
reportFailures |
boolean | When a run fails, send the developer the actor name and build, an error category, the error message (truncated) and a one-way hash of your input - so a bug can be fixed without anyone asking you to reproduce it. Your input itself, your results and your identity are never sent, and successful runs send nothing at all. Switch this off and the actor behaves exactly the same. | True |
What you get back
One JSON object per result, with exactly these fields - no seller identities, no contact data, ever.
| Field | Type | Meaning |
|---|---|---|
productUrl |
string | The monitored product page URL, exactly as provided in the input. |
label |
['string', 'null'] | Your label for this product from the input, if provided. |
retailer |
string | Retailer domain the price was read from. |
productName |
['string', 'null'] | Product name as published on the page's structured data, when available. |
status |
string | Check outcome. 'violation' = advertised below your MAP. 'unreadable' = the page exposes no trustworthy structured price (never guessed, never charged). 'unreachable' = the page could not be fetched. 'currency-mismatch' = page currency differs from the input currency. |
isViolation |
boolean | True when the advertised price is below your MAP. |
isBaseline |
boolean | True on the first check of a product: a price snapshot that seeds the monitor, not a transition alert. |
isUpdate |
boolean | True for every non-baseline item: the situation changed since the last run (new violation, deeper cut, recovery, or check-status change). |
advertisedPrice |
['number', 'null'] | The price a shopper currently sees on the page. For multi-variant products this is the lowest advertised variant (see priceIsVariantLow). |
priceHigh |
['number', 'null'] | Highest advertised variant price when the page advertises a range; null for single-price products. |
priceIsVariantLow |
boolean | True when advertisedPrice is the low end of a variant price range rather than a single price. |
currency |
string | ISO currency of mapPrice and advertisedPrice, from your input. |
currencyVerified |
boolean | True when the page itself confirmed the currency; false when the page exposes only an ambiguous symbol or none and your input currency was assumed. |
mapPrice |
number | Your minimum advertised price for this product, from the input. |
deltaAbs |
['number', 'null'] | advertisedPrice minus mapPrice. Negative = advertised below MAP (the violation depth). |
deltaPct |
['number', 'null'] | deltaAbs as a percentage of mapPrice, rounded to 2 decimals. Negative = below MAP. |
availability |
string | Stock status when the page's structured data exposes it. |
priceSource |
['string', 'null'] | Which extraction path read the price: json-ld, shopify-json, price-meta, microdata or woo-markup. Structured sources (json-ld) are the most reliable. |
checkedAt |
string | ISO timestamp of this check. |
note |
['string', 'null'] | Why a page was unreadable/unreachable or which currencies conflicted; null on clean reads. |
Health
100.0% success over 27 public runs in the last 30 days. Live record, failures included: status page.
Full documentation, examples and the AI-assistant prompt live on the store page.