# Amazon Buy Box Monitor (`s-r/amazon-buybox`) Actor

- **URL**: https://apify.com/s-r/amazon-buybox.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** E-commerce, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

Give it a list of ASINs and it returns who currently wins the Amazon buy box on each one: the featured offer's price, the merchant selling it, who fulfils it, the delivery promise, and every alternative buying option pinned on the page.

No login, no cookie, no API key. It reads the ordinary product page an anonymous shopper sees, on any of 15 marketplaces, with the exit country pinned so the price is the one that market really shows.

### What you get

- **The buy box winner**, as `sold_by` and `ships_from`, which is the pair that tells you whether Amazon itself, the brand, or a third-party reseller owns the sale
- **Every alternative buying option**, not just the winner. New, used and renewed rows each come back with their own price, seller, condition, delivery promise and returns policy
- **A `page_state` that explains itself.** A product with no offer is not the same as a variation parent waiting for a size to be chosen, which is not the same as a Prime Video title that has an ASIN but nothing to buy. Six named states instead of a silent empty row
- **Price in the marketplace's own currency**, because the exit is pinned to that country. An unpinned request returns whatever currency the proxy landed in
- **`scraped_at` on every row**, so consecutive runs build the time series that makes buy box data worth anything
- **Delivery and fastest-delivery promises**, parsed per option, which is usually the reason a more expensive seller is winning
- **Labels understood in nine languages**, so `sold_by` is populated on amazon.de and amazon.co.jp rather than only on the English sites
- **No actor-start fee.** A run that returns nothing costs nothing

### Why monitor the Amazon buy box

The buy box decides the sale. A shopper who presses Add to Cart buys from whoever holds it, and on a contested listing that can change several times a day as sellers reprice against each other. If you sell on Amazon, losing it is a revenue event you want to know about in minutes. If you are a brand, an unfamiliar name in `sold_by` is how you find out someone is reselling your product without permission.

Amazon publishes none of this through an API you can point at a competitor's listing. The Selling Partner API answers questions about your own account, not about the market, and the buy box winner is a rendering decision made on the product page itself. Reading that page is the only way to see it.

What almost every existing tool gets wrong is treating the answer as a snapshot. A single check tells you who holds the buy box right now, which is close to useless. The value is in the series: who held it yesterday, at what price, and what changed when they lost it. That is why this actor returns a timestamp on every row and is built for small, frequent, cheap runs rather than one big sweep.

### Input

| Field | Type | Required | Default | What it does |
|---|---|---|---|---|
| `asins` | array | yes | `["B0DJGDC3BD"]` | ASINs or full Amazon product URLs. URLs are reduced to their ASIN |
| `marketplace` | select | no | `com` | Which Amazon site, and therefore the currency and exit country |
| `limit` | integer | no | `50` | ASINs per run, 1 to 200 |
| `retries` | integer | no | `4` | Retry attempts per product, each with a rotated user agent and TLS fingerprint |

### Output

```json
{
  "asin": "B0DJGDC3BD",
  "url": "https://www.amazon.com/dp/B0DJGDC3BD",
  "marketplace": "com",
  "title": "Amazon Fire TV Stick HD (newest model), free & live TV",
  "page_state": "buybox",
  "num_options": 1,
  "price": 17.99,
  "price_text": "$17.99",
  "currency": "$",
  "condition": "new",
  "sold_by": "Amazon.com",
  "ships_from": "Amazon.com",
  "availability": "In Stock",
  "in_stock": true,
  "delivery": "FREE delivery Thursday, September 4",
  "fastest_delivery": "Or fastest delivery Tomorrow, September 1",
  "returns": "30-day refund/replacement",
  "max_quantity": 3,
  "add_to_cart": true,
  "buying_options": [{ "label": "Buy new", "price": "$17.99", "sold_by": "Amazon.com" }],
  "scraped_at": "2026-08-31T18:42:07Z"
}
```

### Use cases

**Knowing within the hour that you lost the buy box.** Schedule your own ASINs hourly and alert when `sold_by` changes away from you. The row also carries the winning price, so the alert tells you not just that you lost it but by how much you were undercut, which is the number you need before you reprice.

**Finding unauthorised sellers on your own listings.** Run your catalogue weekly and collect the distinct values of `sold_by` per ASIN. Anyone in that set who is not you and not an authorised distributor is a problem you cannot see from Seller Central. `buying_options` widens the net further, because it lists sellers who are visible on the page without holding the buy box.

**Watching a competitor's pricing.** Their ASINs, your schedule. Because `price` is a number and `scraped_at` is a timestamp, two weeks of runs is a price history nobody sells you. `ships_from` tells you whether they are on FBA, which is usually what decides who wins at equal price.

**Cross-market price comparison.** The same ASIN on `com`, `co.uk` and `de` returns three rows with three currencies, each priced as that market actually sees it. Running the same list against several marketplaces is the cleanest way to find where a product is mispriced.

### How it compares

