# Amazon Reviews Scraper — Ratings Histogram & Customers Say (`scrapersdelight/amazon-reviews-scraper`) Actor

Get reviews for any Amazon product by ASIN or URL — rating, title, body, verified purchase, date, helpful votes, images, plus the star-rating histogram and the AI 'Customers say' aspect sentiment. Public pages only: no login, no cookies. 12 marketplaces. Export JSON/CSV.

- **URL**: https://apify.com/scrapersdelight/amazon-reviews-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** E-commerce, Automation, Agents
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 per review returneds

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 Reviews Scraper — Ratings Histogram & Customers Say

Get reviews for any [Amazon](https://www.amazon.com) product by ASIN or URL, from the **public
product page, with no login, no cookie pool and no CAPTCHA solving**. One row per review:
**reviewId, rating, title, body, reviewerName, reviewerId, date, reviewCountry, verifiedPurchase,
vineReview, helpfulVotes, variant, images, hasVideo** — and on every row the product's
**productAverageRating, productTotalRatings, productRatingHistogram** (the 5→1-star percentages)
and the **AI "Customers say" summary with its per-aspect sentiment** (`customersSayAspects`:
aspect, positive/negative/mixed, mention counts, evidence snippets linked to review ids). That last
field is decoded from the page's own serialised state and shipped on every row at no extra charge.

**Scope: up to ~13 reviews per product per marketplace** (13 on a well-reviewed listing; thin or
new listings return fewer — 1 to 8 in our 60-ASIN load test) — the marketplace's own "Top reviews" block
plus "Top reviews from other countries". That is everything Amazon serves without a login, on
every marketplace and every proxy rung we measured (details below). If you need the full
paginated review history of a product, read "Read this before you buy rows" first: it explains
why no logged-out scraper can deliver that today, and what the ones claiming to are doing.

```json
{
  "productUrls": ["B09B8V1LZ3", "B0BDHWDR12", "B00FLYWNYQ"],
  "marketplaces": ["amazon.com"],
  "maxItems": 100
}
```

Click **Try for free** and hit **Start** — that block is the input the Actor ships with. A run on
those shipped defaults returned **34 reviews from 3 product pages in
17 seconds** for **$0.10**, with rating, title, body, date and the
"Customers say" aspects filled on 100% of rows.

***

### The wedge: reliability you can schedule, with the histogram and Customers-say aspects on every row

The leader in this lane (4 GB browser build) documents that "residential proxies return results
more stably", runs at a **3.4% failed / timed-out / aborted rate over its last 77,045 runs**, charges a **$0.50 minimum per run**, and is
rated **3.92**; the runner-up is rated **3.88**. Both ratings were read off the Store on
2026-08-22. Every rated Actor in the lane sits under 4.0 — review scraping on Amazon is a
reliability problem, not a parsing problem.

This Actor takes the other trade: **only the public page, so there is no account to get banned,
logged out or cookie-expired — a blocked session is simply retried on a fresh one**. Plain HTTP,
one request per product, a fresh proxy session on every retry, a
4 GB browser nowhere in sight. What you give up is depth (up to ~13 reviews per page instead of a
paginated history). What you get in exchange:

- **`customersSayAspects`** — Amazon's own AI reading of *all* reviews of the product, not just
  the ones on the page: for each aspect ("sound quality", "battery life", "fit"…) the sentiment
  label, how many reviews mention it, how many of those agree with the label, the percentage, and
  up to 4 evidence snippets each tied to a `reviewId`. On the shipped sample that is 7–8 aspects
  per product built from **thousands** of underlying reviews (e.g. "performance: positive, 26,997
  mentions, 97%"). For voice-of-customer work this is a better summary of the product than 500
  scraped rows, and it costs the same as the 8 rows it arrives with.
- **`productRatingHistogram`** — `{"5": 82, "4": 11, "3": 3, "2": 1, "1": 3}`, the star
  distribution behind the average, with `productTotalRatings` (198,409 for the sample Echo Dot).
- **Marketplace fan-out** — give a bare ASIN and a list of marketplaces and you get each
  marketplace's own top-review set for the same listing, deduplicated on `reviewId` across the
  run. Reviews carry `reviewCountry` and `language` so a mixed dataset stays sortable.
- **No minimum charge, no start fee, no browser compute.** $0.003 per review delivered;
  a product that returns nothing costs nothing.

***

### Read this before you buy rows

Five things that would otherwise turn into a refund request.

1. **The page is the ceiling.** Amazon's full review list (`/product-reviews/<ASIN>`, its star
   filters, the "see more reviews" link, the in-page AJAX endpoints and the lazy-widget stream)
   **is closed to every logged-out client** — measured 2026-08-22 on direct, datacenter and
   residential exits, on amazon.com, .co.uk and .de: the paginated list and its star filters 302
   to `/ap/signin` on 27 of 27 calls, the medley AJAX endpoints return Amazon's 404, and the
   lazy-widget stream returns 0 bytes. No route returned a review. This Actor will never log in,
   never replay a session cookie and never solve a CAPTCHA,
   so `maxReviewsPerProduct` cannot raise the per-page count above what the page shows (up to ~13).
   If another scraper returns hundreds of reviews per ASIN, it is reaching a surface this Actor
   deliberately does not touch — check how before you depend on it.
2. **ASINs are marketplace-specific.** The Echo Dot is `B09B8V1LZ3` on amazon.com and amazon.ca
   but a different ASIN on amazon.co.uk and amazon.de, where `B09B8V1LZ3` is an HTTP 404. A 404 is
   logged, counted and **not billed**, but it also returns no rows — paste the marketplace's own
   product URL if you want that marketplace's reviews.
3. **`reviewerId` / `reviewerProfileUrl` are usually absent on "other countries" reviews**
   (measured 76.5% fill on the sample: 100% on local reviews, 20% on the "other countries"
   block). Amazon usually renders foreign reviews without a profile link. `reviewerName` is
   always present.
4. **`helpfulVotes` is a real 0, not a missing value**, and `images` is an empty array for the
   \~77% of reviews with no photo. `variant` (e.g. "Color: Deep Sea Blue | Configuration: Device
   only") only exists on products with variations — 61.8% on the sample.
5. **Filters remove rows you would otherwise have paid for, and that is the point.**
   `filterByRatings`, `verifiedOnly` and `includeInternationalReviews: false` are applied before
   billing; a page whose 8 reviews all fail your filter delivers 0 rows and charges $0.

***

### What you get

One row per unique review. `rating` is an integer 1–5. `date` is ISO `YYYY-MM-DD` parsed from
Amazon's "Reviewed in the United States on June 29, 2026" line (English, German, French,
Spanish, Italian, Portuguese, Dutch, Swedish, Polish and Japanese date formats are handled;
`dateRaw` always keeps the original text). `scrapedAt` is a full UTC timestamp.

| Group | Fields | Example |
|---|---|---|
| **Identity** | `reviewId`, `reviewUrl`, `asin`, `reviewedAsin`, `marketplace`, `position`, `isInternational` | `R3UN7L2595T26X` · `B00FLYWNYQ` (review written on variant `B06Y1YD5W7`) · `amazon.com` |
| **Review** | `rating`, `title`, `body`, `language` | `5` · "Very useful and easy to use" · 3 paragraphs joined with `\n` · `en-US` |
| **Reviewer** | `reviewerName`, `reviewerId`, `reviewerProfileUrl` | `Daimer Castillo` · `AGW3CMD6VFOG25F4S2EPAETVLP3A` |
| **When / where** | `date`, `dateRaw`, `reviewCountry` | `2026-06-29` · `United States` |
| **Trust signals** | `verifiedPurchase`, `vineReview`, `helpfulVotes` | `true` · `false` · `2` |
| **Media / variant** | `images[]`, `hasVideo`, `variant` | 2 image URLs · `Size: 3 Quarts` |
| **Product summary (on every row)** | `productUrl`, `productTitle`, `productAverageRating`, `productTotalRatings`, `productRatingHistogram{}` | `4.7` · `173,570` · `{"5":84,"4":9,"3":3,"2":1,"1":3}` |
| **Customers say (on every row)** | `customersSaySummary`, `customersSayAspects[]` | 8 aspects with sentiment, mentions, %, snippets |
| **Provenance** | `scrapedAt` | `2026-08-22T17:41:05.107Z` |

The dataset ships with a **Reviews** table view (ASIN, stars, title, body, reviewer, date,
country, verified, helpful votes, variant, product average, total ratings, Customers say, link)
so the Console and the Store page render without configuration.

***

### Field fill — measured on 34 reviews

The shipped default run (3 products on amazon.com, 2026-08-22), sorted by fill so the sparse
fields are impossible to miss. Booleans are reported as the share that is `true`.

| Field | Fill | Notes |
|---|---|---|
| `reviewId` / `reviewUrl` / `asin` / `marketplace` | 100% | |
| `rating` | 100% | integer 1–5, read from the star icon's class, not from locale text |
| `title` / `body` | 100% | full text; "Read more" is already expanded in the HTML |
| `reviewerName` | 100% | |
| `date` / `dateRaw` / `reviewCountry` | 100% | |
| `productAverageRating` / `productTotalRatings` / `productRatingHistogram` | 100% | all five star buckets |
| `customersSaySummary` / `customersSayAspects` | 100% on the 3-product sample; ~88% of rows on a wider 26-product run | 6–8 aspects; `null` on listings Amazon has not generated it for (6 of 26 products) |
| `verifiedPurchase` = true | 100% | |
| `helpfulVotes` > 0 | 64.7% | 0 is a real 0 |
| **`reviewerId` / `reviewerProfileUrl`** | **76.5%** | 100% on local reviews, 20% on "other countries" reviews |
| **`variant`** | **61.8%** | only on products with variations |
| **`isInternational`** = true | **29.4%** | the "Top reviews from other countries" block |
| **`images`** (≥1) | **23.5%** | |
| **`vineReview`** = true | **0%** | Vine badges are rare in top-review slots |
| **`hasVideo`** | **0%** | |

**The headline that could mislead you: `customersSayAspects` summarises the whole product, not
the rows in your dataset.** Its mention counts come from Amazon's model over every review of the
product (26,997 mentions of "performance" on the Instant Pot), while the dataset holds the up-to-13
reviews the page shows. Treat it as product-level metadata that happens to ride on each row.

Every run prints its own measured fill in the log.

***

### How to run it

#### 1. ASINs or product URLs (the usual choice)

```json
{
  "productUrls": [
    "B09B8V1LZ3",
    "https://www.amazon.com/dp/B0BDHWDR12",
    "https://www.amazon.co.uk/dp/B0BDHWDR12"
  ],
  "marketplaces": ["amazon.com"],
  "maxItems": 500
}
```

A bare ASIN is read on every marketplace in `marketplaces`; a full URL is read on the marketplace
in the URL, whatever the list says. Accepted URL shapes: `/dp/…`, `/gp/product/…`,
`/gp/aw/d/…`, `/product-reviews/…`, anything with `?asin=`; anything else with a 10-character
ASIN segment is tried too. `amzn.to` short links are not resolved.

#### 2. The same ASIN on several marketplaces

```json
{
  "productUrls": ["B0BDHWDR12"],
  "marketplaces": ["amazon.com", "amazon.ca", "amazon.com.au"],
  "maxItems": 200
}
```

Each marketplace shows its own top-review set, so this is the cheapest way to get more reviews
for one listing without a login — **provided the ASIN exists there** (gotcha 2). Supported:
amazon.com, .co.uk, .de, .ca, .fr, .it, .es, .com.au, .in, .co.jp, .com.mx, .com.br, .nl, .se,
.pl, .ae, .sa, .sg, .com.be, .ie. The proxy country follows the marketplace automatically.

#### 3. Critical reviews only

```json
{
  "productUrls": ["B00FLYWNYQ"],
  "filterByRatings": ["1", "2", "3"],
  "verifiedOnly": true
}
```

Keeps only 1–3-star verified-purchase reviews from the page. Remember the page is the ceiling: a
product whose top reviews are all 5-star returns 0 rows here (and charges nothing).

#### 4. Local reviews only

```json
{ "productUrls": ["B00FLYWNYQ"], "includeInternationalReviews": false }
```

Drops the "Top reviews from other countries" block (the 5 rows flagged `isInternational: true` on
the Instant Pot sample).

#### Scheduling and integrations

Save the input as a **Task** (Console → the Actor → *Save as Task*), attach an Apify **Schedule**
(`0 6 * * 1` for a weekly Monday refresh of a product list) and read the dataset over the REST
API or the standard integrations (Zapier, Make, n8n, webhooks, MCP). Starting a run from the API:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~amazon-reviews-scraper/runs?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"productUrls":["B09B8V1LZ3"],"marketplaces":["amazon.com","amazon.ca"]}'
```

***

### Sample row

A real row from the shipped-default run, 2026-08-22 (body and aspects truncated here; full
length in the dataset).

```jsonc
{
  "reviewId": "R3UN7L2595T26X",
  "reviewUrl": "https://www.amazon.com/portal/customer-reviews/srp/-/R3UN7L2595T26X/ref=cm_cr_dp_d_rvw_ttl",
  "asin": "B00FLYWNYQ",
  "reviewedAsin": "B06Y1YD5W7",
  "marketplace": "amazon.com",
  "rating": 5,
  "title": "Very useful and easy to use",
  "body": "I bought this Instant Pot to save time when cooking, and it has been a great purchase. It cooks food much faster than traditional methods and is very easy to use.\nI have used it for rice, soups, and meat, and everything comes out well cooked…",
  "language": "en-US",
  "reviewerName": "Daimer Castillo",
  "reviewerId": "AGW3CMD6VFOG25F4S2EPAETVLP3A",
  "reviewerProfileUrl": "https://www.amazon.com/gp/profile/amzn1.account.AGW3CMD6VFOG25F4S2EPAETVLP3A",
  "date": "2026-06-29",
  "dateRaw": "Reviewed in the United States on June 29, 2026",
  "reviewCountry": "United States",
  "isInternational": false,
  "verifiedPurchase": true,
  "vineReview": false,
  "helpfulVotes": 2,
  "variant": "Size: 3 Quarts",
  "images": [
    "https://m.media-amazon.com/images/I/51FZBJue3hL._SY500_.jpg",
    "https://m.media-amazon.com/images/I/51t5lJQauRL._SY500_.jpg"
  ],
  "hasVideo": false,
  "position": 1,

  "productUrl": "https://www.amazon.com/dp/B00FLYWNYQ",
  "productTitle": "Instant Pot Duo 7-in-1 Electric Pressure Cooker, Slow Cooker, Rice, Steamer, Sauté, Yogurt Maker, Warmer & Sterilizer, Includes App With Over 800 Recipes, Stainless Steel, 6 Quart",
  "productAverageRating": 4.7,
  "productTotalRatings": 173570,
  "productRatingHistogram": { "5": 84, "4": 9, "3": 3, "2": 1, "1": 3 },
  "customersSaySummary": "Customers find this pressure cooker to be the best kitchen appliance ever, praising its ease of use with features like \"set and forget\" functionality…",
  "customersSayAspects": [
    {
      "aspect": "performance",
      "sentiment": "positive",
      "summary": "Customers find the pressure cooker performs exceptionally well, describing it as the best kitchen appliance ever.",
      "mentions": 26997,
      "sentimentMentions": 26207,
      "mentionsPercentage": 97,
      "snippets": [
        { "reviewId": "R3C1PP7MFJNS5R", "text": "...There is really nothing I don't like about this product. Five stars!" },
        { "reviewId": "R1K2DIKH3XRRY4", "text": "Love it but wish I had waited a bit since I also found a larger one for not much more money…" }
      ]
    }
    // … 7 more aspects
  ],
  "scrapedAt": "2026-08-22T17:41:05.107Z"
}
```

Fields people misread:

- `reviewedAsin` is the variant the reviewer bought; `asin` is the one you asked for. They differ
  whenever a listing has variations (3 Quarts vs 6 Quarts).
- `mentions` counts reviews mentioning the aspect; `sentimentMentions` is how many of those carry
  the labelled sentiment; `mentionsPercentage` is the ratio. `sentiment` is `positive`,
  `negative` or `mixed`.
- `position` restarts at 1 for the international block; use `isInternational` + `position`
  together.

***

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `productUrls` | string list | 3 sample ASINs | ASINs or product URLs, one per line. Empty = the documented sample. |
| `marketplaces` | string list | `["amazon.com"]` | Marketplaces every bare ASIN is read on. |
| `includeInternationalReviews` | boolean | `true` | Keep the "Top reviews from other countries" block. |
| `filterByRatings` | multi-select | `[]` (all) | Keep only these star ratings. Applied before billing. |
| `verifiedOnly` | boolean | `false` | Verified-purchase reviews only. Applied before billing. |
| `maxReviewsPerProduct` | integer | `0` (all on page) | Cap per product × marketplace. Cannot exceed what the page shows. |
| `maxItems` | integer | `100` | **Your hard cost cap** across the run. 100 = $0.30. 0 = no cap (an internal ceiling of 100,000 rows still applies). |
| `requestConcurrency` | integer | `4` | Product pages in flight (1–6). |
| `proxyConfiguration` | proxy | Apify RESIDENTIAL | Country follows the marketplace unless you pin one. |

***

### Pricing

**$0.003 per review delivered — $3 per 1,000.** Charged on the `review-scraped` event. No
start fee, no minimum charge, no monthly fee from this Actor.

| Run | Reviews | Cost |
|---|---|---|
| The shipped default (3 products, amazon.com) | 34 | **$0.10** |
| 100 products, ~10 reviews each | ~1,000 | **~$3.00** |
| 1,000 products × 3 marketplaces | ~30,000 | **~$90** |

- **You are charged for rows delivered.** A review removed by your filters, a duplicate seen on a
  second marketplace, a product that 404s or a page that failed every attempt is never charged.
- **Rows are charged as they are pushed** (`Actor.pushData(items, 'review-scraped')`), so a
  budget cap stops on whole rows, never a half-billed dataset.
- **`maxItems` is your hard cost cap** (default 100). It counts unique delivered reviews.
- The product summary and the "Customers say" aspects ride on every row at no extra charge.

***

### Honest limits

- **At most ~13 reviews per product page, and fewer on thin listings.** Amazon's paginated review
  list is behind a login
  on every marketplace and every proxy rung measured (27/27 calls redirected to sign-in). This
  Actor does not log in, and no input changes that. It is a *top reviews + product sentiment*
  tool, not a review-history exporter.
- **Datacenter proxies are unreliable here.** Measured 2026-08-22 on 7 valid ASINs: direct 7/7,
  Apify datacenter 2/7 (5 CAPTCHA interstitials), Apify RESIDENTIAL 6/7 (one transient proxy
  error). The default is RESIDENTIAL and the Actor retries every failure on a fresh session
  (up to 4 attempts); a page that fails all four is reported, not billed.
- **A CAPTCHA interstitial is never solved.** It is treated as a per-session block and retried on
  a new session. If Amazon challenges every session of a run, you get 0 rows, a status message
  saying so, and no charge.
- **ASINs are marketplace-specific** (see gotcha 2) — a 404 on amazon.de for a US ASIN is Amazon's
  catalogue, not a scraping failure.
- **`reviewerId` is usually absent on international reviews** (2 of 10 carried one on the sample);
  `reviewerName` is always present.
- **"Customers say" is not on every product.** Amazon only generates it for listings with enough
  reviews; on new or thin listings `customersSaySummary` / `customersSayAspects` are `null` — on a
  wider 26-product run that was 6 of 26 products. The three sample products all carry it (7–8
  aspects each).
- **Review text is returned in the language it was written in** (`language` tells you which);
  the Actor does not use Amazon's translate button.

***

### How it works, and what it cost to make reliable

One plain-HTTP request per product × marketplace to `/dp/<ASIN>`, with a desktop-Chrome header
set and an `Accept-Language` matched to the marketplace. The 1.5–3 MB page is stripped of script,
style and SVG before parsing; reviews are read from the review-card containers (each carries the
review id, the ASIN it was written on, locale and marketplace), the histogram from the star-filter
links and progress meters, and the "Customers say" aspects from the base64 JSON Amazon embeds in
that block's own HTML comments. No browser, no JavaScript execution, no API key.

**Transport ladder, measured 2026-08-22 through Apify, one attempt per ASIN, fresh session each:**

| Rung | Result (7 valid ASINs) |
|---|---|
| Direct, no proxy (reported and then ignored — no Apify container has a home IP) | 7/7 pages with reviews |
| Apify proxy, datacenter / auto | **2/7** — 5 CAPTCHA interstitials (native `validateCaptcha`, no third-party vendor), 1 stripped page with no review block |
| Apify RESIDENTIAL, country matched to the marketplace | **6/7** — 1 transient proxy 590, cleared on retry |
| amazon.ca via RESIDENTIAL country-CA | 2/2 |

**Routes that are closed to a logged-out client (all rungs, 2026-08-22):** `/product-reviews/<ASIN>`
page 1, page 2 and `?filterByStar=` → 302 to `/ap/signin` (27/27); `/hz/reviews-render/ajax/medley-reviews/get/`
and `/medley-filtered-reviews/get/` → Amazon's generic 404 (decommissioned); the
`/portal/customer-reviews/ajax/lazy-widgets/stream` loader → HTTP 200 with 0 bytes; `/dp/<ASIN>?filterByStar=`
and `?sortBy=` → the same unfiltered page. The ladder stops there on purpose: the next rungs are a
session cookie or a CAPTCHA solver, and this Actor uses neither.

**Proof runs, through Apify RESIDENTIAL (platform runs, 2026-08-22):** see the run log of any
run — every run prints `HTTP: N attempt(s) — ok / CAPTCHA / stripped / sign-in / 404`. Measured on
the proof runs for this build: prefill, `{}` and `{"helloWorld":123}` runs on build 0.1.1 (2026-08-22, 1024 MB, timeout 300 s) each fetched 3/3 product pages clean on the first attempt — 9/9 through RESIDENTIAL, 0 CAPTCHA, 0 stripped, 34 reviews each in 17 s / 8 s / 12 s; the offline validation run on the same defaults through RESIDENTIAL was 3/3 as well (12/12). Two
unbounded 60-ASIN runs at 1024 MB fetched 23 and 26 product pages clean through RESIDENTIAL before
the container hit its memory limit — see the memory note under "When a run fails".

`robots.txt` on amazon.com does not disallow `/dp/`. Defaults stay gentle: concurrency 4, one
request per product, fresh session per attempt.

***

### Duplicates — measured

Dedupe key is `reviewId`, run-wide, applied **before** billing and **checked** after: if the
dataset ever held two rows with the same review id the run reports it in the log and status
message. Measured on the shipped default: 34 rows, 34 unique ids,
0 duplicates. Duplicates do arise by design when the same ASIN is read on several marketplaces
(a review can appear in one marketplace's local block and another's international block) — those
are dropped and logged.

***

### When a run fails

- **0 rows** → the run *succeeds* with a status message naming why (all pages 404 on that
  marketplace / all attempts CAPTCHA-challenged / every review removed by your filters) and
  charges nothing. The log carries the per-attempt HTTP tally.
- **Invalid ASIN or URL** → warned and skipped; if nothing usable remains the documented sample
  runs instead.
- **Time budget** → the Actor stops starting new pages ~30–60 s before its timeout, pushes what it
  has and sets a status message with the number of pages left. It never ends TIMED-OUT on its own
  account.
- **Duplicate leak** → the run logs the error and sets a status message naming it; the rows are
  already pushed. Dedupe on `reviewId` in your own store as a belt-and-braces check.
- **Large lists need more memory.** At the default 1024 MB, concurrency 4, a 60-product run peaked
  at 1.0 GB and was killed by the platform (exit 137) partway through — rows already delivered
  stay billed. For lists above ~40 products raise the run memory to 4096 MB or split the list.

***

### Who buys this

- **Brands and agencies doing voice-of-customer on Amazon** — `customersSayAspects` is the
  sentiment breakdown, with counts, for a whole product in one row.
- **Sellers tracking competitors** — schedule a product list weekly; the histogram + total-ratings
  trend is the early signal, the top reviews are the evidence.
- **Marketplace analytics and repricing tools** — rating, histogram and review velocity per ASIN
  per marketplace, with no account to maintain.
- **AI agents** — a single deterministic call per ASIN returns the product's rating summary,
  aspect sentiment and the reviews Amazon itself ranks highest. No minimum charge, pay-per-event.
- **Review-monitoring and alerting** — 1–2-star filter + `verifiedOnly`, deduped on `reviewId`
  across runs by your own store.

***

### FAQ

**Does this need an account, a login or cookies?**
No. It reads the public product page only. There is no login, no cookie jar, no CAPTCHA solving
service and no browser automation.

**Why only ~10 reviews per product?**
Because that is what Amazon serves to a logged-out client. The paginated review list redirects to
sign-in on every rung we measured. Read "Honest limits".

**How do I get more reviews for one product?**
Read it on every marketplace where the ASIN exists (`marketplaces`), and paste variant ASINs —
variants with their own listing page carry their own top-review block.

**What is "Customers say"?**
Amazon's AI summary of all reviews of a product, with per-aspect sentiment and mention counts.
This Actor decodes it from the page and ships it on every row.

**Do I need a residential proxy?**
Yes, realistically: 2/7 on datacenter vs 6/7 on residential in the ladder above. RESIDENTIAL is
the default and the country follows the marketplace.

**Two runs — will I get duplicates?**
Within a run, never — every reviewId is deduped run-wide before push. Across runs, yes if the same page shows the same top reviews —
dedupe on `reviewId` in your store.

**Do I get charged for rows a filter removed, or for a 404?**
No. Only delivered rows are charged.

***

### Legal & fair use

This Actor reads public product pages on Amazon marketplaces without logging in, without
cookies and without touching any authenticated surface. Amazon's Conditions of Use restrict
automated access and direct commercial catalogue use to its Product Advertising API (which
publishes ratings but not review text); **you are responsible for complying with Amazon's terms
and with privacy law in your jurisdiction** — rows contain reviewer display names and, for local
reviews, public profile ids.

Amazon® is a trademark of Amazon.com, Inc. This Actor is not affiliated with, endorsed by, or
connected to Amazon.

***

### Feedback

Found a missing field or a marketplace whose date format is not parsed? Open an issue on the
**Issues** tab, and if the Actor earns it, a review on the **Reviews** tab helps other buyers
find it.

# Actor input Schema

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

One Amazon product per line — a bare ASIN ("B09B8V1LZ3") or any product URL (/dp/…, /gp/product/…, amzn.to short links are not resolved). A URL on amazon.co.uk, amazon.de etc. is scraped on that marketplace; bare ASINs use the Marketplaces list below. Leave empty to run the documented sample (3 products).

## `marketplaces` (type: `array`):

Which Amazon sites to read each bare ASIN from. Every ASIN is crossed with every marketplace, and each marketplace shows its own set of top reviews for the same product — the cheapest way to get more reviews per ASIN without a login. Supported: amazon.com, amazon.co.uk, amazon.de, amazon.ca, amazon.fr, amazon.it, amazon.es, amazon.com.au, amazon.in, amazon.co.jp, amazon.com.mx, amazon.com.br.

## `includeInternationalReviews` (type: `boolean`):

Amazon's product page shows the marketplace's own top reviews plus a second block of top reviews from other countries. ON keeps both (rows are flagged with isInternational + reviewCountry). OFF keeps only the marketplace's own reviews.

## `filterByRatings` (type: `array`):

Leave empty to keep every review. Pick e.g. 1 and 2 to keep only critical reviews, or 5 for praise only. Filtered-out reviews are never billed.

## `verifiedOnly` (type: `boolean`):

Drop reviews without Amazon's "Verified Purchase" badge. Filtered-out reviews are never billed.

## `maxReviewsPerProduct` (type: `integer`):

Cap per product page. 0 = everything the public page shows (typically 8–10 local reviews plus a few from other countries). The page is the ceiling: Amazon's full review list is behind a login, and this Actor never logs in.

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

Stop after this many unique reviews across the whole run. 100 reviews = $0.30. Set 0 for no cap.

## `requestConcurrency` (type: `integer`):

Product pages fetched in parallel (1–6). Each page is one request on a fresh proxy session.

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

Apify RESIDENTIAL proxy is the default and is what was measured. The proxy country is matched to each marketplace automatically (US for amazon.com, GB for amazon.co.uk, DE for amazon.de …) unless you pin one here. Datacenter exits hit Amazon's CAPTCHA interstitial far more often — they are retried on fresh sessions but expect fewer rows.

## Actor input object example

```json
{
  "productUrls": [
    "B09B8V1LZ3",
    "B0BDHWDR12",
    "B00FLYWNYQ"
  ],
  "marketplaces": [
    "amazon.com"
  ],
  "includeInternationalReviews": true,
  "filterByRatings": [],
  "verifiedOnly": false,
  "maxReviewsPerProduct": 0,
  "maxItems": 100,
  "requestConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `reviews` (type: `string`):

The dataset of scraped Amazon reviews — one item per unique review, each carrying the product's average rating, total ratings, star histogram and 'Customers say' aspect sentiment.

# 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 = {
    "productUrls": [
        "B09B8V1LZ3",
        "B0BDHWDR12",
        "B00FLYWNYQ"
    ],
    "marketplaces": [
        "amazon.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/amazon-reviews-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 = {
    "productUrls": [
        "B09B8V1LZ3",
        "B0BDHWDR12",
        "B00FLYWNYQ",
    ],
    "marketplaces": ["amazon.com"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/amazon-reviews-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 '{
  "productUrls": [
    "B09B8V1LZ3",
    "B0BDHWDR12",
    "B00FLYWNYQ"
  ],
  "marketplaces": [
    "amazon.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapersdelight/amazon-reviews-scraper --silent --output-dataset

```

## MCP server setup

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