# MAP Monitoring: Find Minimum Advertised Price Violations

> How to monitor MAP: list every seller of your products from Google Shopping and retailer pages, flag advertised prices below MAP, and keep timestamped evidence.

- URL: https://datatooly.xyz/guides/map-price-monitoring/
- Author: Omar Eldeeb (https://datatooly.xyz/about/)
- Published: 2026-10-20
- Updated: 2026-10-20
- Free tool: [E-commerce price tracker — scrape product prices, stock and variants](https://datatooly.xyz/ecommerce-price-tracker/)
- Tags: ecommerce, python, webscraping, pricing

MAP monitoring means listing every seller that advertises your products, comparing each advertised price with your minimum advertised price, and logging every price below it with the seller, the time and a link. Collect sellers per product from Google Shopping's seller list and from retailer pages, filter out used and refurbished offers, and run it daily so you have dated evidence, not screenshots from memory.

This guide does that with the Google Shopping "Sellers" mode and retailer URLs of [E-commerce Product Scraper Pro](https://apify.com/constructive_calm/ecommerce-product-scraper-pro?fpr=v77kxu), using real seller data for the Sony WH-1000XM5 collected on 2026-10-18 and 2026-10-20. It isn't legal advice.

## What MAP is (and isn't)

A minimum advertised price (MAP) policy is a brand's rule about the lowest price its resellers may advertise for a product. This guide uses the US context. The US Federal Trade Commission's guide on [manufacturer-imposed requirements](https://www.ftc.gov/advice-guidance/competition-guidance/guide-antitrust-laws/dealings-supply-chain/manufacturer-imposed-requirements) describes the typical form from a dealer's point of view, where a dealer "can't participate if I advertise a price that is below the supplier's minimum advertised price", and says "the law allows a manufacturer considerable leeway in setting the terms for advertising that it helps to pay for". The same page notes the FTC challenged MAP policies of five large music distributors that it found unreasonable in reach. Policies differ, so what counts as "advertised" and what happens after a violation comes from your own policy, and its legal side is a question for your lawyer.

For monitoring, three practical points follow:

- **Advertised is not the same as sold.** A retailer can show "see price in cart" and charge less at checkout. Monitoring catches what's shown.
- **Condition matters.** Check whether your policy covers refurbished, renewed and used offers; either way, tag them and keep them apart from new ones.
- **Not every seller is in scope.** You probably don't police the brand's own store, and some sellers may be authorised for promotions. Keep an exempt list.

## Source 1: Google Shopping's seller list

Google Shopping groups offers from many stores under one product, and the actor's **Sellers** mode reads that list: merchant, price, old price, stock, condition, delivery, returns and the offer link, one entry per store. It's the fastest way to see sellers you didn't know about, including stores this actor can't scrape directly (Best Buy, eBay, Lowe's and Newegg pages are unsupported, but they appear in Google's seller lists, which is a different page).

The input from a run on 2026-10-18:

```json
{
  "searchEngineKeyword": "Sony WH-1000XM5",
  "scrapeModeSearchEngine": "Sellers",
  "countryCode": "us",
  "maxSearchEngineProducts": 4,
  "maxSearchEngineSellersPerProduct": 5,
  "maxSearchEngineResults": 20
}
```

`searchEngineKeyword` takes up to 50 lines, one search each. Use your exact model name, or the model number, so Google groups the right product.

One output row, trimmed (the offer links are long `google.com/goto` redirects to each store's offer):

```json
{
  "recordType": "search-result",
  "keyword": "Sony WH-1000XM5",
  "title": "Sony WH-1000XM5 Noise-Canceling Wireless Headphones",
  "priceInsight": "Typically $199–$300",
  "lowestOfferPrice": 228,
  "sellerCount": 4,
  "sellers": [
    { "merchantName": "Store A", "price": 228, "originalPrice": 398, "inStock": true, "condition": null, "bestPrice": true, "url": "https://www.google.com/goto?url=…" },
    { "merchantName": "Sony", "price": 228, "originalPrice": 400, "inStock": true, "condition": null },
    { "merchantName": "Store B", "price": 299, "inStock": null, "condition": null },
    { "merchantName": "Target", "price": 398.99, "inStock": true, "condition": null }
  ],
  "scrapedAt": "2026-10-18T09:14:51.617Z"
}
```

The other three products in that run included a Target "refurbished" offer at $189.99 and an Electronic Express offer tagged `used`: seller badges such as "Refurbished" and "Used" are split out of the merchant name into `condition`.

## Source 2: retailer and marketplace pages

Google's list is a summary. To confirm on the retailer's own page, or to cover marketplace sellers Google doesn't show, scrape the product pages and searches directly on supported sites (Amazon, Walmart, Target, Shopify and WooCommerce stores, and the rest of the README matrix):

```json
{
  "detailsUrls": [{ "url": "https://www.amazon.com/dp/B09XS7JWHH" }],
  "listingUrls": [{ "url": "https://www.walmart.com/search?q=sony+wh-1000xm5" }],
  "maxItemsPerStartUrl": 3,
  "maxProductResults": 4
}
```

Run on 2026-10-20, it returned the Amazon listing at $199.99 and three Walmart marketplace listings with their `seller` field: "Video & Audio Center" at $288, "Electronic Express" at $298 (pink), and a "Restored" unit from "Secondipity" at $147.26. Product rows have no `condition` field, so for direct pages filter by title words such as "Restored", "Renewed" or "Refurbished", and by the URL (Walmart's restored listing carried `conditionGroupCode=2`).

## Flag violations and keep evidence

This reads a Sellers-mode run, skips used/refurbished offers and exempt merchants, flags prices below MAP, and appends every flag to a CSV evidence log:

```python
"""Flag sellers advertising below your MAP in a Google Shopping "Sellers" run. pip install apify-client"""
import csv
import os
import sys

from apify_client import ApifyClient

MAP_USD = {"Sony WH-1000XM5": 250.00}        # made-up MAP for the example; use your policy's figures
EXEMPT = {"Sony"}                             # merchants you don't police (e.g. the brand's own store)

run = ApifyClient(os.environ["APIFY_TOKEN"]).run(os.environ["RUN_ID"])
rows = run.dataset().list_items(clean=True).items

violations = []
for row in rows:
    if row.get("recordType") != "search-result":
        continue
    map_price = MAP_USD.get(row["keyword"])
    for s in row.get("sellers") or []:
        if s.get("condition"):                 # "refurbished", "used": skip unless your policy covers them
            continue
        if s["merchantName"] in EXEMPT or s.get("currency") != "USD" or s.get("price") is None:
            continue
        if map_price and s["price"] < map_price:
            violations.append({
                "checked_at": row["scrapedAt"], "keyword": row["keyword"], "listing": row["title"],
                "merchant": s["merchantName"], "advertised": s["price"], "map": map_price,
                "gap_pct": round(100 * (s["price"] - map_price) / map_price, 1),
                "was_price": s.get("originalPrice"), "offer_link": s["url"], "google_page": row["url"],
                "run_id": os.environ["RUN_ID"],
            })

w = csv.DictWriter(sys.stdout, fieldnames=["checked_at", "merchant", "advertised", "map", "gap_pct", "listing"],
                   extrasaction="ignore")
w.writeheader()
w.writerows(violations)
if violations:                                 # append the full rows to your evidence log
    new_file = not os.path.exists("map_evidence.csv")
    with open("map_evidence.csv", "a", newline="", encoding="utf-8") as f:
        log = csv.DictWriter(f, fieldnames=list(violations[0]))
        if new_file:
            log.writeheader()
        log.writerows(violations)
```

Output for the 2026-10-18 run (`RUN_ID=FiUR4s8DgTfDEE02e`):

```text
checked_at,merchant,advertised,map,gap_pct,listing
2026-10-18T09:14:51.617Z,Store A,228,250.0,-8.8,Sony WH-1000XM5 Noise-Canceling Wireless Headphones
```

**The $250 MAP is made up for this example, and the merchant names are replaced with "Store A" and "Store B".** Sony's actual policy, if it has one for this model, isn't public, and nothing here says any retailer broke one. With that test number, the script flagged one offer and correctly skipped: Sony's own store (exempt), Target's and Electronic Express's refurbished/used offers (condition), and the offers at or above $250.

`map_evidence.csv` keeps the full record for each flag: `checked_at`, `keyword`, `listing`, `merchant`, `advertised`, `map`, `gap_pct`, `was_price`, `offer_link`, `google_page` and `run_id`. That's the core of what a MAP enforcement email needs. For a stronger record:

- **Confirm on the seller's page** for supported retailers (Source 2) before you act, and store that row too. Google's price can lag the store's.
- **Keep the raw rows.** Export each run's dataset (JSON or CSV) to your own storage instead of relying on the run being kept on Apify.
- **Add a screenshot** if your policy process needs one. The actor doesn't take screenshots, so use a browser tool on the flagged links.
- **Log repeats.** The same seller below MAP on three consecutive daily checks is a different conversation from a one-hour glitch.

## Schedule and cost

Save the Sellers input as a task and add an [Apify schedule](https://docs.apify.com/platform/schedules?fpr=v77kxu), for example `0 9 * * *` (09:00 daily in the schedule's timezone).

The actor is pay per event. In the README's pricing table, a Google Shopping request costs $0.0045 on FREE and $0.0035 on GOLD (billed per successful request; failed ones aren't billed), a seller row $0.0024 and $0.0008, and the run start $0.005. The 2026-10-18 run billed 4 search-engine requests and 9 seller rows:

- FREE: 4 × $0.0045 + 9 × $0.0024 + $0.005 = **$0.0446**
- GOLD: 4 × $0.0035 + 9 × $0.0008 + $0.005 = **$0.0262**

In Sellers mode each product costs one extra Google request, so cost grows with `maxSearchEngineProducts` × keywords, plus one seller row per store listed. Use `maxSearchEngineSellersPerProduct` to cap the long tail. Apify's free plan gives $5 of usage a month with no credit card; the actor has no in-actor free trial.

## During Black Friday and the holiday season

MAP pressure peaks when everyone discounts. Some brands also suspend or relax MAP for a set window, a "MAP holiday". For example, board-game publisher Iello suspended its MAP for Black Friday weekend in 2017, letting retailers "advertise games at prices below 20% off MSRP" ([ICv2](https://icv2.com/articles/news/view/38996/iello-suspends-map-policy)). If your policy has such a window, put its dates and temporary floor into the check instead of flagging authorised promotions. For the busiest window, add a second schedule to the same task such as `0 */3 20-30 11 *`, every three hours from 20 to 30 November 2026 (88 runs in `America/New_York`; at the run size above, 88 × $0.0446 = $3.92 on FREE or 88 × $0.0262 = $2.31 on GOLD per keyword). Black Friday is Friday 27 November and Cyber Monday 30 November 2026. The [holiday sales calendar](https://datatooly.xyz/guides/holiday-sales-calendar-price-tracking/) has every event's window, and [comparing Black Friday prices across stores](https://datatooly.xyz/guides/black-friday-google-shopping-price-comparison/) uses the same Google Shopping data from the shopper's side.

## Limits

- Google Shopping's "Reviews" mode isn't available, and an answer for the wrong market gets one retry and is then reported as blocked (not billed). Google may truncate long product titles.
- Direct checks only work on supported sites; Best Buy, eBay, Home Depot, Lowe's, Costco and Newegg pages are not supported.
- Google's grouping isn't perfect: listings for different colours, bundles or the previous model can share a search. Check `title` before you send anything.

Related: [competitor price monitoring](https://datatooly.xyz/guides/competitor-price-monitoring-scraper/), [price drop alerts in Slack](https://datatooly.xyz/guides/price-drop-alerts-email-slack/), and the [e-commerce price tracker query builder](https://datatooly.xyz/ecommerce-price-tracker/).

*Disclosure: I built the actor and this site. The flagging and evidence logic works with seller data from any source.*

Sources: [FTC: Manufacturer-imposed requirements](https://www.ftc.gov/advice-guidance/competition-guidance/guide-antitrust-laws/dealings-supply-chain/manufacturer-imposed-requirements), [ICv2: Iello suspends MAP policy (2017)](https://icv2.com/articles/news/view/38996/iello-suspends-map-policy), [E-commerce Product Scraper Pro README](https://apify.com/constructive_calm/ecommerce-product-scraper-pro?fpr=v77kxu) (Sellers mode, pricing, supported sites, limitations), [Apify docs: Schedules](https://docs.apify.com/platform/schedules?fpr=v77kxu), and actor runs on 2026-10-18 and 2026-10-20.

## Quick answers

### What is a MAP violation?

A reseller advertising a product below the minimum advertised price that the brand's MAP policy sets. What counts as 'advertised' (a product page, a feed to Google Shopping, an email, a price shown only in the cart) and what happens next are defined by each brand's own policy, not by a single standard.

### Is MAP the same as the price a retailer can sell at?

No. MAP limits the price a reseller advertises. Policies typically leave the actual selling price to the retailer, which is why some retailers show 'see price in cart'. Check the wording of the specific policy, and ask a lawyer about how it applies to you.

### How do brands find MAP violators?

They list the sellers of each product (Google Shopping's seller lists, marketplace offer pages, retailer sites), compare each advertised price with the MAP, and log every violation with a timestamp, the seller, the price and a link, typically on a daily schedule. Paid MAP-monitoring services do this as a managed product; you can also script it.

### Do refurbished or used listings count toward MAP?

It depends on the wording of the policy. Either way, separate condition in your data: the Sellers mode output in this guide tags refurbished and used offers in a `condition` field so they aren't mixed in.

## Related guides

- [Retail Sales Calendar 2026-2027: When to Track Prices](https://datatooly.xyz/guides/holiday-sales-calendar-price-tracking/)
- [Amazon Price History Without Keepa: Build Your Own](https://datatooly.xyz/guides/amazon-price-history-without-keepa/)
- [Amazon Price Scraper: Prices by ASIN on Any Marketplace](https://datatooly.xyz/guides/amazon-price-scraper-asin/)
- [Back in Stock Alert Scraper: Products, Sizes, Colours](https://datatooly.xyz/guides/back-in-stock-alert-scraper/)
- [Back to School Price Tracker: Tax Holidays & Laptops](https://datatooly.xyz/guides/back-to-school-price-tracker/)
- [Compare Black Friday Prices Across Stores (Google Shopping)](https://datatooly.xyz/guides/black-friday-google-shopping-price-comparison/)
- [Black Friday Price Tracker: Watch 2026 Prices Daily](https://datatooly.xyz/guides/black-friday-price-tracker/)
- [Boxing Day Sales Tracker UK 2026: Prices in GBP](https://datatooly.xyz/guides/boxing-day-sales-price-tracker-uk/)
- [Christmas Price Tracker: When to Buy Gifts Cheapest](https://datatooly.xyz/guides/christmas-price-tracker/)
- [Competitor Price Monitoring: Scraper Setup and Cost](https://datatooly.xyz/guides/competitor-price-monitoring-scraper/)
- [Cyber Monday Price Tracker: Hourly Checks for Nov 30](https://datatooly.xyz/guides/cyber-monday-deal-tracker/)
- [Grocery Price Tracker: Build a Basket Index in Python](https://datatooly.xyz/guides/grocery-price-tracker-scraper/)
- [Price Drop Alerts to Slack or Email with a Scraper](https://datatooly.xyz/guides/price-drop-alerts-email-slack/)
- [Prime Day Price Tracker: ASINs, Big Deal Days, 2027](https://datatooly.xyz/guides/prime-day-price-tracker/)
- [Ramadan Sale Price Tracker 2027: Noon & Amazon UAE](https://datatooly.xyz/guides/ramadan-eid-sales-price-tracking/)
- [Scrape Product Prices with Python from JSON-LD](https://datatooly.xyz/guides/scrape-product-prices-json-ld-python/)
- [Scrape Product Reviews from Walmart, Target and Amazon](https://datatooly.xyz/guides/scrape-product-reviews-walmart-target-amazon/)
- [Scrape Product Variants: Sizes, Colors and Price per SKU](https://datatooly.xyz/guides/scrape-product-variants-sizes-colors/)
- [Fake Black Friday Deals: Check the Real Discount](https://datatooly.xyz/guides/spot-fake-black-friday-discounts/)
- [Apify E-commerce Scraping Tool Alternative: Same Input](https://datatooly.xyz/guides/switch-from-apify-ecommerce-scraping-tool/)
- [When Do Black Friday Prices Drop? The 2026 Timeline](https://datatooly.xyz/guides/thanksgiving-black-friday-price-drop-timeline/)
- [Walmart and Target Price Scraper: Search and Product Pages](https://datatooly.xyz/guides/walmart-target-price-scraper/)
- [White Friday & 11.11 Tracker: Noon and Amazon UAE Prices](https://datatooly.xyz/guides/white-friday-11-11-noon-amazon-uae-prices/)
- [Shopify products.json Pagination: 250 Limit and the 25,000 Cap](https://datatooly.xyz/guides/shopify-products-json-pagination/)
- [AI Share of Voice: Measure It in ChatGPT and Perplexity](https://datatooly.xyz/guides/ai-share-of-voice-chatgpt-perplexity/)
