# Amazon Buy Box Monitor Agent (`buzzidata/amazon-buybox-monitor-agent`) Actor

Watch ASINs on a schedule. Snapshot Buy Box winner, price, and stock, then emit changed, unchanged, or new verdicts.

- **URL**: https://apify.com/buzzidata/amazon-buybox-monitor-agent.md
- **Developed by:** [Buzzi Data](https://apify.com/buzzidata) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 asin changeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Amazon Buy Box Monitor Agent

Watch [Amazon](https://www.amazon.com) ASINs on a schedule. Each run snapshots the live **Buy Box** winner, price, and stock for a deliver-to ZIP, then compares that snapshot to the last one and emits `changed`, `unchanged`, or `new`.

This is the scheduled sister of the one-shot [Amazon Buy Box + Offers Agent](https://apify.com/buzzidata/amazon-buybox-offers-agent). Use the offers Actor for a single ASIN check with competing landed-cost rows. Use this monitor when you need Apify Schedules, a named watchlist, and a change verdict on every ASIN.

- **Unblocker by default.** Amazon.com production runs use Apify Unblocker, not datacenter IPs.
- **Deliver-to ZIP.** Buy Box, shipping eligibility, and stock follow a real location. Default **92618** (Irvine, CA).
- **Change verdicts.** Each row includes `previous`, `current`, and `changeType`, so you can see whether Amazon or another seller took the box.
- **Honest pay-per-event.** Successful moved or first-seen ASINs charge `asin_changed` at **$0.02**. Successful stable ASINs charge `asin_unchanged` at **$0.01**. Errors and BLOCKED checks are written. They are not billed as those events.

### Why use Amazon Buy Box Monitor Agent

Buy Box ownership, price, and stock change by location and over time. A one-off scrape does not tell you who held the box on the last check.

- **MAP and retail compliance.** Track the live Buy Box owner across scheduled runs, not a catalog list price.
- **Third-party sellers.** See whether Amazon or another seller took the box since yesterday.
- **Agents and automation.** Each ASIN is one structured record with `previous`, `current`, and `changeType`, so workflows can branch.

Apify Schedules, webhooks, the REST API, and proxy rotation are built in. Save an Actor task once, then run it on a cron.

### What data can Amazon Buy Box Monitor Agent extract

| Field | Description |
| --- | --- |
| `asin`, `marketplace`, `watchlistId`, `postalCode`, `productUrl` | Identity of the check |
| `title` | Product title when parsed |
| `fetchedAt` | ISO-8601 timestamp |
| `status` | `ok`, `blocked`, `error`, or `failed` |
| `changeType` | `changed`, `unchanged`, or `new` on success. `null` on failure |
| `changedFields` | `buyBoxSellerId`, `buyBoxPrice`, and/or `inStock` |
| `previous` | Last persisted Buy Box summary, or `null` if this ASIN is new |
| `current` | This run's Buy Box summary (`buyBoxSellerId`, `buyBoxSellerName`, `buyBoxPrice`, `currency`, `inStock`, and related fields) |
| `errorCode`, `errorMessage` | Typed failure. `null` on success |

### How to run the first Buy Box snapshot

Give the Actor ASINs or `/dp/` URLs. For each marketplace × ASIN it applies deliver-to cookies for the postal code, fetches the product page, parses Buy Box seller, price, and stock, compares against the named watchlist snapshot, then writes a dataset row with `previous`, `current`, and `changeType`. Failed checks are written with a typed error (`BLOCKED`, `RATE_LIMIT`, `PARSE`, `NETWORK`) and are never billed as `asin_changed` or `asin_unchanged`.

1. Open the Actor in [Apify Console](https://console.apify.com).
2. Paste ASINs or product URLs. Keep marketplace `com`, postal code `92618`, and `monitorMode` on.
3. Set a stable `watchlistId` (default `default`). You will reuse this ID on the schedule.
4. Leave `proxyGroup` on **UNBLOCKER** unless you need sticky residential IPs for ZIP cookies.
5. Start the run. The first successful check for each ASIN is `changeType: new` and writes the baseline snapshot.

### How to schedule Amazon Buy Box watches

State lives in the named key-value store (`buybox-monitor-{watchlistId}`), not in the run dataset. Deleting that store resets every ASIN to `changeType: new`.

1. Run the Actor once in Console with your ASINs, marketplace, ZIP 92618, `monitorMode` on, and a stable `watchlistId`. Confirm the first run wrote baselines (`changeType: new`).
2. Open [Schedules](https://console.apify.com/schedules) and click **Create new**. Name it, for example `buybox-watch-daily`.
3. Set the timezone (DST is supported). Example cron: `0 8 * * *` for every day at 08:00.
4. Click **Add** and select this Actor. Reuse the **same input JSON**, especially the same `watchlistId`. Different catalogs need different IDs so stores do not collide.
5. Optional: save an [Actor task](https://docs.apify.com/platform/actors/running/tasks) with that input, then schedule the task instead of pasting JSON on the schedule.
6. Enable the schedule. The minimum interval is 10 seconds. Hourly or daily is enough for Buy Box watches.
7. Optional: add a webhook on the task for `SUCCEEDED` so agents pull dataset items only when the run finished.

### How much does Amazon Buy Box monitoring cost

Pay-per-event charges apply on successful checks only:

| Event | When it fires | Price | When it does not fire |
| --- | --- | --- | --- |
| `asin_changed` | Successful check and Buy Box seller, price, or stock moved, or first snapshot (`new`) | **$0.02** | Errors. `BLOCKED`. `dryRun: true` |
| `asin_unchanged` | Successful check and seller, price, and stock are stable | **$0.01** | Errors. `BLOCKED`. `dryRun: true` |

See the [Store pricing tab](https://apify.com/buzzidata/amazon-buybox-monitor-agent/pricing) for current list prices and platform start events.

`onlyChanges` only filters dataset output. A stable successful check still charges `asin_unchanged` and still overwrites the snapshot.

`dryRun: true` parses, writes items, and persists snapshots without charging `asin_changed` or `asin_unchanged`.

### Input

See the input tab for full configuration options.

| Field | Type | Default | Notes |
| --- | --- | --- | --- |
| `asins` | `string[]` | | 10-character ASINs |
| `productUrls` | `string[]` | | Amazon URLs. ASIN extracted from `/dp/` and related paths |
| `marketplace` | `com` | `co.uk` | `de` | `com` | Storefront TLD |
| `postalCode` | string | `92618` | Deliver-to ZIP or postal code. Alias: `zipCode` |
| `monitorMode` | boolean | `true` | Compare to the last snapshot and emit verdicts |
| `watchlistId` | string | `default` | Named snapshot store suffix |
| `onlyChanges` | boolean | `false` | Skip pushing `unchanged` rows (still persist and charge) |
| `proxyGroup` | `UNBLOCKER` | `RESIDENTIAL` | `UNBLOCKER` | Production default. Select `RESIDENTIAL` as a sticky-IP fallback |
| `dryRun` | boolean | `false` | Write items and snapshots, do not charge |
| `proxyConfiguration` | proxy | widget RESIDENTIAL + US | Console widget. The real default is `proxyGroup=UNBLOCKER`, which overrides this |

At least one parseable ASIN (from `asins` or `productUrls`) is required.

```json
{
    "asins": ["B014I8SSD0", "B004U3Y8OM"],
    "marketplace": "com",
    "postalCode": "92618",
    "monitorMode": true,
    "watchlistId": "default",
    "onlyChanges": false,
    "proxyGroup": "UNBLOCKER"
}
```

#### Why `postalCode` defaults to 92618

Amazon Buy Box, shipping eligibility, and stock copy are location-specific. If deliver-to is unset, the page often still has a title but the Buy Box is missing and availability becomes "cannot be shipped to your selected delivery location". The Actor sets location cookies before `/dp/`. Default **92618** is Irvine, CA, a US deliver-to example. Use a local postcode for `co.uk` or `de`.

### Proxy

Amazon.com blocks datacenter and AUTO Apify Proxy groups. **Unblocker is the recommended Amazon.com production default.** Residential US is a fallback when you need sticky IPs so deliver-to ZIP cookies hold across hops.

Set `proxyGroup` to `UNBLOCKER` or `RESIDENTIAL`. Do not put `UNBLOCKER` on `proxyConfiguration.apifyProxyGroups`. That widget field is overridden by `proxyGroup`.

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. One dataset item per marketplace × ASIN (unless `onlyChanges` drops a stable row).

```json
{
    "asin": "B014I8SSD0",
    "marketplace": "com",
    "watchlistId": "default",
    "postalCode": "92618",
    "productUrl": "https://www.amazon.com/dp/B014I8SSD0",
    "title": "Example product",
    "fetchedAt": "2026-09-09T11:00:00.000Z",
    "status": "ok",
    "changeType": "changed",
    "changedFields": ["buyBoxSellerId", "buyBoxPrice"],
    "previous": {
        "buyBoxSellerId": "A1F83G8C2ARO7P",
        "buyBoxSellerName": "Amazon.com",
        "buyBoxPrice": 12.99,
        "currency": "USD",
        "inStock": true
    },
    "current": {
        "buyBoxSellerId": "A3P5ROKL5A1OLE",
        "buyBoxSellerName": "Example 3P Seller",
        "buyBoxPrice": 11.49,
        "currency": "USD",
        "inStock": true
    },
    "errorCode": null,
    "errorMessage": null
}
```

Each item is JSON with `status`, typed `errorCode`, nested `previous` / `current`, and `changeType`. Point a client at the default dataset (`{{links.apiDefaultDatasetUrl}}/items`) or run the Actor from the [API tab](https://apify.com/buzzidata/amazon-buybox-monitor-agent/api). Failed checks remain in the dataset so you can retry only `BLOCKED` or `RATE_LIMIT` without being billed for those attempts.

#### Error codes

| Code | Meaning |
| --- | --- |
| `BLOCKED` | CAPTCHA, robot check, or automated-access interstitial |
| `RATE_LIMIT` | HTTP 429/503 or throttle copy |
| `PARSE` | HTML loaded but title or Buy Box could not be extracted |
| `NETWORK` | Timeouts, DNS, connection errors, other 4xx/5xx |

### Risks and limitations

- **Amazon ToS.** Scraping Amazon storefronts may violate Amazon's terms. Use this Actor only where you have a lawful basis. This is not an official Amazon API.
- **Blocking.** Datacenter IPs are frequently CAPTCHA'd. This Actor defaults to Apify Unblocker and retries CAPTCHA or throttle pages with a new session before writing `BLOCKED` or `RATE_LIMIT`. The Actor does not execute JavaScript. Some A/B Buy Box layouts hydrate late and will surface as `PARSE`.
- **Selector drift.** Amazon A/B-tests Buy Box markup. Selectors are centralized in the Actor.
- **Stock is heuristic.** `inStock` is derived from availability copy, not warehouse quantity.
- **Unblocker is not sticky.** If deliver-to ZIP does not hold, switch `proxyGroup` to `RESIDENTIAL`.

### FAQ

#### How is this different from Amazon Buy Box + Offers Agent?

The [Amazon Buy Box + Offers Agent](https://apify.com/buzzidata/amazon-buybox-offers-agent) is one-shot: Buy Box plus All Offers Display landed-cost rows. This Actor persists snapshots and emits change verdicts for Schedules.

#### Does onlyChanges skip billing?

No. `onlyChanges` only filters dataset output. A stable successful check still charges `asin_unchanged` and still overwrites the snapshot.

#### What happens on the first scheduled run?

If the watchlist is empty, every successful ASIN is `changeType: new` and is billed as `asin_changed`. Later runs compare against that baseline.

#### How do I test without charges?

Set `dryRun: true`. The Actor still parses, writes dataset items, and persists snapshots.

### Support

Questions, blocks, or feature requests: use the [Issues](https://apify.com/buzzidata/amazon-buybox-monitor-agent/issues/open) tab. Programmatic runs: see the [API](https://apify.com/buzzidata/amazon-buybox-monitor-agent/api) tab.

### License

Apache-2.0

# Actor input Schema

## `asins` (type: `array`):

Amazon ASINs to watch (10-character identifiers). Duplicate ASINs are checked once per marketplace.

## `productUrls` (type: `array`):

Amazon product URLs. The Actor extracts the ASIN from `/dp/`, `/gp/product/`, `/gp/aw/d/`, or an `asin=` query parameter.

## `marketplace` (type: `string`):

Amazon marketplace TLD used for every ASIN in this run.

## `postalCode` (type: `string`):

Deliver-to ZIP or postal code for Buy Box, shipping eligibility, and stock. The Actor applies Amazon location cookies before fetching product pages. Without a deliver-to location, Amazon often hides the Buy Box or shows that the item cannot be shipped. Default 92618 is Irvine, CA. Use a local postcode for amazon.co.uk or amazon.de. Accepts US ZIP (for example 92618) and alphanumeric UK and DE postcodes. Alias: `zipCode` in JSON input is treated the same.

## `monitorMode` (type: `boolean`):

When true (default), compare this run's Buy Box snapshot to the last snapshot for the same watchlistId, ASIN, and marketplace, then emit changeType changed, unchanged, or new. When false, still snapshot and persist, but skip comparison and treat each successful check as new.

## `watchlistId` (type: `string`):

Named watchlist used to persist snapshots in a key-value store (`buybox-monitor-{watchlistId}`). Use a stable ID on Apify Schedules so later runs can compare. Letters, digits, and hyphens only after sanitization. Default: default.

## `onlyChanges` (type: `boolean`):

When true, the dataset skips `changeType: unchanged` rows. Snapshots are still saved, and successful unchanged checks still charge asin\_unchanged. Errors and BLOCKED rows are still written.

## `dryRun` (type: `boolean`):

Parse, write dataset items, and persist snapshots as usual, but never charge `asin_changed` or `asin_unchanged`. Use this to test without billing.

## `proxyGroup` (type: `string`):

Choose which Apify Proxy product to use. UNBLOCKER is the recommended Amazon.com production default (CAPTCHA bypass, billed in Unblocker units). Choose RESIDENTIAL when you need sticky US IPs so deliver-to ZIP cookies hold (billed per GB). This field overrides the proxy widget below.

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

Optional Console proxy widget. The Amazon.com production default is proxyGroup=UNBLOCKER, which overrides this widget. Choose RESIDENTIAL on proxyGroup when you need sticky US IPs. Datacenter and AUTO IPs are often CAPTCHA'd. Set useApifyProxy to false only for local debugging.

## Actor input object example

```json
{
  "asins": [
    "B014I8SSD0",
    "B00MNV8E0C",
    "B004U3Y8OM"
  ],
  "productUrls": [
    "https://www.amazon.com/dp/B014I8SSD0"
  ],
  "marketplace": "com",
  "postalCode": "92618",
  "monitorMode": true,
  "watchlistId": "default",
  "onlyChanges": false,
  "dryRun": false,
  "proxyGroup": "UNBLOCKER",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset items: previous and current Buy Box summaries plus changeType.

# 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 = {
    "asins": [
        "B014I8SSD0",
        "B00MNV8E0C",
        "B004U3Y8OM"
    ],
    "productUrls": [
        "https://www.amazon.com/dp/B014I8SSD0"
    ],
    "postalCode": "92618",
    "watchlistId": "default",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("buzzidata/amazon-buybox-monitor-agent").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 = {
    "asins": [
        "B014I8SSD0",
        "B00MNV8E0C",
        "B004U3Y8OM",
    ],
    "productUrls": ["https://www.amazon.com/dp/B014I8SSD0"],
    "postalCode": "92618",
    "watchlistId": "default",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("buzzidata/amazon-buybox-monitor-agent").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "asins": [
    "B014I8SSD0",
    "B00MNV8E0C",
    "B004U3Y8OM"
  ],
  "productUrls": [
    "https://www.amazon.com/dp/B014I8SSD0"
  ],
  "postalCode": "92618",
  "watchlistId": "default",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call buzzidata/amazon-buybox-monitor-agent --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,buzzidata/amazon-buybox-monitor-agent"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/D8olLx4EEHzaFfyBD/builds/Y58tlJk1JszOqeya4/openapi.json
