# Trustpilot Reviews Scraper | Includes Company Replies (`themineworks/trustpilot-reviews`) Actor

Scrape Trustpilot business reviews by domain: reviewer, star rating, title, text, date, company reply, trust score & total count. No login, beats the AWS WAF via residential proxies. Works in Claude, ChatGPT & any MCP agent.

- **URL**: https://apify.com/themineworks/trustpilot-reviews.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Lead generation, E-commerce, MCP servers
- **Features:** Limited permissions
- **Stats:** 7 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 reviews

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

## ⭐ Trustpilot Reviews Scraper: Ratings & Replies

> **Part of the Company Diligence MCP.** This actor's data is also available to AI agents through our [Company Diligence MCP server](https://apify.com/themineworks/company-diligence-mcp?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral), ten official-registry tools behind one endpoint. No result, no charge.

> 💰 From $0.45 / 1,000 results.
>
> Guide and FAQs: [Trustpilot Reviews Scraper on themineworks.com](https://themineworks.com/actors/trustpilot-reviews/). Tutorial: [Scrape Trustpilot Reviews by Company Domain in Python](https://themineworks.com/blog/trustpilot-reviews-scraper-api/).

> ⚡ 16 of 17 runs succeeded in the last 30 days · no login, no API key, residential proxy included to clear Trustpilot's AWS WAF.

> 💸 You're only charged for delivered results. Empty searches, failed pages and duplicate listings are never billed.

### Overview

Trustpilot Reviews Scraper pulls the full public review history for any business on Trustpilot. Give it a domain like `amazon.com`, `booking.com`, or `nike.com` and get back every review as structured JSON: reviewer name, star rating, title, body text, publish date, company reply, plus the business's overall TrustScore and total review count. Optionally filter to just 1-star and 2-star reviews to focus on complaints.

It beats Trustpilot's AWS WAF (which blocks almost every data-centre IP) using a residential proxy pool, so runs return actual data instead of a challenge page. No login, no API key, priced pay per review. Blocked pages, missing domains, and failed runs are never charged. You only pay for a review that was actually delivered.

✅ No login required | ✅ Residential proxy included | ✅ Pay per review returned | ✅ MCP-ready for AI agents

### Features

Full review scrape. Every public review on the business page paginated to the end.
Star filter. Return only 1-star and 2-star reviews for churn or complaint analysis.
Company replies. Reply text and reply date included on every review that has one.
Business summary. Overall TrustScore and total review count included per business.
Ban-resistant. Residential proxy pool clears the AWS WAF that stops data-centre scrapers.

### How it works

The actor takes a business domain (`amazon.com`), normalises it to the Trustpilot slug (`https://www.trustpilot.com/review/amazon.com`), and requests the review pages through Apify's residential proxy pool. Trustpilot fronts every page with an AWS WAF challenge that blocks almost every data-centre IP: residential IPs clear the challenge and get the real page.

Each page is parsed for reviews (reviewer, rating, title, text, date, reply) and paginated until the `maxResults` budget is hit or the business runs out of reviews. Star-rating filters are applied client-side, so you can pull only the 1-star and 2-star reviews for churn work without paying for the rest.

### 🧾 Input configuration

Pass a **list** of companies in one run. That is materially cheaper per review than one run
each, and it is the same number of reviews (see *Batching* below).

```json
{
  "companyDomains": ["amazon.com", "booking.com", "etsy.com"],
  "maxResults": 200,
  "starsFilter": ["1", "2"],
  "includeReviewInsights": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

### 💡 Batching: why one run with many companies is cheaper

Trustpilot fronts every page with an AWS WAF bot check. Clearing it requires one real browser
page load, which is by far the most expensive thing this actor does. The clearance token it
produces is scoped to **trustpilot.com**, not to the one company page it was minted on, so a
single solve covers every company in the same run and all their pagination.

Verified live: a token minted on `amazon.com` then fetched `booking.com`, `etsy.com` and
`ryanair.com` over plain HTTP, plus cross-company page 2, all returning full data. The same
requests without the token are rejected.

| Companies in one run | Approx. cost per 1,000 reviews |
| --- | --- |
| 1 | $0.16 |
| 20 | **$0.07** |
| 50 | **$0.07** |

So twenty companies in one run costs roughly a third per review of twenty separate runs. Each
run's summary reports `browser_pages`, it should stay at about **1** however many companies
you pass. If it climbs, the WAF is rejecting our token and the actor says so rather than
quietly costing more.

`maxResults` applies **per company**, and with `includeReviewInsights` on you get one insights
row per company. Multi-company runs also emit a `_type: "run_summary"` row with the totals and
the realised cost per 1,000.

### 📤 Output format

Each run pushes two kinds of records: one business summary record (once per run) and one record per review. Here is a real review record captured from a live run against `amazon.com`:

```json
{
  "business_domain": "amazon.com",
  "reviewer_name": "John",
  "rating": 1,
  "title": "Amazon lost my package and then updated…",
  "text": "Amazon lost my package and then updated the package as undeliverable, then Amazon tried to blame Intelcom for losing the package, but Intelcom didn't even have the package ever in their possession. Amazon lied to me about who's fault it was. Then Amazon says I have to wait a week or more before they can return my money, because they say that's the waiting period to see if the package gets delivered, but the package tracking on the Amazon site clearly says the package is undeliverable. Amazon makes you wait for your refund when it's clearly their lies and fault the package was lost.",
  "review_date": "2026-07-15T00:30:31.000Z",
  "review_url": "https://www.trustpilot.com/reviews/6a56b8878caf7c42b6979634",
  "review_id": "6a56b8878caf7c42b6979634",
  "scraped_at": "2026-07-15T04:17:40.059Z"
}
```

And the business summary record from the same run:

```json
{
  "_type": "business",
  "business_domain": "amazon.com",
  "business_name": "Amazon",
  "overall_rating": 1.6,
  "total_reviews": 47501,
  "trustpilot_url": "https://www.trustpilot.com/review/amazon.com",
  "scraped_at": "2026-07-15T04:17:39.772Z"
}
```

Fields on the business summary record:

| Field | Description |
| --- | --- |
| 🌐 `business_domain` | Company domain scraped (e.g. `amazon.com`) |
| 🏢 `business_name` | Business name as displayed on Trustpilot |
| ⭐ `overall_rating` | Overall TrustScore for the business |
| 🔢 `total_reviews` | Total number of reviews on the business page |
| 🔗 `trustpilot_url` | The Trustpilot review page scraped |
| 🕒 `scraped_at` | ISO timestamp of the scrape |

Fields on each review record:

| Field | Description |
| --- | --- |
| 🌐 `business_domain` | Company domain scraped (e.g. `amazon.com`) |
| 🙋 `reviewer_name` | Display name of the reviewer |
| ⭐ `rating` | Star rating (1 to 5) |
| ✍️ `title` | Review headline |
| 📝 `text` | Full review body text |
| 📅 `review_date` | ISO date the review was published |
| 🔗 `review_url` | Direct link to the review on Trustpilot |
| 🆔 `review_id` | Trustpilot's internal review ID |
| 💬 `reply_text` | Company reply text, present only when the business replied |
| 🕒 `scraped_at` | ISO timestamp of the scrape |

#### Review insights (optional, `includeReviewInsights: true`)

One extra record per run, computed entirely from the reviews already collected in that
same run, no extra fetch, no AI, nothing non-deterministic. Real output from a live run
against `amazon.com`:

```json
{
  "_type": "review_insights",
  "business_domain": "amazon.com",
  "rating_distribution": {
    "1_star": { "count": 44, "pct": 73.3 },
    "2_star": { "count": 8, "pct": 13.3 },
    "3_star": { "count": 4, "pct": 6.7 },
    "4_star": { "count": 1, "pct": 1.7 },
    "5_star": { "count": 3, "pct": 5.0 }
  },
  "reply_rate_negative_pct": 0,
  "top_complaint_terms": [
    { "term": "delivery", "count": 29 },
    { "term": "customer service", "count": 22 },
    { "term": "prime", "count": 15 },
    { "term": "order", "count": 15 }
  ],
  "rating_trend": [
    { "month": "2026-06", "review_count": 18, "avg_rating": 1.4 },
    { "month": "2026-07", "review_count": 42, "avg_rating": 1.6 }
  ],
  "based_on_reviews": 60,
  "based_on_negative_reviews": 52,
  "computed_at": "2026-08-14T10:06:24.325Z"
}
```

| Field | Description |
| --- | --- |
| ⭐ `rating_distribution` | Count and percentage of reviews at each star level |
| 💬 `reply_rate_negative_pct` | Share of 1 and 2 star reviews that got a business reply |
| 🔎 `top_complaint_terms` | The most frequent words and two-word phrases in negative review text, ranked by count. This is word and phrase frequency, not an AI reading the reviews for you, a real signal, computed instantly, at no AI cost |
| 📈 `rating_trend` | Average rating by month, only included when reviews span 2 or more months (a single month is a snapshot, not a trend, so it is left out rather than shown as fake) |
| 🔢 `based_on_reviews` / `based_on_negative_reviews` | How many reviews the insights were computed from |

Only computed and charged when at least one review was delivered, an empty or blocked
run never produces or charges for this record.

### 💼 Common use cases

**Customer & churn insight**
Pull every 1-star and 2-star review for your product or a competitor and cluster the complaints.
Feed reviews into an LLM to surface recurring themes and priority fixes.

**Competitor teardown**
Compare TrustScores and review volume across a competitor set.
Read the top complaints and top praise for a competitor to sharpen positioning.

**Reputation monitoring**
Watch your own business page for new negative reviews on a daily cadence.
Track how quickly and consistently the company responds to reviews.

**Due diligence & investing**
Pull every review for a target acquisition to gauge product and support quality.
Spot patterns of fraud, delivery issues, or refund refusals before buying in.

### 🚀 Getting started

1. Open the actor and enter one or more domains in `companyDomains` (e.g. `["booking.com", "etsy.com"]`).
   Batching is cheaper per review than separate runs. The older single `companyDomain` field
   still works if you are already using it.
2. Set `maxResults`, this is the cap **per company**.
3. Optionally set `starsFilter` (e.g. `["1", "2"]`) to focus on negative reviews.
4. Leave the residential proxy on (required to clear the AWS WAF).
5. Click Start. Download as JSON, CSV, or Excel, or pull the dataset via API or MCP.

### 💵 Pricing

**Reviews now cost from $0.45 per 1,000**, an 80%+ cut, passed straight through from a
rebuilt fetch path (see *How it works*) that made runs about 8x cheaper to operate.

> 💎 On the `GOLD` tier and above: **$0.45 per 1,000 results** ($0.00045 each, 31% below the `FREE`-tier price of $0.00065). Your tier is shown on your Apify billing page.

> **How many reviews you can actually get:** Trustpilot's public site stops serving after
> **10 pages, about 200 reviews per business**, and asks for a login beyond that. Measured
> live 2026-08-14: a run asking for 400 returned exactly 200 and stopped cleanly. `maxResults`
> above ~200 will simply return everything available and finish; you are never charged for
> reviews that do not exist. To go deeper, run again with a different `starsFilter`, each
> filtered view opens its own 10-page window.

Three pay-per-event charges:

- **`apify-actor-start`**, charged once when a run starts. This covers the single real-browser
  page load that clears Trustpilot's bot check for the entire run. Charging it separately is
  exactly what lets the per-review price be this low, instead of burying that fixed cost in
  every review.
- **`review-scraped`**, charged when a review record lands in your dataset.
- **`review-insights-computed`**, charged once per business analyzed, only when
  `includeReviewInsights` is `true` and at least one review was delivered.

Apify applies a discount tier to your account. Price at each tier:

| Apify tier | Per 1,000 reviews | Actor start | `review-insights-computed` |
| --- | --- | --- | --- |
| FREE | $0.65 | $0.05 | $0.02 |
| BRONZE | $0.58 | $0.04 | $0.02 |
| SILVER | $0.52 | $0.03 | $0.02 |
| GOLD | $0.45 | $0.025 | $0.02 |
| PLATINUM | $0.45 | $0.025 | $0.02 |
| DIAMOND | $0.45 | $0.025 | $0.02 |

Worked example, FREE tier: 200 reviews from one business, with insights, is
`$0.05 start + 200 × $0.00065 + $0.02` = **$0.20**. Your tier is shown on your Apify billing page.

`review-insights-computed` is flat across every tier, it is a per-run analysis charge, not a
per-record discount.

Pay-per-event, no subscription and no monthly minimum. WAF-blocked pages, unknown domains, and failed or empty runs are never billed, the charge fires only when a review is actually delivered to your dataset.

### Run it on a schedule

Turn on `monitorMode` and each run delivers only the reviews you have not received before, so a daily run costs you only for what is new.

1. Enter your input, switch on **Monitor mode** and click **Save as a task**.
2. In Apify Console open **Schedules**, click **Add schedule** and pick **Daily** (or any time and timezone you like).
3. Under **Actors or tasks to run**, add the task you saved and save the schedule.

```json
{
  "companyDomains": [
    "booking.com",
    "etsy.com"
  ],
  "maxResults": 100,
  "starsFilter": [
    "1",
    "2"
  ],
  "monitorMode": true
}
```

The first run delivers everything it finds. After that, each run delivers only reviews that were not in an earlier run with the same input, and reviews it skips are never charged. The summary row at the end shows `new_this_run` and `skipped_duplicates`. Changing the input starts a fresh history; changing only the result limit does not. When nothing new turns up, a company stops after three pages in a row of reviews you already have. A long list of companies that turns up little new can stop before its last companies to keep request costs in line; the log names the companies not checked, and none of them are charged. The business summary row is still written on every run and is never charged, so your dataset keeps a record of the TrustScore and review count over time. With `includeReviewInsights` on, the insights row covers only the new reviews of that run.

### FAQ

**Why do I need a residential proxy?**
Trustpilot fronts every page with an AWS WAF challenge that blocks almost every data-centre IP. Residential IPs from real consumer ISPs clear the challenge and return the real page. Data-centre proxies will just return a challenge page.

**How many reviews can I pull for one business?**
As many as the business has publicly, up to Trustpilot's ~200-per-company public ceiling. The actor paginates to the end within your `maxResults` budget, which applies per company.

**How much does it cost?**
Pay per review returned, pay as you go. No subscription, no monthly minimum.

**Can I use it in an AI agent?**
Yes. It's exposed as an MCP tool. See below.

**Does Trustpilot have a public API?**
Trustpilot does publish APIs, but they require a Trustpilot for Business account and an API key (Client ID), that applies even to the public Business Units endpoints. There is no open, keyless endpoint for pulling any company's reviews. This actor reads the public review pages a logged-out visitor already sees, so it needs no Trustpilot account, key, or OAuth flow.

**Can I pull only the negative reviews?**
Yes. Set `starsFilter` to `["1", "2"]` and only those ratings are kept, so you can build a complaint corpus without paying for the 4- and 5-star reviews you don't need.

**What can I legitimately use scraped Trustpilot reviews for?**
Reputation monitoring, competitor and market research, customer-complaint analysis, and pre-acquisition due diligence on reviews that are already public. This actor is read-only, it cannot post, edit, flag, or remove reviews, and it is not a tool for influencing ratings. Treat reviewer names as personal data: analyse reviews in aggregate rather than using them to identify or target individual reviewers.

### Use in Claude, ChatGPT & any MCP agent

```
https://mcp.apify.com/?tools=themineworks/trustpilot-reviews
```

Or call it programmatically with the Apify client:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('themineworks/trustpilot-reviews').call({
  companyDomains: ['amazon.com', 'booking.com'],
  maxResults: 100,   // per company
  starsFilter: ['1', '2'],
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### 🛠️ Complete your competitor & reputation pipeline

Got the reviews. Now build the wider picture:

- **[Google Trends Scraper](https://apify.com/themineworks/google-trends-pro?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)**: track brand interest for the same business over time.
- **[Meta Ad Library Scraper](https://apify.com/themineworks/meta-ad-library-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)**: see how the brand is running paid creative right now.
- **[LinkedIn Company Scraper](https://apify.com/themineworks/linkedin-company-details?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)**: profile the business with size, industry, HQ, and website.

Typical flow: trustpilot-reviews reveals what customers actually think, google-trends shows demand, meta-ad-library shows the creative response.

Questions or need a custom field set? Reach out through the Apify profile.

# Actor input Schema

## `companyDomains` (type: `array`):

Trustpilot company domains to scrape, for example \["amazon.com", "booking.com"]. Batching is much cheaper per review than separate runs: clearing Trustpilot's bot check costs one real browser page load, and that clearance then covers every company in the same run. Twenty companies in one run costs roughly a third per review of twenty single-company runs. Max reviews applies PER company.

## `companyDomain` (type: `string`):

Single company domain, for example "amazon.com". Kept for existing runs and saved tasks; prefer Company domains above, which accepts a list and is cheaper per review. If both are given, the list wins.

## `maxResults` (type: `integer`):

Maximum reviews PER COMPANY (not per run), so 100 with three companies can return up to 300. Trustpilot's public site serves about 200 reviews per company (10 pages) before asking for a login, so a higher value returns everything available and finishes early. You are never charged for reviews that do not exist. Use the star rating filter to open a fresh 10-page window.

## `starsFilter` (type: `array`):

Only keep reviews with these star ratings (1-5). Leave empty to keep all ratings. Example: \[1, 2] for negative reviews only.

## `includeReviewInsights` (type: `boolean`):

Adds one extra insights row PER COMPANY: a rating breakdown, the most common phrases in negative reviews, the reply rate on negative reviews, and a month by month rating trend. Computed entirely from the reviews already collected in this run, no AI, no extra fetch. Off by default. Only charged for a company that actually returned at least one review.

## `monitorMode` (type: `boolean`):

Run on a schedule and deliver ONLY reviews not seen in a previous run. You are charged per new review, not for the whole feed each time. Ideal for daily monitoring. Requires the same input across runs.

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

Trustpilot fronts every page with an AWS WAF challenge that blocks datacenter IPs. RESIDENTIAL proxies are REQUIRED for this actor to return data.

## Actor input object example

```json
{
  "companyDomains": [
    "amazon.com",
    "booking.com"
  ],
  "companyDomain": "amazon.com",
  "maxResults": 25,
  "starsFilter": [
    "1",
    "2"
  ],
  "includeReviewInsights": false,
  "monitorMode": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# 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 = {
    "companyDomains": [
        "amazon.com",
        "booking.com"
    ],
    "companyDomain": "amazon.com",
    "maxResults": 25,
    "starsFilter": [
        "1",
        "2"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/trustpilot-reviews").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 = {
    "companyDomains": [
        "amazon.com",
        "booking.com",
    ],
    "companyDomain": "amazon.com",
    "maxResults": 25,
    "starsFilter": [
        "1",
        "2",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/trustpilot-reviews").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 '{
  "companyDomains": [
    "amazon.com",
    "booking.com"
  ],
  "companyDomain": "amazon.com",
  "maxResults": 25,
  "starsFilter": [
    "1",
    "2"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call themineworks/trustpilot-reviews --silent --output-dataset

```

## MCP server setup

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

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/J3Gzx69GH0PPcQkPT/builds/tLxMApcMa09BZ6cxa/openapi.json
