# Amazon Scraper — Search, Products & Best Sellers (No Login) (`sondalabs/amazon-scraper`) Actor

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

## Pricing

from $1.00 / 1,000 search results

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Amazon Scraper — Search, Products & Best Sellers (No Login)

Extract Amazon data from **search results, product pages and Best Sellers lists** in four marketplaces: amazon.com, .com.mx, .com.br and .co.jp. Prices as numbers with their currency, exact rating counts with the 1–5 star breakdown, Best Sellers Rank and product details, in one consistent output format.

Built for reliability: browser-grade connections, automatic retries on blocked pages, and you **only pay for results delivered**.

**Public pages only. No login, no CAPTCHA solving.**

### What you get

- **Search, product details and Best Sellers in one actor,** with one output format.
- **You only pay for results.** Blocked pages, retries and empty searches are never charged.
- **Exact ratings, not "1.6K".** With `includeRatingsHistogram` (on by default) every search result, Best Sellers item and product detail gets the exact number of ratings and the 1–5 star breakdown.
- **Prices you can compute with.** `price.value` is a number and `price.currency` an ISO code read from the price Amazon shows.
- **Transparent about the connection.** Every record says in `fetchTier` whether it came through a datacenter or a residential IP, and the final status message reports blocked pages recovered and lost.

### Use cases

- Market research: what sells, at what price and with what rating, in a category or keyword.
- Best Sellers tracking: snapshots of the top 100 in any category.
- Catalog enrichment: titles, features, images and attributes for a list of ASINs.

### Quick start

Search results:

```json
{
  "mode": "search",
  "searchTerms": ["wireless earbuds"],
  "marketplace": "amazon.com",
  "maxItemsPerStart": 50
}
```

Product details for a list of ASINs:

```json
{
  "mode": "product",
  "asins": ["B09FT58QQP", "B0C2W1KLSS"],
  "marketplace": "amazon.com"
}
```

Top 100 Best Sellers of a category:

```json
{
  "mode": "bestsellers",
  "startUrls": [{ "url": "https://www.amazon.com/gp/bestsellers/electronics" }],
  "maxItemsPerStart": 100
}
```

### Input

The input is checked before anything runs or is charged. A field the actor does not read, an input the chosen mode does not use (for example `asins` in `search` mode), or a feature that is not available yet makes the run fail at once with a message that says what to change. Nothing is silently ignored.

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | enum | `search` | `search`, `product` or `bestsellers`. `product` works on amazon.com, amazon.com.mx and amazon.com.br. |
| `searchTerms` | string\[] | `[]` | Keywords for `search` mode. With no input at all, the actor searches "wireless earbuds" on amazon.com; if you pick a marketplace and leave this empty, it searches a headphones term in that marketplace's language. |
| `asins` | string\[] | `[]` | ASINs for `product` mode. An invalid ASIN produces an error row and is not charged. |
| `startUrls` | URL\[] | `[]` | Amazon URLs of the mode's type: search and category URLs (`/s?k=…`, `/s?rh=…`, `/b?node=…`) in `search`, product URLs (`/dp/ASIN`) in `product`, Best Sellers URLs (`/gp/bestsellers/…`, or the `/Best-Sellers-…/zgbs/…` links from Amazon's menu) in `bestsellers`. The marketplace comes from each URL's domain. A category URL keeps its filters, sort order and page. Any other page (deals, stores, New Releases, the Best Sellers home page without a category, a search without a term, an invalid `page`, or a page in another language such as `/-/es/` or `language=es_US`) is rejected before the run starts, with the reason. Each marketplace is read in its default language. Duplicate inputs (the same term, ASIN or URL twice) are fetched once and each duplicate gets its own `skipped` summary row. If Apify migrates the run to another server, results already delivered are not delivered or charged again. The same product or page given twice is fetched and charged once, including overlapping pages of the same search (`/s?k=x` and `/s?k=x&page=2`): no page and no product is charged twice across them. Best Sellers mode needs at least one Best Sellers URL. |
| `marketplace` | enum | `amazon.com` | Amazon site used for `searchTerms` and `asins`. |
| `maxItemsPerStart` | integer | `50` | Maximum results per search term, URL or category. |
| `maxPages` | integer | `20` | Maximum result pages per search or category. |
| `maxItems` | integer | `500` | Maximum results for the whole run. |
| `scrapeProductDetails` | boolean | `false` | In `search` and `bestsellers` modes, open every product and return the full product record (charged as product details). Only on amazon.com, amazon.com.mx and amazon.com.br. |
| `includeRatingsHistogram` | boolean | `true` | Add the exact rating count and the 1–5 star breakdown. |
| `allowResidentialFallback` | boolean | `true` | If a page is still blocked after 7 attempts on datacenter IPs, use residential IPs for the last 3 attempts. A page lost after all 10 attempts gets one more round of 5 attempts about a minute later (at most 2 pages per run), because Amazon's blocks are often short bursts. |
| `proxyConfiguration` | object | Apify datacenter proxy | Datacenter proxy (`useApifyProxy`, optional datacenter group, country `US` only) or your own `proxyUrls`. |
| `maxResidentialMB` | integer | `200` | Residential traffic limit per run (0–500), measured with a conservative estimate of what the proxy bills. When it is reached, retries stay on datacenter IPs and pages that still fail are reported as blocked and not charged. |

