# Amazon Best Sellers Scraper & Rank Tracker (`cyprusapi/amazon-bestsellers`) Actor

Scrapes Amazon Best Sellers, New Releases, Most Wished For and Most Gifted grids per category URL — structured prices, change tracking, errors never charged.

- **URL**: https://apify.com/cyprusapi/amazon-bestsellers.md
- **Developed by:** [Torchtechnology LTD](https://apify.com/cyprusapi) (community)
- **Categories:** Automation, E-commerce, Developer tools
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.40 / 1,000 result items

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 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

### What does this Actor do?

Amazon Best Sellers Scraper extracts the ranked product charts of any Amazon category — **Best Sellers, Movers & Shakers, New Releases, Most Wished For, and Most Gifted** — across eighteen verified marketplaces: amazon.de, .com, .co.uk, .fr, .it, .es, .ca, .com.au, .co.jp, .in, .nl, .se, .pl, .com.be, .com.mx, .com.br, .ae, and .sa. For every ranked product you get position, ASIN, name, price as a **structured number with the marketplace's own currency**, star rating, review count, thumbnail, and product URL — and for **Movers & Shakers** the **rank change in percent** Amazon reports. Optional **change tracking** compares every category against its previous run and reports climbers, new entries, and drop-outs — no external state needed on your side.

It is designed for both humans and AI agents: deterministic JSON output, documented error semantics, and pay-per-result pricing where **errors are never charged**.

### When to use this Actor

- **Trend detection** — "Which products entered the top 100 in category X this week?" → run daily/weekly with `trackChanges: true` and read `positionDelta`, `isNewEntry`, `droppedOut`. For the fastest movers right now, scrape the **Movers & Shakers** chart and read `rankChangePercent`.
- **Assortment & market research** — pull the top products of any category, filtered by price band, rating, or review count (`minPrice`/`maxPrice`/`minStars`/`minReviews`). Filters are applied **before** charging.
- **Competitive monitoring** — track specific subcategories over time via scheduled runs.

**When not to use it:** you need full product detail pages (use a product-data actor) or review texts (use a reviews actor).

### Quickstart (API)

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~amazon-bestsellers/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "categoryUrls": ["https://www.amazon.com/gp/bestsellers/beauty"],
    "maxItemsPerCategory": 100,
    "trackChanges": true
  }'
