# Amazon Bestsellers Scraper: 64 Fields, 19 Marketplaces (`amazonscrapers/amazon-bestsellers-scraper`) Actor

Scrape Amazon bestseller and category lists with the full product record: price, units bought last month, every bestseller rank, stock, ratings, images, specifications, variants, return policy and delivery date. 64 fields per product across 19 marketplaces.

- **URL**: https://apify.com/amazonscrapers/amazon-bestsellers-scraper.md
- **Developed by:** [Amazon Scrapers](https://apify.com/amazonscrapers) (community)
- **Categories:** E-commerce, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 products with a prices

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 bestsellers scraper: 64 fields per product, 19 marketplaces

Give it a bestseller or category link. Get back every product on it with the full
product record: price and what it used to cost, units bought last month, every
bestseller rank, stock, ratings, all images, the merged specification table,
variants, return policy and delivery date.

Sixty-four fields per product. The most-used bestsellers scraper on this Store
returns eight: position, category, name, price, currency, offer count, url and a
thumbnail.

### What the eight-field tools leave out

A bestseller list tells you the order. Every interesting question is one layer
down, on the product page, which is the layer a list scraper does not open.

**How much is actually selling.** `boughtInPastMonth` is Amazon's own figure, the
one printed as "10K+ bought in past month". `estimatedMonthlySales` and
`estimatedMonthlyRevenue` turn that into money. Rank fifteen in a category where
everyone sells two hundred a month is a different business from rank two where
the leader sells four.

**Every rank, not the first.** Amazon assigns several ranks per product, one per
category level. `bestsellerRanks` keeps all of them with their category names.
The narrow rank moves first; the broad one looks like noise.

**Whether you could compete.** `otherSellersCount`, `reviewCount`, `rating`,
`isPrime`. Four hundred reviews at 4.8 is a wall. Four hundred at 3.9 is an
opening.

**What it physically is.** `weight`, `dimensions`, `gtin`, `modelNumber`,
`material` and the full `specifications` table, merged from all eight of Amazon's
detail tables. This is what you need to source the same product or work out
shipping.

**The whole family.** `variantAsins` and `variantAttributes`, so you know whether
a listing is one product or fourteen wearing one page.

**The real price picture.** `listPrice`, `savingsAmount`, `discountPercent`,
`coupon`, `dealBadge`, `pricePerUnit`. The list shows one number; the product
page shows what that number means.

### Every field it returns

All sixty-four, grouped the way you would use them.

#### Price and offer

| Field | What it holds |
| --- | --- |
| `price` | Current price from Amazon's own buy box data **(this is what you are charged for)** |
| `listPrice` | The struck-through price, when Amazon shows one |
| `savingsAmount` | How much is off in money |
| `discountPercent` | How much is off as a percentage |
| `currency` | Three-letter code, from the page itself |
| `pricePerUnit` | Price per count, ounce, litre, whatever Amazon uses |
| `priceSource` | Where the price came from, so you can audit it |
| `isDiscounted` | Whether it is currently below list price |
| `coupon` | The clip-coupon text, when there is one |
| `dealBadge` | Lightning deal, limited time deal, and similar |
| `hasSubscribeAndSave` | Whether a subscription price exists |
| `hasUsedOffer` | Whether a used copy is offered |
| `isRefurbished` | Renewed and refurbished listings |
| `otherSellersCount` | How many other sellers offer it |

#### Demand and rank

| Field | What it holds |
| --- | --- |
| `boughtInPastMonth` | Units bought last month as a number |
| `boughtInPastMonthText` | Amazon's own wording, such as 10K+ bought in past month |
| `estimatedMonthlySales` | Units, derived from the line above |
| `estimatedMonthlyRevenue` | Units times price |
| `bestsellerRanks` | Every rank with its category, not just the first |
| `isBestSeller` | The orange best seller badge |
| `isAmazonChoice` | The Amazon's Choice badge |
| `rating` | Average stars, read in every shop language |
| `reviewCount` | How many ratings, as a number |

#### Stock and delivery

| Field | What it holds |
| --- | --- |
| `inStock` | True, false, or null when Amazon does not say |
| `availability` | Amazon's own availability sentence |
| `stockLeft` | Only three left in stock, when shown |
| `deliveryInfo` | The delivery date Amazon promises |
| `returnPolicy` | The return terms in full |
| `isPrime` | Prime delivery on this offer |

#### Identity and catalogue

| Field | What it holds |
| --- | --- |
| `asin` | The product id |
| `parentAsin` | The parent listing, for variant families |
| `title` | Full product title, shortened only past 1000 characters |
| `brand` | Brand name |
| `manufacturer` | Manufacturer, when different from brand |
| `modelNumber` | Model number |
| `partNumber` | Manufacturer part number |
| `gtin` | GTIN, EAN or UPC |
| `marketplace` | Which shop this row came from |
| `url` | The page this was read from |
| `scrapedAt` | Timestamp of the read |

#### Description, media and variants

| Field | What it holds |
| --- | --- |
| `description` | The product description under the fold, as plain text |
| `features` | The bullet points at the top |
| `image` | Main image at the largest size Amazon offers |
| `images` | Every gallery image, largest version first |
| `imageCount` | How many images there are |
| `videoCount` | How many videos are on the page |
| `hasAPlusContent` | Whether the brand added enhanced content |
| `variantAsins` | Sibling products in the variant family |
| `variantCount` | How many variants there are |
| `variantAttributes` | What varies, such as size and colour |
| `category` | The most specific category |
| `categories` | The full breadcrumb path |

#### Specifications, pulled apart

| Field | What it holds |
| --- | --- |
| `specifications` | Every row of every detail table, merged |
| `productFacts` | Amazon's newer facts panel |
| `weight` | Weight with its unit |
| `dimensions` | Package or product dimensions |
| `colour` | Colour |
| `material` | Material |
| `unitCount` | How many units in the pack |
| `firstAvailable` | Date first available on Amazon |
| `countryOfOrigin` | Country of origin |
| `warranty` | Warranty description |
| `importantInformation` | Safety and legal text, when present |
| `isClimatePledgeFriendly` | The Climate Pledge Friendly badge |

### What to put in

**A bestseller link.** The main way in:
`https://www.amazon.com/gp/bestsellers/electronics`, or any of Amazon's Movers
and Shakers, New Releases or Most Wished For lists.

**Any category link.** Anything under `/b/?node=` or a browse node URL works the
same way.

**A search term**, when the set you want is defined by what shoppers type.

**ASINs**, if you already have the list and want the full read on it.

Several at once is fine, and every row carries `marketplace` and the category it
came from, so a run across five lists stays sortable.

### A real row

```
asin                     B0BZYCJK89
title                    Owala FreeSip Stainless Steel Water Bottle 24 oz
brand                    Owala
price                    27.99
listPrice                34.99
discountPercent          20
priceSource              buybox-data
otherSellersCount        3
boughtInPastMonth        30000
estimatedMonthlyRevenue  839700
bestsellerRanks          #1 in Water Bottles, #12 in Sports Water Bottles
isBestSeller             true
rating                   4.7
reviewCount              89412
weight                   1.02 pounds
dimensions               3.5 x 3.5 x 10 inches
material                 Stainless Steel
variantCount             34
variantAttributes        ["size", "color"]
imageCount               7
inStock                  true
deliveryInfo             Tomorrow, August 27
```

Thirty-four variants on that listing. A list scraper would have told you
it is number one in Water Bottles at $27.99 and left you to find out the rest.

### What it costs to run one

Four dollars per thousand products with a price, plus three cents to start.

There are cheaper bestseller scrapers on this Store, and if all you want is name
and price on a list, one of those is the right tool and you should use it. This
one opens every product, which is where the weight, the units figure, the full
rank list and the specification table live, and that is what you are paying for.

Rows arrive free when Amazon does not price them, which on a bestseller list is
usually a handful out of a hundred.

### Reliability, measured

For scale: the most-used bestsellers scraper on this Store reports a 86.0 percent
run success rate over the last thirty days, read from its own public statistics
on 26 August 2026, 17,560 succeeded out of 20,423.

Three consecutive runs of twelve products on 26 August 2026, at the default
settings:

```
run 1   11 of 12 delivered, 8 with a price
run 2   12 of 12 delivered, 8 with a price
run 3   12 of 12 delivered, 8 with a price
```

And one run of sixty products the same day: 27 delivered,
21 with a price, in 7.8 minutes.

One thing is worth reading out of that, and it is not the one you would expect.
The sixty product run delivered 27, which sounds worse than the 35 of 36 above
until you notice what it was asked for: a category page, and Amazon only offered
27 products on it that day. A list Actor is bounded by what the list holds, so
"delivered" here means "everything that was there", not "everything we wanted".

The second is the residential switch, and the honest version is less dramatic
than it sounds. Measured 26 August on the same sixty products, twice: with the
switch off, fifty-one came back with the field this Actor charges on, for $0.0205
of platform usage. With it on, fifty-three came back, for $0.1192. Two more
products for roughly six times the cost.

That is why it is off by default. It is in your input form, so if a marketplace
is refusing almost everything you can turn it on and pay for the difference.

### It will not guess a price

Amazon puts up to nine price-shaped numbers on a product page: the subscribe
option, a used offer, a struck-through list price, a per-unit price, a bundle,
and a Prime upsell block that shows two amounts at once.

Measured on this engine: prices derived from reading the markup were correct zero
times out of six. Prices taken from the buy box data Amazon itself uses to render
the page were correct nine times out of nine. So that is the only source used.

When that data is not there you get no price rather than a wrong one, and the row
still arrives with the rank, the rating, the specifications and the images.
`priceSource` records where every price came from.

**You are not charged for a row without a price.**

### Settings worth knowing about

| Setting | What it does |
| --- | --- |
| `marketplace` | One of nineteen, from `com` to `co.jp`. |
| `proxyCountry` | Leave empty and it follows the marketplace. |
| `maxItems` | Hard ceiling on delivered products across the whole run. |
| `maxItemsPerList` | How many to take from each list. Prefilled at ten so your first click is quick; Amazon caps a bestseller list at a hundred. |
| `maxListPages` | How deep to walk each list. |
| `lanes` | How many products are read at once. Eight by default. Sixteen roughly halves the run time and costs a few prices, because Amazon strips the buy box sooner when you push. |
| `maxAttempts` | Attempts per product, each from a different address. Twelve by default. |
| `residentialFallback` | Off by default. On product pages it buys almost nothing: measured 2026-08-26, it cost roughly six times as much and returned two more products out of sixty. On the search and category pages this Actor starts from, it is a different story. Measured 2026-08-30, during hours when Amazon refused every listing page with a two kilobyte stub, twenty datacenter retries returned nothing and residential returned a full page in eight attempts. Turn it on if a run comes back empty. |
| `economical` | Off by default. On a sixty-four field read it would cost you the fields that sit late in the page, which is most of the specification table. |

### Reading the run log

```
Done: 16 charged (+4 delivered without a price, free), 0 refused by Amazon, 0 other. 1548 KB per charged result, 219 attempts in total.
Exit addresses: 188 used, 1 proven good, 11 burned.
Attempts by outcome: {"refused by Amazon":162,"page did not carry the field this Actor needs":38,"ok":16,"network error":1,"http_500":2}
```

`charged` is what you pay for. The bracketed number arrived with all its other
fields and cost you nothing.

If a run ever delivers rows and charges for none of them, the log says so in
capitals at the bottom.

### What you can build with it

**A category monitor.** The same three bestseller lists, daily, into one dataset.
Every row carries `scrapedAt`, so after a month you can see which products
climbed and which fell out.

**A supplier brief.** `weight`, `dimensions`, `material` and `gtin` on the top
fifty of a category is what you hand a manufacturer.

**A launch watch.** Amazon's New Releases lists plus this Actor tells you which
new products are gaining traction, weeks before they reach the main bestseller
list.

**A pricing study.** `price`, `listPrice` and `dealBadge` across a category over
time shows how deep the discounting really goes.

**A content audit.** `imageCount`, `videoCount` and `hasAPlusContent` on the top
of a category tell you what a listing needs to look like to compete there.

### Working it into your stack

Every run writes to a dataset you can download as CSV, JSON, Excel or XML, or
pull through the API. Sixty-four fields is a wide table; most people pick a
subset in the dataset view and export that.

Schedules take a cron expression. Webhooks fire on completion. Point repeated
runs at one named dataset and the category becomes a time series.

### Marketplaces

Nineteen, from amazon.com to amazon.co.jp. The cheaper alternative covers six.

Reading them in their own language is not cosmetic. A German rating says "4,5 von
5 Sternen" and a Japanese one puts the number last; both come back as 4.5. Stock
is read the same way, so a German "Derzeit nicht verfügbar" comes back as false
rather than as an empty field.

Prices are the one field that does not travel everywhere. Measured on 2026-08-24:

| Marketplace | Products priced |
| --- | --- |
| amazon.com | 57 of 60 |
| amazon.ca | 5 of 5 |
| amazon.co.uk | 5 of 6 |
| amazon.fr | 4 of 5 |
| amazon.it | 1 of 5 |
| amazon.es | 1 of 5 |
| amazon.de | 0 of 8 |
| amazon.com.au | 0 of 5 |

On the marketplaces where the buy box does not arrive, everything else still
does: twenty specifications per product, ranks, ratings, images. Those rows are
free. Run a small job on your marketplace first and see what you get.

Note also that `currency` reports what Amazon actually quoted. amazon.ca quotes
US dollars to a visitor it places in the United States.

### The rest of this family

Eleven Actors on one engine. If sixty-four fields is more than you need, the
focused ones cost the same four dollars and return less noise:

- **Amazon BSR Tracker** for rank over time on a watchlist.
- **Amazon Price Tracker** for price history on a fixed list of ASINs.
- **Amazon Niche Research** for the same category with revenue and competition
  in front.
- **Amazon Product Specs** when you only want the catalogue half.
- **Amazon Search Results Scraper** for the same depth on a search term instead
  of a category.

### Questions people ask

**How many products per category.** Amazon shows up to a hundred per bestseller
list. Set the maximum to zero and it takes them all.

**Can I crawl subcategories.** Give the subcategory links directly. This Actor
does not walk down a category tree on its own, because doing so quietly
multiplies what you are charged.

**Can I export to a spreadsheet.** Yes. Every run writes to a dataset you can
download as CSV, JSON, Excel or XML, or pull through the API.

**Can I run it on a schedule.** Yes, from the Schedules tab. Every row carries
`scrapedAt`, so repeated runs into one dataset become a record of how a category
moved.

**Does the row order match the bestseller order.** Rows come back in the order
Amazon returned them, so position in your dataset is position on the list at the
moment of the run.

**How long does it take.** Sixty products take about 17 minutes at the default
settings. Sixteen lanes halves that and costs a few prices.

### What it does not collect

No review text, no reviewer names, no customer questions, no seller names.

That is a design decision. Scraping personal data out of a public website is
almost always a GDPR problem in Europe, and a purely commercial interest does not
count as a legitimate one. An average score and a review count are facts about a
product, not about a person, so you get those.

### Legal note

This Actor reads public pages and takes product facts: prices, ranks,
availability, specifications, aggregate ratings. Business information about an
item, not information about a person.

You are responsible for what you do with the output. Check Amazon's terms for
your own use case, and if you are in Europe, keep in mind that combining public
data into a profile of a person is a different activity from tracking a category.

# Actor input Schema

## `search` (type: `array`):

Anything that lists products: a plain search term ("tower fan"), an Amazon search URL, a category link, or a bestsellers page. Each one is crawled and every product found is scraped. Use this when you do not know the ASINs up front.

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

Amazon product URLs or bare ASINs, one per line. Leave empty if you are using Search instead. Duplicates are removed so you are never charged twice.

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

Which Amazon site to read. The currency of the price follows the marketplace and the proxy country.

## `proxyCountry` (type: `string`):

Which country the requests should appear to come from. Leave empty and it follows the marketplace: amazon.de is read from Germany, amazon.co.uk from the UK. This matters more than it looks -- Amazon shows different prices, currencies and even availability depending on where you appear to be.

## `maxItems` (type: `integer`):

Hard ceiling on delivered products. 0 means no ceiling: the Actor keeps going until the lists run out or your limits stop it.

## `maxItemsPerList` (type: `integer`):

Products to take from each search term or category link. Up to 10000.

## `maxListPages` (type: `integer`):

Result pages to walk per list. Up to 100. Amazon itself stops earlier on most searches.

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

Datacenter proxies were enough in testing: 30 out of 30 products returned with zero blocks. They are the cheaper option and the default. Switch to residential if you start seeing blocked pages at higher volume. Running without any proxy stops after roughly 85-120 products, because Amazon closes the door on a single IP address for over an hour.

## `lanes` (type: `integer`):

How many products to read at the same time. Each lane uses its own exit address, so more lanes never means asking one address more often. Eight is the tested default and the most accurate. Sixteen finishes the same sixty products in about half the time, but measured on 2026-08-24 it returned six more products without a price, because Amazon strips the buy box sooner under pressure. Raise it when speed matters more than the last few prices.

## `maxAttempts` (type: `integer`):

How often to retry a product Amazon refuses, each time from a different exit IP. A refusal is a property of one address, not of the product, and a refused attempt costs about 4 KB. Twelve tries is cheap insurance against a run that comes back short.

## `residentialFallback` (type: `boolean`):

After half the attempts have failed, retry through residential addresses instead of datacenter ones. Measured 2026-08-26: residential transfer was 90 percent of the bill on a sixty product run ($0.150 of $0.167) while a run that never touched it delivered all sixty anyway. Leave it off unless you are losing products; turn it on when a marketplace refuses everything.

## `economical` (type: `boolean`):

Hang up on each product page once the price is in, instead of reading it to the end. Roughly three times less traffic and about three times faster. Measured cost: over 30 products this lost 2 ratings, 4 review counts and 1 brand, because Amazon sometimes puts the rating below the price. Prices were identical either way. Leave this off unless you only need prices and are paying per gigabyte.

## `minDelayMs` (type: `integer`):

Pause between products. Measured 2026-08-23: at 1-2 seconds this returned 10 of 15 products; at 8-15 seconds it returned 12 of 15 on the same list. Pace turned out to matter more than anything else. The market leader waits about 14 seconds per product.

## `maxDelayMs` (type: `integer`):

Upper bound for the pause between products. The actual pause is random between the minimum and this value, which looks less mechanical than a fixed interval.

## `retryPauseMs` (type: `integer`):

How long to wait before trying a refused product again. Kept short because the retry already switches to a different exit IP, and waiting longer only makes the run more expensive.

## Actor input object example

```json
{
  "search": [
    "https://www.amazon.com/gp/bestsellers/electronics"
  ],
  "productUrls": [],
  "marketplace": "com",
  "maxItems": 0,
  "maxItemsPerList": 10,
  "maxListPages": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "lanes": 8,
  "maxAttempts": 12,
  "residentialFallback": false,
  "economical": false,
  "minDelayMs": 8000,
  "maxDelayMs": 15000,
  "retryPauseMs": 300
}
```

# Actor output Schema

## `products` (type: `string`):

One row per product with the full record. Rows without a price are delivered in full and never charged for.

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

Counts per outcome, exit addresses used, bytes per charged result.

# 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 = {
    "search": [
        "https://www.amazon.com/gp/bestsellers/electronics"
    ],
    "productUrls": [],
    "maxItemsPerList": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("amazonscrapers/amazon-bestsellers-scraper").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 = {
    "search": ["https://www.amazon.com/gp/bestsellers/electronics"],
    "productUrls": [],
    "maxItemsPerList": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("amazonscrapers/amazon-bestsellers-scraper").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 '{
  "search": [
    "https://www.amazon.com/gp/bestsellers/electronics"
  ],
  "productUrls": [],
  "maxItemsPerList": 10
}' |
apify call amazonscrapers/amazon-bestsellers-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/7E0QMYnBQ7XZEML0z/builds/DJNvESjxRHTbtpaAw/openapi.json