### Output

Product (`type: "product"`), from a product page (`detailLevel: "full"`):

```json
{
  "type": "product",
  "asin": "B09FT58QQP",
  "marketplace": "amazon.com",
  "url": "https://www.amazon.com/dp/B09FT58QQP",
  "title": "TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones",
  "brand": "TOZO",
  "price": { "value": 13.96, "currency": "USD", "raw": "$13.96" },
  "listPrice": { "value": 19.99, "currency": "USD", "raw": "$19.99" },
  "availability": "In Stock",
  "inStock": true,
  "buyBoxSeller": { "name": "Worgo", "id": "A1B1TP8XQ7ZVJZ" },
  "stars": 4.3,
  "ratingsTotal": 118394,
  "ratingsHistogram": { "5": 67, "4": 15, "3": 8, "2": 4, "1": 6 },
  "bestsellerRanks": [{ "rank": 18, "category": "Electronics" }, { "rank": 1, "category": "Sleep Earbuds" }],
  "categoryPath": ["Electronics", "Headphones, Earbuds & Accessories", "Headphones & Earbuds", "Earbud Headphones", "Sleep Earbuds"],
  "features": ["…"],
  "images": ["https://m.media-amazon.com/images/I/….jpg"],
  "attributes": { "Brand": "TOZO" },
  "detailLevel": "full",
  "fetchTier": "datacenter",
  "scrapedAt": "2026-10-22T07:10:12.000Z"
}
```

Fields that Amazon does not show for a product are `null` (or an empty list). A few things worth knowing:

- **Search results** (`detailLevel: "card"`) carry what the result card shows: title, price, list price, stars, `searchPosition`, `page` and `isSponsored`. `page` is Amazon's result page; `searchPosition` counts from 1 on the first page the actor fetched for that search (a start URL with `page=3` starts counting there). Card rating counts are rounded by Amazon ("4.3K"): then `ratingsTotal` is `null` and `ratingsTotalApprox` has the rounded number; with `includeRatingsHistogram` you get the exact count.
- **Best Sellers** lists have 50 items per page. Amazon renders full data for about 30 of them; the rest come with `asin`, `url`, `bestsellerRank` and, with `includeRatingsHistogram`, stars and ratings. Turn on `scrapeProductDetails` to complete them.
- **Local prices.** The actor asks for each marketplace's own currency and, when a page hides prices, sets a guest delivery location in a large city of that country (for example New York 10001 on amazon.com, Mexico City 06600 on amazon.com.mx, São Paulo 01310-100 on amazon.com.br), the same "Deliver to" choice any visitor can make without an account. Prices and availability are therefore the ones a shopper in that city sees. `price.currency` always reflects the text Amazon showed.
- Some products only show their price after being added to the cart ("See price in cart"), and some sellers do not ship to the marketplace's default location. The actor never adds anything to a cart, so `price` is `null` on those records. With `scrapeProductDetails`, when the product page shows no price but the search or Best Sellers card did, the card's price is used. In search mode, when a result card shows no price ("Click to see price", products with several options), the actor reads the price from that product's page once, at no extra charge.
- `stars` is `null` for products without reviews (never `0`). With `includeRatingsHistogram`, `stars` comes from the same ratings breakdown as the histogram.
- `isPrime` is `true` when the Prime badge is visible, otherwise `null`. Amazon hides the badge from most visitors who are not signed in, so expect `null` on most records; do not read `null` as "not Prime".
- `ratingsHistogram` values are percentages, as Amazon publishes them. It is `null` when the product has no ratings.
- `listPrice` is only the struck-through "was" price shown by Amazon, as Amazon shows it (it is not validated; it is `null` when it equals the price). Unit prices ("€12.82/kg") and instalment prices are not list prices and are not returned there.

If two requested ASINs lead to the same product page (merged or redirected ASINs), the product is delivered and charged once; the second ASIN gets a `skipped` summary row saying so. A definitive HTTP error from Amazon (for example 410) is reported as `error` and not retried. Every product record carries a `start` field with the search term, URL or ASIN that produced it: the same product found by two different searches is delivered (and charged) once per search, and `start` tells them apart; with `scrapeProductDetails` it is delivered once per run. Search terms are limited to 200 characters and URLs to 2,000. `proxyConfiguration` takes either the Apify datacenter proxy (optionally a datacenter group and a country) or your own `proxyUrls`, not both; residential and Google SERP groups are rejected, and if the proxy refuses the connection, or your own proxy cannot be reached, the run fails with that reason instead of retrying.