```

Or in the Console: paste one or more category URLs, click Start, download as JSON/CSV/Excel/XML.

### Input reference

| Field | Type | Default | Description |
|---|---|---|---|
| `categoryUrls` | string\[] | — | Chart URLs: `/gp/bestsellers/…` or `/zgbs/…`, `/gp/movers-and-shakers/…`, `/gp/new-releases/…`, `/gp/most-wished-for/…`, `/gp/most-gifted/…`. Multiple URLs and marketplaces per run are fine. Optional when `chartType` + `marketplace` are set. |
| `chartType` | string | — | `bestsellers` | `movers-and-shakers` | `new-releases` | `most-wished-for` | `most-gifted` — builds the chart URL for you. |
| `marketplace` | string | — | One of the 18 marketplace codes (e.g. `de`, `com`, `co.jp`) — used with `chartType`. |
| `categorySlug` | string | — | Optional category path appended to the chart URL, e.g. `beauty` or `electronics/172541`. Empty = chart root page. |
| `maxItemsPerCategory` | integer | 100 | Cap per category (Amazon renders max. 100 per chart). |
| `includeSubcategories` | boolean | false | Also crawl child categories discovered in the nav tree. |
| `maxSubcategoryDepth` | integer | 1 | Tree depth when subcategory crawl is enabled (1–3). |
| `minStars` | number | 0 | Only items with ≥ this rating. |
| `minReviews` | integer | 0 | Only items with ≥ this many reviews. |
| `minPrice` / `maxPrice` | number | 0 | Price band in marketplace currency. |
| `trackChanges` | boolean | false | Rank-diff against the previous snapshot of each category. Snapshots persist across runs and always store the *unfiltered* grid. |
| `proxyConfiguration` | object | bundled geo proxies | Optional — the actor ships with bundled geo proxies per marketplace (no setup needed, we cover the cost). Enable this only to force your own or Apify proxies instead. |
| `proxiesByMarketplace` | object | — | Bring-your-own geo-pinned proxies per marketplace (`{"co.uk": ["http://…"]}`). Overrides the bundled pool for the listed marketplaces. |

### Output

One dataset item per ranked product:

```json
{
  "position": 1,
  "asin": "B08P4YPB8Q",
  "name": "Maybelline New York Sky High Mascara …",
  "url": "https://www.amazon.com/dp/B08P4YPB8Q",
  "thumbnailUrl": "https://m.media-amazon.com/images/I/…jpg",
  "price": { "value": 9.31, "currency": "USD" },
  "stars": 4.4,
  "reviewsCount": 37118,
  "numberOfOffers": null,
  "rankChangePercent": null,
  "chartType": "bestsellers",
  "categoryName": "Beauty & Personal Care",
  "categoryUrl": "https://www.amazon.com/gp/bestsellers/beauty",
  "marketplace": "com",
  "input": "https://www.amazon.com/gp/bestsellers/beauty",
  "previousPosition": 2,
  "positionDelta": 1,
  "isNewEntry": false,
  "scrapedAt": "2026-08-16T10:33:30Z"
}
```

| Field | Meaning |
|---|---|
| `position` | Rank in the chart (from the rank badge; DOM order as fallback; `null` if not observable) |
| `asin`, `name`, `url`, `thumbnailUrl` | Product identity; `url` is the canonical `/dp/` link |
| `price` | `{value, currency}` — numeric, in the marketplace's own currency |
| `priceString` | Price exactly as rendered on the page |
| `stars`, `reviewsCount` | Rating and review count as rendered on the card |
| `numberOfOffers` | Offer count when Amazon renders it, otherwise `null` |
| `isPrime` | `true` when a Prime badge is rendered on the card; `null` when the grid shows no Prime info (never a guessed `false`) |
| `badges` | Visible badge texts on the card (e.g. "Bestseller"); usually empty on chart grids |
| `rankChangePercent` | Movers & Shakers only: Amazon's "% increase in sales rank" figure as an integer (e.g. `256` for "+256%"); always `null` on the other charts |
| `chartType` | `bestsellers` | `new-releases` | `most-wished-for` | `most-gifted` | `movers-and-shakers` |
| `categoryName` | The category name only (no chart label), localized as rendered by the marketplace — e.g. `Kosmetik` for amazon.de `…/bestsellers/beauty`. Use it to group items when batching many categories in one run |
| `input` | The start URL this category was reached from (also for subcrawled categories) |
| `previousPosition`, `positionDelta`, `isNewEntry` | Only with `trackChanges: true`. `positionDelta` > 0 = climbed. All `null` on the first (baseline) run |
| `scrapedAt` | UTC timestamp of capture |

`null` means "not rendered by Amazon" — never a guess. If Amazon skips positions in a grid, the gap is reported in the `RUN_SUMMARY` key-value record, never silently filled. `RUN_SUMMARY` also contains per-category item counts and, with change tracking, `changes: {newEntries, droppedOut, basedOnSnapshotAt}`.

### Error items (never charged)

Failures are pushed as dataset items for transparency, but no `result` event is charged for them:

| `error` | Meaning | Typical action |
|---|---|---|
| `invalid_url` | Not a supported Amazon marketplace URL | Fix the URL |
| `category_not_found` | Amazon returned 404 | Check the category path |
| `no_results_found` | Page rendered no product cards | Retry later |
| `category_unavailable` | Amazon renders the URL as an empty "undefined" category page — the bare slug no longer resolves | Use the node-id URL form: `…/gp/bestsellers/<slug>/<nodeId>` (e.g. `https://www.amazon.de/gp/bestsellers/electronics/562066`) |
| `blocked` | Bot-detection page after automatic retries across the proxy tier chain (own pool → Apify DC → Apify residential) | Use residential / geo-pinned proxies |
| `transport` | Navigation failure (proxy/timeout) | Simply retry |

