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.

FieldTypeWhat it doesDefault
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.

FieldTypeMeaning
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.