Each start (search term, ASIN or URL) also produces a free `type: "run_summary"` row with its status (`ok`, `empty`, `blocked`, `not_found`, `error`, or `skipped` when the run reached `maxItems` or its charge limit before that start, or another start URL already covers the same pages), results, pages fetched, blocked pages recovered and lost, and residential traffic used. It is never charged.

### Pricing

You pay per result delivered: a **search result**, a **product detail** or a **Best Sellers item**. Run summaries, error rows, blocked pages, retries and empty searches are not charged. Set a maximum cost per run and the actor stops cleanly when it is reached. The current prices are shown on the Pricing tab.

### Supported marketplaces

**Search and Best Sellers:** amazon.com, amazon.com.mx, amazon.com.br and amazon.co.jp.

**Product details** (`product` mode and `scrapeProductDetails`): amazon.com, amazon.com.mx and amazon.com.br. On amazon.co.jp, asking for product details returns a clear error before anything runs or is charged.

ASINs can differ between marketplaces: a product that exists on amazon.com may not exist on amazon.com.mx (it appears as `not_found`).

### Default run

With no input, the actor searches amazon.com for "wireless earbuds" and returns up to 50 products, usually in 1–4 minutes. If Amazon blocks a page, the actor retries it (up to 10 attempts, then one more round a minute later); a search that stays blocked is reported as `blocked` and not charged.

### Limits

- Public pages only. The actor never signs in, so it does not return the paginated review list, which Amazon only shows to signed-in users.
- Amazon blocks some requests. The actor retries with a new connection and, if needed, a residential IP, up to your `maxResidentialMB`. If a page cannot be fetched it is reported as blocked in the run summary and not charged.

### Roadmap

Not available yet; listed so you know what is planned. Nothing here is promised for a date.

- Seller offers (`offers` mode and `includeOffers`).
- Public reviews shown on the product page, with star and verified-purchase filters, and Amazon's "Customers say" summary.
- Price-change monitoring (`onlyChanged`): return only products whose price or availability changed since the previous run.
- Delivery location (`zipCode`).
- Product variations.
- More marketplaces (France, Italy, Spain, Canada, Australia, Netherlands and others).

### FAQ

**Why is a price missing?**
Some products have no featured offer or are unavailable, or Amazon does not ship them to the location of the connection used.

**Is this affiliated with Amazon?**
No. It is an independent tool that collects publicly visible information from Amazon pages.

### Support

Open an issue in the **Issues** tab. Issues are answered within 48 hours. Changes to output fields are announced in the changelog and never break existing fields.

# Actor input Schema

## `mode` (type: `string`):

What to scrape. Search reads search terms and search or category URLs; Product reads ASINs and product URLs; Best Sellers reads Best Sellers URLs. An input the chosen mode does not read makes the run fail before anything is charged. Product mode (and product details) is available on amazon.com, amazon.com.mx and amazon.com.br; Search and Best Sellers also work on amazon.co.jp.

## `searchTerms` (type: `array`):

Keywords for Search mode. Leave empty to search a default headphones term in the chosen marketplace's language. Not read in Product or Best Sellers mode (the run fails with a clear message if you fill it there).

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

10-character Amazon product IDs for Product mode.

## `startUrls` (type: `array`):

Amazon search, category, Best Sellers or product URLs. The marketplace is taken from each URL.

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

Amazon site used for search terms and ASINs.

## `maxItemsPerStart` (type: `integer`):

Maximum results per search term, category or start URL.

## `maxPages` (type: `integer`):

Maximum result pages to read per search or category.

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

Maximum charged results for the whole run.

## `scrapeProductDetails` (type: `boolean`):

In Search and Best Sellers modes, open every product and return the full product record (charged as product details). Available on amazon.com, amazon.com.mx and amazon.com.br.

## `includeRatingsHistogram` (type: `boolean`):

Add the exact number of ratings and the 1–5 star breakdown.

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

Apify datacenter proxy is recommended. Residential traffic is used automatically only as a fallback for blocked pages.

## `allowResidentialFallback` (type: `boolean`):

If a page is still blocked after 7 attempts on datacenter IPs, use residential IPs of the marketplace's country for the last 3 attempts, up to maxResidentialMB.

## `maxResidentialMB` (type: `integer`):

Cap on residential traffic per run.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [],
  "asins": [],
  "startUrls": [],
  "marketplace": "amazon.com",
  "maxItemsPerStart": 50,
  "maxPages": 20,
  "maxItems": 500,
  "scrapeProductDetails": false,
  "includeRatingsHistogram": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "allowResidentialFallback": true,
  "maxResidentialMB": 200
}
```

# Actor output Schema

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

Products and run summary rows in the default dataset.

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("sondalabs/amazon-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 = { "proxyConfiguration": { "useApifyProxy": True } }

# Run the Actor and wait for it to finish
run = client.actor("sondalabs/amazon-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 '{
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call sondalabs/amazon-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sondalabs/amazon-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/0f4pQ6549N8ZbMc4M/builds/j8Fjqa4cC27Xmqjim/openapi.json