### Pricing

Pay-per-event: one `result` event per product item pushed. **Error items are free. Filters are applied before charging.** A full top-100 category costs 100 result events; a daily change-tracked watchlist of 10 categories costs 1,000 events/day. See the Pricing tab for the current event price.

### Tips

- **Batch your categories** into one run — per-run startup cost is shared across all URLs.
- Use `maxItemsPerCategory` while exploring to cap spend.
- Subcategory crawl multiplies output fast (one root can mean 30+ categories). Combine with filters and caps.
- For correct prices, the proxy exit country must match the marketplace — the bundled pool is already geo-pinned per marketplace; if you bring your own, use `proxiesByMarketplace` or Apify Residential with country targeting.
- Schedule the Actor (e.g. daily) with `trackChanges: true` to build a trend time series; snapshots persist between runs.

### Known limitations

- **Movers & Shakers availability:** Amazon gates this chart more aggressively than the others — anonymous sessions sometimes get no product grid at all (the page renders but stays empty). The actor renders the page in a real browser and extracts the grid whenever Amazon serves it, including the `rankChangePercent` figures; when Amazon withholds the grid, you get an uncharged `no_results_found` error item instead of being charged for nothing.
- **Dead bare slugs (e.g. `/gp/bestsellers/ce` on amazon.de):** Amazon has stopped resolving some bare category slugs server-side — the page loads with HTTP 200 but the category renders as "undefined" with no product grid at all, so there is no markup any scraper could parse. The same chart still works via its node-id URL (e.g. `https://www.amazon.de/gp/bestsellers/electronics/562066` for Elektronik & Foto). The Actor detects this case and returns an uncharged `category_unavailable` error item instead of a generic `no_results_found`; pass the node-id form of the URL to get data.
- Amazon caps every chart at 100 visible items per category — this is a platform limit, not an Actor limit.
- Verified marketplaces: **de, com, co.uk, fr, it, es, ca, com.au, co.jp, in, nl, se, pl, com.be, com.mx, com.br, ae, sa** (18). Others may work but are untested — report your results via the Issues tab.

### Use with AI agents (MCP)

This Actor is MCP-ready and works as a structured Amazon chart tool for AI agents. Exact identity: `cyprusapi/amazon-bestsellers`.

**Tool description:** fetch ranked Amazon chart products (Best Sellers, Movers & Shakers, New Releases, Most Wished For, Most Gifted) from 18 marketplaces and return structured records with rank, ASIN, title, structured local-currency price, rating, review count, and chart context — Movers & Shakers items additionally carry `rankChangePercent`. Optionally diffs against the previous run (`trackChanges`).

> Example prompt: "Scrape the US Amazon Best Sellers chart for Electronics, top 20, with rank, ASIN, title, price, rating, and review count." → input: `{"chartType": "bestsellers", "marketplace": "com", "categorySlug": "electronics", "maxItemsPerCategory": 20}`

**Output interpretation for agents:**

- `position` is the chart rank, `1` is the top item
- `asin` + `url` identify the product for follow-up enrichment
- `price.value` / `price.currency` are numeric and marketplace-local — safe for arithmetic
- `positionDelta` > 0 means the product climbed since the previous run
- `rankChangePercent` is only set on Movers & Shakers items — Amazon's own "% increase in sales rank" figure
- Items with an `error` field are failures — they are never charged and should not be counted as data
- A field set to `null` means "not rendered by Amazon" — do not treat it as zero or absence of the attribute