| | this actor | `junglee/Amazon-crawler` | the buy box clones |
|---|---|---|---|
| Per 1.000 products | **$4,50** | $5,00 | mostly unpriced |
| Actor-start fee | **none** | none | varies |
| Buy box winner (`sold_by` / `ships_from`) | **yes** | partial | yes |
| All alternative buying options | **yes** | offers list | no |
| Explains why a page has no offer | **6 named states** | no | no |
| Timestamp per row for a time series | **yes** | no | no |
| Non-English marketplaces | **9 label languages** | limited | no |
| 30-day run failure rate | 0% across validation runs | **10,8%** | – |

Honest about the other side: `junglee/Amazon-crawler` has 1.843 monthly users and returns search results and category crawls that this actor does not do at all. It is a broader product scraper. This one answers a single question properly.

The nearest direct competitors are five near-identical buy box actors, none above four monthly users, and none of them keeps state between runs.

### Pricing

One event. `asin` costs $0,0045 per product checked, which is $4,50 per 1.000. ASINs that do not resolve or stay blocked are never written to the dataset and are therefore never billed. All pricing is pay-per-event. No actor-start fee, no per-compute-unit charges, and a run that returns nothing costs nothing.

### Limits and gotchas

- **Not every ASIN is a retail product.** Prime Video, Kindle and Music titles have ASINs and answer on `/dp/`, but there is nothing to buy. Those come back as `page_state: not_a_product` rather than an empty buy box.
- **A variation parent pins nothing until a size or colour is chosen.** Those return `page_state: select_variant`. Pass the child ASIN of the specific variant you care about.
- **`page_state: see_all_buying_options`** means Amazon showed no featured offer at all, only a link to the offer listing. That is a real market state, usually a listing with no seller meeting the buy box criteria.
- **An ASIN is marketplace-specific.** A US ASIN often does not resolve on amazon.co.uk, and the run says `asin_not_found` for it rather than returning an empty row.
- **Each row is one full product page**, over a megabyte, fetched through a residential exit. A 200-ASIN run takes minutes. Concurrency is deliberately low because Amazon throttles hard, and a faster setting draws 429s.
- **Buy box ownership changes intraday.** A daily run tells you much less than an hourly one. The actor is priced for frequent small runs for exactly this reason.

### FAQ

**Can I see who has the Amazon buy box without an API key?**
Yes. The featured offer is rendered on the ordinary product page for anonymous visitors, and that is what this actor reads. There is no credential field in the input.

**Does it show sellers who do not have the buy box?**
Yes, in `buying_options`, which carries every buying option Amazon pins on the product page with its own seller, price and condition. For the complete third-party offer list behind the "other sellers" panel you would need an offer-listing scraper; this returns what the page itself shows.

**Why does my ASIN come back with no price?**
Check `page_state`. It will say whether the product is a variation parent, has no featured offer, is unavailable, or is not a retail product at all. That field exists so you never have to guess.

**Which marketplaces are supported?**
Fifteen: com, co.uk, de, fr, it, es, nl, se, pl, ca, com.au, com.mx, com.br, in and co.jp. Each is fetched through an exit in its own country so the price and offer match that market.

**How do I track buy box changes over time?**
Schedule the run and store `asin`, `sold_by`, `price` and `scraped_at`. A change in `sold_by` between two runs is a buy box flip, and the price difference tells you what it cost.

### Related Actors

- [Amazon Bestsellers Scraper](https://apify.com/s-r/amazon-bestsellers) — ranked products across 15 Amazon marketplaces
- [EAN to ASIN Converter](https://apify.com/s-r/free-ean-to-asin-converter---turn-any-ean-into-an-amazon-asin) — turn a barcode into an Amazon ASIN
- [Google Shopping Scraper](https://apify.com/s-r/free-google-shopping-scraper---extract-offers-from-any-ean-sku) — offers from every merchant for an EAN or SKU

# Actor input Schema

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

Products to check. Bare ASINs or full Amazon product URLs both work, and URLs are reduced to their ASIN automatically.

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

Which Amazon site to check. The proxy exit is pinned to this country, so the price comes back in the local currency and the offer is the one that market actually sees.

## `limit` (type: `integer`):

How many ASINs to check in one run, 1 to 200. Each one is a full product page fetch, so a large batch takes minutes rather than seconds.

## `retries` (type: `integer`):

Retry attempts per product, each with a rotated user agent and TLS fingerprint. Amazon throttles harder than most sites, so leaving this at 4 or higher is worthwhile.

## Actor input object example

```json
{
  "asins": [
    "B0DJGDC3BD"
  ],
  "marketplace": "com",
  "limit": 50,
  "retries": 4
}
```

# Actor output Schema

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

One row per ASIN, with the featured offer and every alternative buying option.

## `summary` (type: `string`):

How many ASINs were requested, how many returned a buy box, and the page-state breakdown.

## `errors` (type: `string`):

Per-ASIN failures with a code and a redacted message.

# 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": [
        "B0DJGDC3BD"
    ],
    "limit": 50,
    "retries": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/amazon-buybox").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": ["B0DJGDC3BD"],
    "limit": 50,
    "retries": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/amazon-buybox").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": [
    "B0DJGDC3BD"
  ],
  "limit": 50,
  "retries": 4
}' |
apify call s-r/amazon-buybox --silent --output-dataset

```

## MCP server setup

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

```

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/Bo3PeJraKrXU1NoS1/builds/Oxv6lnxSBCBdFibDo/openapi.json
