# Amazon Reviews Scraper - Thousands, Not Hundreds (`heroic_wagon/amazon-reviews-scraper`) Actor

Most Amazon review scrapers stop at 100 to 500 reviews per product and never tell you. This one works past that limit and reports exactly what percent of Amazon's written reviews you received, broken down by star rating.

- **URL**: https://apify.com/heroic_wagon/amazon-reviews-scraper.md
- **Developed by:** [Red Reap](https://apify.com/heroic_wagon) (community)
- **Categories:** E-commerce, Marketing, Automation
- **Features:** Limited permissions
- **Stats:** 4 total users, 2 monthly users, 92.3% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $6.00 / 1,000 unique reviews

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

### How does Amazon Reviews Scraper work?

This Actor collects Amazon product reviews past the limit that stops every other scraper, and tells
you what percent of them you received.

Amazon returns at most ten pages of ten reviews behind any single filtered view. Ask for a product's
reviews and you get a few hundred, whatever the product actually has. This Actor splits the review
pool into hundreds of small filtered views, each one under that ceiling, and collects them all.

1. **Input parameters.** Provide one or more ASINs, or any Amazon product or review URLs, up to 100
   per run. Choose the marketplace, and optionally how complete you want the result, a source
   budget, or specific star ratings.
2. **Collection.** The Actor reads how many written reviews Amazon reports for each star rating,
   then collects across many narrow filtered views, so that no single view runs into Amazon's cap.
3. **Deduplication.** The same review appears in many views. Duplicates are removed before anything
   is written, and you are never charged for them.
4. **Totals you can check.** Alongside the reviews, the Actor writes one row per product giving
   Amazon's own written review count, how many of them you received, the split by star rating, and
   why collection stopped for each one.

Reviews are delivered to your dataset and can be downloaded as JSON, CSV, Excel, XML or HTML, or
pulled straight from the Apify API.

**This Actor needs a paid Apify plan.** It buys review rows from a separate Store Actor, and that
Actor does not serve free-plan accounts. On a free plan this run stops immediately and tells you so
without charging you for any reviews.

### Input data

| Field | Required | Default | What it does |
|---|---|---|---|
| `asins` | Yes | | Bare ASINs, or any Amazon product or reviews URL. Up to 100 per run. |
| `marketplace` | No | `com` | Which Amazon domain to read. Reviews differ per marketplace. |
| `targetCoveragePercent` | No | `85` | Stop collecting a star rating once this much of it is held. |
| `maxSpendUsd` | No | `5` | Hard cap on what the run spends buying rows, enforced in code before every call. |
| `stars` | No | all five | Collect only certain ratings, for a cheaper focused run. |
| `collectionHints` | No | none | Words you know appear in this product's reviews. Helps on products with distinctive vocabulary. Does not filter your results. |
| `excludeReviewIds` | No | none | Review IDs you already hold. Suppressed before anything is written, so you are not charged for them. |
| `useSavedState` | No | `true` | Remember what was delivered per product and send only new reviews next run. |
| `maxCollectionRounds` | No | `40` | Set to `0` for a faster, cheaper run that collects less. |

A sample input:

```
{
  "asins": [
    "B0747FGGVC",
    "https://www.amazon.com/dp/B0BFSM1GHJ"
  ],
  "marketplace": "com",
  "targetCoveragePercent": 95,
  "maxSpendUsd": 5.0,
  "stars": ["five_star", "four_star", "three_star", "two_star", "one_star"],
  "collectionHints": ["battery", "accurate", "app"],
  "useSavedState": true
}
```

### Output data

Two record types land in the same dataset, separated by `record_type`. Use the **Reviews** dataset
view for the reviews alone and the **Review totals** view for the per-product counts.

A review record, taken from a live run:

```
{
  "record_type": "review",
  "review_id": "R2FY6UHDSQLZA7",
  "asin": "B0747FGGVC",
  "rating": 5,
  "star": "five_star",
  "title": "I like real time tracking.",
  "text": "I like real time tracking.",
  "date": "2026-05-12",
  "country": "United States",
  "verified": true,
  "vine": false,
  "helpful_votes": 1,
  "image_urls": [],
  "video_urls": [],
  "variant": null,
  "variant_asin": null,
  "review_url": "https://www.amazon.com/gp/customer-reviews/R2FY6UHDSQLZA7",
  "word_count": 10,
  "found_in_window": "five_star/recent"
}
```

Every field on a review record:

| Field | Type | What it is |
|---|---|---|
| `record_type` | string | `review` or `coverage_report`. |
| `review_id` | string | Amazon's review ID, unique across the marketplace. |
| `asin` | string | ASIN the review was collected for. |
| `rating` | number | Star rating, 1 to 5. |
| `star` | string | Star filter the review belongs to, for example `five_star`. |
| `title` | string, null | Review title. Null when the reviewer left none. |
| `text` | string, null | Review body, exactly as Amazon serves it. |
| `date` | string, null | Review date, normalized to `YYYY-MM-DD`. |
| `country` | string, null | Country the review was written in. |
| `verified` | boolean | Verified purchase. |
| `vine` | boolean | Vine Voice review. |
| `helpful_votes` | integer | Helpful votes at the time of collection. |
| `image_urls` | array | Images attached to the review. |
| `video_urls` | array | Videos attached to the review. |
| `variant` | string, null | Product variant reviewed. |
| `variant_asin` | string, null | ASIN of that variant. |
| `review_url` | string | Permalink to the review. |
| `word_count` | integer | Words in title plus body. |
| `found_in_window` | string | Which Amazon filter combination surfaced it. |

Reviewer names and profile links are never collected, in any field.

The totals record, one per product:

```
{
  "record_type": "coverage_report",
  "asin": "B0747FGGVC",
  "amazon_written_review_count": 750,
  "reviews_delivered": 701,
  "coverage_percent": 93.5,
  "per_star": [
    { "star": "five_star", "amazon_written_count": 519, "held": 473,
      "coverage_percent": 91.1, "missing": 46, "stopped_reason": "spend cap reached" },
    { "star": "four_star", "amazon_written_count": 107, "held": 104,
      "coverage_percent": 97.2, "missing": 3, "stopped_reason": "target reached" }
  ],
  "run_status": "stopped-short"
}
```

If a run reaches 71%, the report says 71%, names the ratings that fell short, and says why each one
stopped. When your budget ends a run early it says so, rather than presenting a partial result as a
complete one.

### Supported Amazon domains

Seventeen marketplaces:

`amazon.com`, `amazon.co.uk`, `amazon.de`, `amazon.fr`, `amazon.it`, `amazon.es`, `amazon.ca`,
`amazon.com.mx`, `amazon.com.au`, `amazon.co.jp`, `amazon.in`, `amazon.nl`, `amazon.com.br`,
`amazon.sg`, `amazon.ae`, `amazon.se`, `amazon.pl`

Reviews differ per marketplace, so each one is a separate run.

### How much does Amazon Reviews Scraper cost?

There are two charges, and you should know about both before your first run.

**This Actor** charges per unique review delivered, plus a flat fee for the per-product totals
record. Duplicates are never charged, however many filtered views they turn up in. Current prices
are on the pricing tab of this listing.

**The underlying row fetcher** is a separate Store Actor, billed to your own account at its own
price. This is the larger of the two charges. The `maxSpendUsd` input caps it in code before every
call, so a run cannot spend past the figure you set, and a run that reaches the cap stops cleanly
and still reports everything it collected.

Estimating the total up front is difficult, because what a product costs depends on how its reviews
are distributed rather than simply on how many it has. Start with the prefilled budget on one
product, read your actual usage on the run detail page, and scale from there.

### What to consider when using this Actor

1. **Small products come back nearly complete.** A few hundred reviews finishes in the nineties. A
   product with thousands levels off near 85%, and that is a property of Amazon, not of this Actor.
   The last slice is one-line reviews whose only words are the commonest ones, so they exist only
   inside views Amazon truncates. The report tells you this instead of hiding it.
2. **Amazon's headline number is ratings, not reviews.** A product showing 38,000 ratings may hold
   12,000 written reviews. Only written reviews have text, and the percentages count only those.
3. **Repeat runs are cheap.** With `useSavedState` on, the Actor remembers what it already delivered
   per product and sends only new reviews next time, so you are not billed twice for the same row.
4. **Set a budget you are comfortable with.** `maxSpendUsd` is enforced in code before every call,
   not estimated afterward. Pair it with the run's own maximum cost setting to cap both halves.
5. **No credentials, ever.** This Actor sends no cookie, signs in to nothing, and never collects
   reviewer identity.
6. **A paid Apify plan is required.** The row source will not serve a free-plan account. If yours
   is free, the run stops on its first call, says exactly that, and charges you nothing for
   reviews.

### Reliability and data handling

**This Actor holds no credential.** It sends no cookie, signs in to nothing, and stores no account
of any kind. There is nothing here to share and nothing here to suspend. That is a deliberate limit
rather than an oversight: it is also why the Actor cannot reach anything Amazon shows only to
signed-in visitors.

**No reviewer identity, ever.** Display names, profile links and Amazon account IDs are dropped
before anything is written. There is a test in the suite asserting it, so it cannot regress
quietly. If you need reviewer identity, this is the wrong Actor.

**Proxies, geo targeting and captchas are handled, by a third party we do not audit.** Row fetching
is done by a separate, long-established Store Actor that carries its own proxy pool and solves
blocks and captchas under the hood, billed to your account at its own price. You never configure a
proxy. How that supplier obtains its data inside its own infrastructure is not something we can
verify for you, and we would rather say so than imply an audit we have not performed.

**Review text is never altered.** No escaping, no trimming, no normalizing of the body or title.
What Amazon served is what lands in your dataset, which is the only honest thing to do with text
you intend to analyze. See the spreadsheet note at the end for the one consequence of that.

**The documented input matches the shipped input.** A test asserts that every default in the input
schema equals what the code actually uses, so the table above cannot drift away from the Actor.

### Use cases

1. **Ongoing review monitoring, the cheapest way to run this.** Collect a product once, then
   schedule the same run on a timer with `useSavedState` left on. Reviews you already hold are
   never charged again and still count toward your coverage percent, so every run after the first
   bills only for what is genuinely new while the report keeps telling you where you stand. This is
   how to watch a catalogue without paying for it twice.
2. **Brand review monitoring.** Track everything customers write about your products, not the most
   recent hundred, and know what fraction of the record you are looking at.
3. **Sentiment analysis with a stated denominator.** Sentiment drawn from a few hundred reviews of a
   twelve thousand review product is a sample nobody measured. This gives you the sample size.
4. **Competitor teardown.** Pull the full written record on a rival product and find the complaints
   that repeat, including the ones buried past the first hundred.
5. **Product quality and defect discovery.** Low-star reviews are where failure modes live, and star
   filters let you buy only those for a fraction of a full run.
6. **Market and academic research.** Research that cites review data has to say how much of the
   record it actually read. The totals record is designed to be quoted.
7. **Training and evaluation datasets.** Large, deduplicated, text-bearing review corpora with
   verified-purchase and helpfulness signals attached.
8. **Due diligence.** Before acquiring a brand or a listing, read the whole review history rather
   than the page-one summary.
9. **Review-led content.** Comparison pages and buying guides built on the full record.

### Opening the data in a spreadsheet

Review text is delivered exactly as Amazon serves it. A few reviews begin with `=`, `+`, `-` or `@`,
which Excel, Google Sheets and LibreOffice read as the start of a formula.

Prefer the JSON or the API for anything automated, where no formula evaluation happens. If you need
a spreadsheet, import the CSV rather than double-clicking it and set the title and text columns to
Text: in Excel use Data, then From Text/CSV, then Transform; in Google Sheets untick "Convert text
to numbers, dates, and formulas."

This Actor deliberately does not alter those characters, because prefixing them would store a
character Amazon never wrote and corrupt the text for every consumer reading the JSON.

# Actor input Schema

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

Amazon products to cover, up to 100 per run. Each entry is a bare ASIN (B06XVZ6Y4T) or any Amazon product or reviews URL. The source budget is shared across all of them.

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

Amazon domain to read. Reviews differ per marketplace; each one is a separate job.

## `targetCoveragePercent` (type: `integer`):

Stop a star rating once this percent of its written reviews is held. Very high targets cost disproportionately more than moderate ones, because the last reviews of any product are the hardest to reach.

## `maxSpendUsd` (type: `number`):

Hard cap on what this run spends buying review rows from the underlying scraper, enforced in code before every call. The row source requires a paid Apify plan; on a free plan the run stops immediately and charges nothing. It does not cover this Actor's own per-review price, which you cap with the run's maximum cost. Start with the prefilled value on one product, then read your actual usage and scale from there.

## `stars` (type: `array`):

Leave empty for all five. Restricting to one or two ratings makes a cheap run that covers only those.

## `collectionHints` (type: `array`):

Optional words or short phrases you already know appear in this product's reviews, up to 200. They help the run reach more of the reviews on products with distinctive vocabulary. They do not filter your results: everything the run collects is delivered either way. A multi-word entry is matched as a group, and punctuation and apostrophes may not match exactly as typed.

## `excludeReviewIds` (type: `array`):

Amazon review IDs you already hold. They are suppressed before anything is written, so you are not charged for them.

## `useSavedState` (type: `boolean`):

Remember which reviews this account has already been given for each ASIN and marketplace, and deliver only new ones next time. Reviews you already hold are never charged again, and they still count toward your coverage percent, so a repeat run on the same product costs a fraction of the first. Leave this on for monitoring; turn it off to re-collect a product from scratch.

## `maxRequestsPerAsin` (type: `integer`):

Safety limit on how many requests a single ASIN may make to the row source. Your source budget normally stops a run long before this does.

## `maxCollectionRounds` (type: `integer`):

How many additional collection passes the run may make. Set to 0 for a faster, cheaper run that collects less.

## `rowSourceActorId` (type: `string`):

Advanced. Overrides which Store Actor fetches the review rows. Leave this alone unless support has told you to change it.

## Actor input object example

```json
{
  "asins": [
    "B0BFSM1GHJ"
  ],
  "marketplace": "com",
  "targetCoveragePercent": 95,
  "maxSpendUsd": 1,
  "stars": [],
  "collectionHints": [],
  "excludeReviewIds": [],
  "useSavedState": true,
  "maxRequestsPerAsin": 5000,
  "maxCollectionRounds": 40
}
```

# Actor output Schema

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

No description

## `coverageReport` (type: `string`):

No description

## `summary` (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 = {
    "asins": [
        "B0BFSM1GHJ"
    ],
    "targetCoveragePercent": 95,
    "maxSpendUsd": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("heroic_wagon/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 = {
    "asins": ["B0BFSM1GHJ"],
    "targetCoveragePercent": 95,
    "maxSpendUsd": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("heroic_wagon/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 '{
  "asins": [
    "B0BFSM1GHJ"
  ],
  "targetCoveragePercent": 95,
  "maxSpendUsd": 1
}' |
apify call heroic_wagon/amazon-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,heroic_wagon/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/4COEWWfRdk6Ewr287/builds/gNKV3DoNRDmeZQHCh/openapi.json