**Cost guidance:** one product = one `result` event; errors, filters, and the first baseline snapshot cost nothing. Lower `maxItemsPerCategory` when only the chart top is needed.

### FAQ, disclaimers, and support

- **Is it legal?** The Actor reads publicly available chart pages. You are responsible for complying with Amazon's Terms of Service and applicable law in your jurisdiction.
- **Do I need proxies?** No — the actor ships with bundled geo-pinned residential proxies per marketplace, and we cover their cost. You only touch the proxy settings if you want to force your own pool or Apify Proxy instead.
- **Found a bug or need another marketplace or chart type?** Open an issue — selector maintenance is part of the product.

# Actor input Schema

## `categoryUrls` (type: `array`):

Amazon chart URLs to scrape: Best Sellers (/zgbs/... or /gp/bestsellers/...), Movers & Shakers, New Releases, Most Wished For, Most Gifted. One dataset item per product. Multiple URLs and multiple marketplaces in one run are fine. Optional when chartType + marketplace are given.

## `chartType` (type: `string`):

Build the chart URL from settings instead of passing categoryUrls: pick a chart, a marketplace, and optionally a category slug.

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

Used with chartType to build the chart URL.

## `categorySlug` (type: `string`):

Optional category path appended to the chart URL (e.g. 'beauty' or 'electronics/172541'). Empty = the chart's root page.

## `maxItemsPerCategory` (type: `integer`):

Upper bound of products collected per category URL (Amazon shows up to 100 per chart).

## `includeSubcategories` (type: `boolean`):

Also scrape child categories discovered in the navigation tree of each start URL. Costs scale with the number of discovered categories.

## `maxSubcategoryDepth` (type: `integer`):

How deep to follow the category tree when 'Crawl subcategories' is enabled (1 = direct children only).

## `minStars` (type: `number`):

Only push products with at least this rating (0 = no filter). Products without a rendered rating are filtered out when a filter is active.

## `minReviews` (type: `integer`):

Only push products with at least this many reviews (0 = no filter).

## `minPrice` (type: `number`):

Only push products at or above this price in marketplace currency (0 = no filter).

## `maxPrice` (type: `number`):

Only push products at or below this price in marketplace currency (0 = no filter).

## `trackChanges` (type: `boolean`):

Compare each category against its previous run: per item you get previousPosition, positionDelta (positive = climbed) and isNewEntry; RUN\_SUMMARY adds newEntries/droppedOut per category. Snapshots persist across runs; the first run only establishes the baseline.

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

Optional — the actor ships with bundled geo proxies per marketplace (no setup needed, we cover the cost). Enable this only to force your own or Apify proxies instead.

## `proxiesByMarketplace` (type: `object`):

Optional: {"de": \["http://user:pass@host:port", …], "co.uk": \[…]}. Geo-pinned proxies per marketplace — exit-IP country should match the marketplace, otherwise Amazon serves wrong currencies or bot-gates. Proxy tier chain per task: this explicit pool FIRST; otherwise the bundled shared pool (we cover it); on blocked/transport the run falls back to Apify datacenter, then Apify residential. With useApifyProxy off and no pool at all: single direct attempt.

## Actor input object example

```json
{
  "categoryUrls": [
    "https://www.amazon.com/gp/bestsellers/beauty"
  ],
  "maxItemsPerCategory": 10,
  "includeSubcategories": false,
  "maxSubcategoryDepth": 1,
  "minStars": 0,
  "minReviews": 0,
  "minPrice": 0,
  "maxPrice": 0,
  "trackChanges": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

# 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 = {
    "categoryUrls": [
        "https://www.amazon.com/gp/bestsellers/beauty"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cyprusapi/amazon-bestsellers").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 = { "categoryUrls": ["https://www.amazon.com/gp/bestsellers/beauty"] }

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

```

## MCP server setup

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

```

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/dKsGDUy1ef6uh8cJx/builds/iOEpUAgyCKD9EXUno/openapi.json
