# Map Compliance Monitor (`e-commerce/map-compliance-monitor`) Actor

Scrapes advertised prices from retailer product pages and detects Minimum Advertised Price (MAP) violations. Outputs a compliance report with violation details, retailer risk levels, and category breakdowns.

- **URL**: https://apify.com/e-commerce/map-compliance-monitor.md
- **Developed by:** [E Commerce](https://apify.com/e-commerce) (community)
- **Categories:** Automation, E-commerce, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## MAP Compliance Monitor

Automatically scrape advertised prices from retailer product pages and detect **Minimum Advertised Price (MAP) violations** — no manual checking required. Give the actor your MAP policy and a list of retailer URLs, and it returns a full compliance report with violation details, retailer risk scores, and category breakdowns.

---

### What Is MAP Compliance Monitoring?

MAP (Minimum Advertised Price) is a pricing policy brands set to prevent retailers from advertising products below a minimum price. Retailers who violate MAP agreements undercut authorized sellers, erode brand value, and can trigger price wars. Monitoring compliance manually across dozens of retailers and hundreds of SKUs is time-consuming and error-prone. This actor automates the entire process.

---

### What Does This Actor Do?

1. Reads your MAP policy (a JSON array of SKU → price mappings with retailer URLs)
2. Scrapes each retailer product page using CheerioCrawler (fast, HTTP-based)
3. Extracts the advertised price using a universal multi-strategy extractor (JSON-LD schema, meta tags, DOM selectors)
4. Compares advertised price against your MAP price
5. Outputs:
   - Per-violation records (SKU, retailer, prices, violation %, severity)
   - Retailer compliance summary (risk level: High / Medium / Low)
   - Category breakdown (most violated SKUs per category)
   - Full JSON report saved to the Key-Value Store as `MAP_COMPLIANCE_REPORT`

The actor handles strike-through/was-now pricing (ignores old price, uses current), auth-walled prices (flags `requiresAuth: true`), and scraping errors (soft-fail — the run never crashes).

---

### Use Cases

- **Brand protection teams** monitoring authorized retailers weekly or monthly
- **E-commerce managers** verifying compliance after pricing policy updates
- **Wholesale brands** tracking whether distributors honour MAP agreements
- **Marketplace sellers** auditing competitors to identify policy violation patterns

---

### Input Format

The core input is a `mapPolicy` array. Each entry describes one product and lists the retailer URLs to check:

```json
[
  {
    "sku": "TG-1001",
    "upc": "123456789012",
    "productName": "Pro Wireless Headphones",
    "category": "Audio",
    "mapPrice": 299.99,
    "currency": "USD",
    "effectiveDate": "2025-01-01",
    "expirationDate": "2026-12-31",
    "retailers": [
      { "name": "ElectroMart", "url": "https://electromart.com/product/tg1001" },
      { "name": "BargainTech", "url": "https://bargaintech.com/product/tg1001" }
    ]
  }
]
````

**Required fields per entry:** `sku`, `productName`, `mapPrice`, `retailers`\
**Optional fields:** `upc`, `category`, `currency` (default: USD), `effectiveDate`, `expirationDate`

#### Other Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `mapPolicy` | array | — | MAP policy entries (required) |
| `matchingStrategy` | string | SKU | Identifier used in output keying (SKU / UPC / EAN / ASIN) |
| `alertThreshold` | number | 0 | Minimum violation % to report (0 = report every penny below MAP) |
| `maxConcurrency` | integer | 5 | Parallel pages scraped simultaneously |
| `proxyConfiguration` | object | none | Apify proxy settings (recommended for large catalogs) |

***

### Output Format

The actor writes **three datasets** — one per report type — plus a full JSON report in the Key-Value Store.

| Dataset | Name | Contents |
|---------|------|----------|
| Default | (unnamed) | One row per retailer × SKU price check — violations and compliant records |
| Named | `retailer-summary` | One row per retailer with compliance rate, risk level, violation count |
| Named | `category-summary` | One row per category with violation count and most-violated SKU |

All three appear under the run's **Storage** tab in the Apify Console.

#### Dataset 1 — Violation Records (default)

Each row represents one retailer check for one SKU:

```json
{
  "violationId": "VIO-001",
  "sku": "TG-1001",
  "productName": "Pro Wireless Headphones",
  "category": "Audio",
  "mapPrice": 299.99,
  "currency": "USD",
  "retailerName": "ElectroMart",
  "retailerUrl": "electromart.com",
  "advertisedPrice": 279.99,
  "requiresAuth": false,
  "violationAmount": -20.00,
  "violationPercentage": -6.7,
  "severity": "medium",
  "status": "open",
  "productUrl": "https://electromart.com/product/tg1001",
  "detectedAt": "2026-01-15T14:22:00Z"
}
```

**Severity levels:**

- `low` — violation less than 5% below MAP
- `medium` — 5–10% below MAP
- `high` — more than 10% below MAP

#### Dataset 2 — Retailer Compliance Summary (named: `retailer-summary`)

One row per retailer. Use this to rank retailers by risk and identify repeat offenders:

```json
{
  "retailerName": "BargainTech",
  "productsMonitored": 32,
  "violationCount": 5,
  "complianceRate": 84.4,
  "riskLevel": "high",
  "avgViolationAmount": -22.50,
  "repeatedViolator": true
}
```

**Risk levels:** `high` (<90% compliance) · `medium` (90–95%) · `low` (>95%)

#### Dataset 3 — Category Breakdown (named: `category-summary`)

One row per product category. Use this to spot which product lines are most affected:

```json
{
  "category": "Audio",
  "productsMonitored": 52,
  "violationCount": 8,
  "mostViolatedSku": "TG-1001",
  "avgViolationPercentage": -7.2
}
```

#### Key-Value Store — Full Report

All three datasets are also bundled into a single JSON report saved to the Key-Value Store under the key `MAP_COMPLIANCE_REPORT`, with top-level `reportMetadata`, `violations`, `retailerSummary`, and `categorySummary`. Useful for downstream integrations that prefer one file over three datasets.

***

### How to Prepare Your MAP Policy File

1. Export your existing MAP policy from your ERP, spreadsheet, or brand portal
2. Convert to JSON format (see input format above)
3. For each SKU, collect the direct product page URLs from each retailer you want to monitor
4. Paste the JSON array into the `mapPolicy` input field in the Apify Console

**Tip:** Start with your top 20 highest-risk SKUs and 5–10 known retailers to validate the setup before scaling to your full catalog.

***

### Frequently Asked Questions

**Is this legal to use?**\
Yes. The actor scrapes publicly visible advertised prices — the same prices any consumer would see on a product page. It does not bypass authentication, access private data, or violate CFAA. MAP monitoring of public prices is a standard brand-protection practice. Always check the retailer's Terms of Service for your jurisdiction.

**Does it work on Amazon?**\
Yes. Amazon product pages (ASIN URLs like `amazon.com/dp/B0XXXXX`) are supported. Use `matchingStrategy: ASIN` when monitoring Amazon.

**What if a price is behind a login wall?**\
The actor detects common auth-wall patterns and flags those records as `requiresAuth: true`. These are excluded from violation detection since the public advertised price is not visible.

**Can I use this with the Apify API or MCP?**\
Yes. The actor is fully API-compatible. Call it via the [Apify API](https://docs.apify.com/api/v2) or via the Apify MCP server for AI-native integrations.

**How do I schedule automatic monitoring?**\
In the Apify Console, open the actor and click **Schedule** to run it daily, weekly, or monthly. You can also trigger it via the API from your own systems.

**How accurate is the price extraction?**\
The actor uses a layered extraction strategy: JSON-LD structured data (most reliable), meta tags, and DOM selectors. For major retailers (Amazon, Best Buy, Walmart, Target, B\&H, etc.) accuracy is high. For niche or heavily JavaScript-rendered retailers, enable proxies or contact support.

**What happens if a retailer URL changes or returns a 404?**\
The actor records a `NOT_FOUND` error for that entry and continues with the rest of the policy. The run always exits successfully regardless of individual page errors.

**Does it capture historical violation data?**\
Each run produces a timestamped report. Save results across runs in a shared Apify dataset to build a violation history timeline.

**How many SKUs and retailers can I monitor per run?**\
There is no hard limit. For large catalogs (500+ SKUs, 30+ retailers), enable proxies and set `maxConcurrency` to 10–15. A catalog of 500 SKUs × 10 retailers = 5,000 pages typically completes in 20–40 minutes with concurrency 10.

**Can I export results to Excel or CSV?**\
Yes. From the Apify dataset view, click **Export** and select CSV or Excel. You can also call the dataset API with `?format=csv` to integrate into your reporting pipeline.

***

### Pricing

This actor runs on Apify's pay-per-use infrastructure. A typical run of 100 SKUs × 10 retailers (1,000 pages) costs approximately $0.05–$0.15 depending on page complexity and proxy usage. Use Apify Residential Proxies for anti-bot protection on major retailers.

# Actor input Schema

## `brand` (type: `string`):

Your brand name, shown in the Executive Summary of the compliance report (e.g. 'TechGear Electronics'). Optional but recommended for branded reports and emails.

## `mapPolicy` (type: `array`):

Your brand's MAP policy as a JSON array of product entries. The actor reads each entry, visits the retailer URLs listed under it, scrapes the advertised price, and compares it against the MAP price. Each entry must include at minimum: sku, productName, mapPrice, and a retailers array with at least one {name, url} object pointing to the retailer product page. Example: \[{"sku":"TG-1001","productName":"Pro Wireless Headphones","mapPrice":299.99,"currency":"USD","category":"Audio","retailers":\[{"name":"ElectroMart","url":"https://electromart.com/product/tg1001"}]}]. Accepts any retailer URL — the actor uses a universal price-extraction strategy that works across most e-commerce sites. Add as many SKUs and retailers as needed; the actor processes them concurrently.

## `matchingStrategy` (type: `string`):

The product identifier field used to match scraped pages back to MAP policy entries. The actor uses this field when logging and grouping violations — it does not affect which URLs are scraped (URLs are supplied directly in the mapPolicy). Choose the identifier your brand uses internally: SKU is most common for direct-to-retailer relationships, ASIN for Amazon, UPC/EAN for broader retail. Example: select SKU if your MAP policy file uses internal part numbers like TG-1001. Changing this field only affects how violations are keyed in the output; it has no impact on accuracy.

## `alertThreshold` (type: `number`):

The minimum violation percentage required for a price to be reported as a MAP violation. The actor calculates violation% as (mapPrice − advertisedPrice) / mapPrice × 100. Only prices that fall below MAP by at least this percentage are included in the violations list. Example: set to 5 to ignore minor rounding differences and only flag prices that are 5% or more below MAP. Set to 0 (default) to catch every penny below MAP. Recommended: 0–3% for strict enforcement, 5% for high-volume monitoring where minor discounts are tolerated.

## `maxConcurrency` (type: `integer`):

Maximum number of retailer pages scraped simultaneously. The actor opens this many pages in parallel to speed up the run. Example: with 50 retailers and maxConcurrency 10, the actor processes ~10 pages at a time. Higher values finish faster but increase memory usage and the risk of triggering rate limits on retailer sites. Lower values are more polite and less likely to get blocked. Recommended: 5–10 for most brand monitoring use cases. Do not set above 20 unless you have residential proxies configured.

## `proxyConfiguration` (type: `object`):

Proxy settings for scraping retailer pages. Using proxies reduces the chance of being blocked by retailers, especially for high-volume monitoring runs. Example: enable Apify Residential Proxies to rotate IPs automatically across requests. Without proxies the actor uses your server's IP directly, which works for low-volume runs but may get blocked on large catalogs or aggressive retailers. Recommended: enable residential proxies for production monitoring runs with more than 50 SKUs.

## `resendApiKey` (type: `string`):

Resend API key to email the HTML compliance report after each run (for weekly/monthly delivery). Leave empty to skip email — the report is always saved to the key-value store as MAP\_COMPLIANCE\_REPORT\_HTML. Get a key at resend.com.

## `recipientEmails` (type: `array`):

Email addresses to send the compliance report to. Requires a Resend API key. Leave empty to skip email.

## Actor input object example

```json
{
  "brand": "",
  "mapPolicy": [
    {
      "sku": "GS-LEGGING-ONYX",
      "productName": "Gymshark Everyday Seamless Legging",
      "category": "Apparel",
      "mapPrice": 55,
      "currency": "USD",
      "retailers": [
        {
          "name": "Gymshark",
          "url": "https://www.gymshark.com/products/gymshark-everyday-seamless-washed-legging-2-0-gs-onyx-grey-wash"
        }
      ]
    },
    {
      "sku": "ALLBIRDS-WR-BLACK",
      "productName": "Allbirds Wool Runners",
      "category": "Footwear",
      "mapPrice": 110,
      "currency": "USD",
      "retailers": [
        {
          "name": "Allbirds",
          "url": "https://www.allbirds.com/products/mens-wool-runners"
        }
      ]
    },
    {
      "sku": "MVMT-CLASSIC-40",
      "productName": "MVMT Classic Watch 40mm",
      "category": "Accessories",
      "mapPrice": 128,
      "currency": "USD",
      "retailers": [
        {
          "name": "MVMT",
          "url": "https://www.mvmt.com/watches/mens/classic-40mm-40000107-d"
        }
      ]
    }
  ],
  "matchingStrategy": "SKU",
  "alertThreshold": 0,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "recipientEmails": []
}
```

# Actor output Schema

## `violations` (type: `string`):

Per-SKU per-retailer price check records.

## `retailerSummary` (type: `string`):

Per-retailer compliance rate, violation count, and risk level.

## `categorySummary` (type: `string`):

Per-category violation count and most-violated SKU.

## `fullReport` (type: `string`):

All three reports bundled with reportMetadata into a single JSON file.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mapPolicy": [
        {
            "sku": "GS-LEGGING-ONYX",
            "productName": "Gymshark Everyday Seamless Legging",
            "category": "Apparel",
            "mapPrice": 55,
            "currency": "USD",
            "retailers": [
                {
                    "name": "Gymshark",
                    "url": "https://www.gymshark.com/products/gymshark-everyday-seamless-washed-legging-2-0-gs-onyx-grey-wash"
                }
            ]
        },
        {
            "sku": "ALLBIRDS-WR-BLACK",
            "productName": "Allbirds Wool Runners",
            "category": "Footwear",
            "mapPrice": 110,
            "currency": "USD",
            "retailers": [
                {
                    "name": "Allbirds",
                    "url": "https://www.allbirds.com/products/mens-wool-runners"
                }
            ]
        },
        {
            "sku": "MVMT-CLASSIC-40",
            "productName": "MVMT Classic Watch 40mm",
            "category": "Accessories",
            "mapPrice": 128,
            "currency": "USD",
            "retailers": [
                {
                    "name": "MVMT",
                    "url": "https://www.mvmt.com/watches/mens/classic-40mm-40000107-d"
                }
            ]
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("e-commerce/map-compliance-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mapPolicy": [
        {
            "sku": "GS-LEGGING-ONYX",
            "productName": "Gymshark Everyday Seamless Legging",
            "category": "Apparel",
            "mapPrice": 55,
            "currency": "USD",
            "retailers": [{
                    "name": "Gymshark",
                    "url": "https://www.gymshark.com/products/gymshark-everyday-seamless-washed-legging-2-0-gs-onyx-grey-wash",
                }],
        },
        {
            "sku": "ALLBIRDS-WR-BLACK",
            "productName": "Allbirds Wool Runners",
            "category": "Footwear",
            "mapPrice": 110,
            "currency": "USD",
            "retailers": [{
                    "name": "Allbirds",
                    "url": "https://www.allbirds.com/products/mens-wool-runners",
                }],
        },
        {
            "sku": "MVMT-CLASSIC-40",
            "productName": "MVMT Classic Watch 40mm",
            "category": "Accessories",
            "mapPrice": 128,
            "currency": "USD",
            "retailers": [{
                    "name": "MVMT",
                    "url": "https://www.mvmt.com/watches/mens/classic-40mm-40000107-d",
                }],
        },
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("e-commerce/map-compliance-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mapPolicy": [
    {
      "sku": "GS-LEGGING-ONYX",
      "productName": "Gymshark Everyday Seamless Legging",
      "category": "Apparel",
      "mapPrice": 55,
      "currency": "USD",
      "retailers": [
        {
          "name": "Gymshark",
          "url": "https://www.gymshark.com/products/gymshark-everyday-seamless-washed-legging-2-0-gs-onyx-grey-wash"
        }
      ]
    },
    {
      "sku": "ALLBIRDS-WR-BLACK",
      "productName": "Allbirds Wool Runners",
      "category": "Footwear",
      "mapPrice": 110,
      "currency": "USD",
      "retailers": [
        {
          "name": "Allbirds",
          "url": "https://www.allbirds.com/products/mens-wool-runners"
        }
      ]
    },
    {
      "sku": "MVMT-CLASSIC-40",
      "productName": "MVMT Classic Watch 40mm",
      "category": "Accessories",
      "mapPrice": 128,
      "currency": "USD",
      "retailers": [
        {
          "name": "MVMT",
          "url": "https://www.mvmt.com/watches/mens/classic-40mm-40000107-d"
        }
      ]
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call e-commerce/map-compliance-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=e-commerce/map-compliance-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Map Compliance Monitor",
        "description": "Scrapes advertised prices from retailer product pages and detects Minimum Advertised Price (MAP) violations. Outputs a compliance report with violation details, retailer risk levels, and category breakdowns.",
        "version": "0.1",
        "x-build-id": "61tHuNBdWMUTjQ7lK"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/e-commerce~map-compliance-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-e-commerce-map-compliance-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/e-commerce~map-compliance-monitor/runs": {
            "post": {
                "operationId": "runs-sync-e-commerce-map-compliance-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/e-commerce~map-compliance-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-e-commerce-map-compliance-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mapPolicy"
                ],
                "properties": {
                    "brand": {
                        "title": "Brand",
                        "type": "string",
                        "description": "Your brand name, shown in the Executive Summary of the compliance report (e.g. 'TechGear Electronics'). Optional but recommended for branded reports and emails.",
                        "default": ""
                    },
                    "mapPolicy": {
                        "title": "MAP Policy",
                        "type": "array",
                        "description": "Your brand's MAP policy as a JSON array of product entries. The actor reads each entry, visits the retailer URLs listed under it, scrapes the advertised price, and compares it against the MAP price. Each entry must include at minimum: sku, productName, mapPrice, and a retailers array with at least one {name, url} object pointing to the retailer product page. Example: [{\"sku\":\"TG-1001\",\"productName\":\"Pro Wireless Headphones\",\"mapPrice\":299.99,\"currency\":\"USD\",\"category\":\"Audio\",\"retailers\":[{\"name\":\"ElectroMart\",\"url\":\"https://electromart.com/product/tg1001\"}]}]. Accepts any retailer URL — the actor uses a universal price-extraction strategy that works across most e-commerce sites. Add as many SKUs and retailers as needed; the actor processes them concurrently."
                    },
                    "matchingStrategy": {
                        "title": "Matching Strategy",
                        "enum": [
                            "SKU",
                            "UPC",
                            "EAN",
                            "ASIN"
                        ],
                        "type": "string",
                        "description": "The product identifier field used to match scraped pages back to MAP policy entries. The actor uses this field when logging and grouping violations — it does not affect which URLs are scraped (URLs are supplied directly in the mapPolicy). Choose the identifier your brand uses internally: SKU is most common for direct-to-retailer relationships, ASIN for Amazon, UPC/EAN for broader retail. Example: select SKU if your MAP policy file uses internal part numbers like TG-1001. Changing this field only affects how violations are keyed in the output; it has no impact on accuracy.",
                        "default": "SKU"
                    },
                    "alertThreshold": {
                        "title": "Alert Threshold (%)",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "number",
                        "description": "The minimum violation percentage required for a price to be reported as a MAP violation. The actor calculates violation% as (mapPrice − advertisedPrice) / mapPrice × 100. Only prices that fall below MAP by at least this percentage are included in the violations list. Example: set to 5 to ignore minor rounding differences and only flag prices that are 5% or more below MAP. Set to 0 (default) to catch every penny below MAP. Recommended: 0–3% for strict enforcement, 5% for high-volume monitoring where minor discounts are tolerated.",
                        "default": 0
                    },
                    "maxConcurrency": {
                        "title": "Max Concurrency",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of retailer pages scraped simultaneously. The actor opens this many pages in parallel to speed up the run. Example: with 50 retailers and maxConcurrency 10, the actor processes ~10 pages at a time. Higher values finish faster but increase memory usage and the risk of triggering rate limits on retailer sites. Lower values are more polite and less likely to get blocked. Recommended: 5–10 for most brand monitoring use cases. Do not set above 20 unless you have residential proxies configured.",
                        "default": 5
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings for scraping retailer pages. Using proxies reduces the chance of being blocked by retailers, especially for high-volume monitoring runs. Example: enable Apify Residential Proxies to rotate IPs automatically across requests. Without proxies the actor uses your server's IP directly, which works for low-volume runs but may get blocked on large catalogs or aggressive retailers. Recommended: enable residential proxies for production monitoring runs with more than 50 SKUs."
                    },
                    "resendApiKey": {
                        "title": "Resend API key (optional)",
                        "type": "string",
                        "description": "Resend API key to email the HTML compliance report after each run (for weekly/monthly delivery). Leave empty to skip email — the report is always saved to the key-value store as MAP_COMPLIANCE_REPORT_HTML. Get a key at resend.com."
                    },
                    "recipientEmails": {
                        "title": "Recipient emails (optional)",
                        "type": "array",
                        "description": "Email addresses to send the compliance report to. Requires a Resend API key. Leave empty to skip email.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
