# Trustpilot Reviews Scraper - TrustScore, Stars & Replies (`lanternlab318/trustpilot-reviews`) Actor

Trustpilot reviews by business URL or domain: rating, title, text, language, country, dates and the company's reply, plus TrustScore, review count and categories. Filter by language and stars. No login or cookies; reviewer names are never collected. Partial results are marked.

- **URL**: https://apify.com/lanternlab318/trustpilot-reviews.md
- **Developed by:** [Lantern Lab](https://apify.com/lanternlab318) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.49 / 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.

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

Give it Trustpilot business URLs or website domains and get the public reviews back: star rating, title, full text, language, the reviewer's **country**, publish and experience dates, verification label and the **company's reply**. Each business also gets its **TrustScore**, total review count, categories and the contact details it published on Trustpilot. Filter by language and star rating. No Trustpilot login, no cookies, no account - and no reviewer names.

**Price:** you pay per review collected. Business rows, status rows and the run summary are free, and so is a URL or domain that finds nothing.

### Quick example

Input:

```json
{
  "businessUrls": ["https://www.trustpilot.com/review/www.bol.com"],
  "domains": ["zalando.de"],
  "maxReviewsPerBusiness": 100,
  "languages": ["all"],
  "stars": []
}
```

One review row (`recordType: "review"`, text shortened):

```json
{
  "recordType": "review",
  "reviewId": "6ad3165b6727fdb98dc1f8bd",
  "reviewUrl": "https://www.trustpilot.com/reviews/6ad3165b6727fdb98dc1f8bd",
  "businessName": "Bol",
  "businessDomain": "www.bol.com",
  "rating": 1,
  "title": "About two years ago",
  "text": "About two years ago, I bought a computer and sent it in for warranty service ...",
  "language": "en",
  "country": "NL",
  "publishedAt": "2026-10-17T08:31:56.000Z",
  "experiencedAt": "2026-10-17T00:00:00.000Z",
  "updatedAt": null,
  "isVerified": false,
  "companyReply": {
    "text": "Thank you for your review. We have sent you a request so that you can provide more information ...",
    "publishedAt": "2026-10-19T13:30:12.000Z",
    "updatedAt": null
  },
  "partial": false,
  "collectedAt": "2026-10-23T16:39:11.000Z"
}
```

One business row (`recordType: "business"`, free):

```json
{
  "recordType": "business",
  "businessId": "47783f3e0000640005020bb9",
  "name": "Bol",
  "domain": "www.bol.com",
  "url": "https://www.trustpilot.com/review/www.bol.com",
  "trustScore": 2.6,
  "reviewCount": 48890,
  "categories": ["Software Company"],
  "country": "NL",
  "contact": { "phone": "030 - 310 4999", "city": "Utrecht", "country": "NL" },
  "reviewsAvailable": 43585,
  "reviewsReturned": 100,
  "partial": false,
  "statusText": "Collected 100 review(s) of 43585 matching."
}
```

Every business URL and domain also gets one free `input_status` row (`found`, `not_found`, `invalid_input` or `partial`), and the last row is the `RUN_SUMMARY`.

### What you get

| Row | Fields |
| --- | --- |
| `review` (charged) | `reviewId`, `reviewUrl`, `rating` (1-5), `title`, `text`, `language`, `country`, `publishedAt`, `experiencedAt`, `updatedAt`, `isVerified`, `source`, `likes`, `companyReply` (`text`, `publishedAt`, `updatedAt`, or `null`), `businessName`, `businessDomain`, `businessId`, `collectedAt` |
| `business` (free) | `name`, `domain`, `url`, `websiteUrl`, `trustScore`, `stars`, `reviewCount`, `reviewsLast12Months`, `categories`, `primaryCategory`, `country`, `isClaimed`, `isClosed`, `contact` (only what the business published), `reviewsAvailable` / `reviewsRequested` / `reviewsReturned` / `reviewsCharged`, `partial`, `partialReason`, `statusText` |
| `input_status` (free) | `input`, `inputType`, `outcome`, `businessDomain`, `partial`, `partialReason`, `statusText` |

A review is written and charged once per run, even when two inputs reach the same business.

### Input

| Field | Default | Meaning |
| --- | --- | --- |
| `businessUrls` | - | Trustpilot review pages, on any country site (`de.trustpilot.com`, `fr.trustpilot.com`, ...). |
| `domains` | - | Website domains such as `www.amazon.com` or `zalando.de`; Trustpilot's own redirect is followed. |
| `maxReviewsPerBusiness` | 100 | Newest first. `0` = business profile only. |
| `languages` | `all` | Language codes (`en`, `de`, `fr`, ...), one pass each. |
| `stars` | all | Any of `1`-`5`. |
| `maxUpstreamRequests` | derived | Hard ceiling on requests to Trustpilot; derived from the input when empty. |
| `proxyConfiguration` | Apify datacenter | Residential also works and uses more paid traffic. |

### Limits

- **200 reviews per filter.** Trustpilot shows a logged-out visitor 10 pages of 20 reviews for one combination of language and stars; page 11 asks for a login. This Actor never logs in. Above 200 reviews it collects one star rating at a time, so it reaches up to 1,000 reviews per language (200 per star). When more match than that, the business row says `partialReason: "login_wall"` - narrow `languages` or `stars` to reach others.
- **Language default.** On trustpilot.com, Trustpilot itself lists only English reviews; this Actor asks for every language unless you set `languages`.
- **Reviewer privacy.** The reviewer appears only as a country. Names, profile pictures and profile links are never collected. Review text and company replies are written as published.
- **A browser is used.** Trustpilot answers plain HTTP clients with a browser check, so each Trustpilot site is opened once in headless Chrome and the review pages are then read as the site's own JSON. Give a run 2 GB of memory: 1 GB works but is about half as fast.
- **Partial is never empty.** `partial: true` with a `partialReason` (`login_wall`, `upstream_request_cap`, `charge_limit_reached`, `blocked`, `upstream_error`, `not_collected`) means the result is incomplete, never that there is nothing to collect. A business with no matching review has `reviewsAvailable: 0` and `partial: false`.

# Actor input Schema

## `businessUrls` (type: `array`):

Trustpilot review pages, one per line, for example https://www.trustpilot.com/review/www.amazon.com. Any country site works (de.trustpilot.com, fr.trustpilot.com, ...). An entry that is not a Trustpilot review URL gets its own status row and is not charged.

## `domains` (type: `array`):

Website domains, one per line, for example www.amazon.com or zalando.de. Trustpilot's own redirect is followed (amazon.com -> www.amazon.com). A domain Trustpilot has no page for gets a not_found status row and is not charged.

## `maxReviewsPerBusiness` (type: `integer`):

Upper bound on the reviews collected for each business, newest first. 0 collects only the business profile. Trustpilot shows a logged-out visitor 200 reviews (10 pages) per filter; above 200 this Actor collects star rating by star rating, so up to 1,000 per language. Whatever lies beyond that needs a login, which this Actor never does - the business row then says partialReason "login_wall".

## `languages` (type: `array`):

Language codes to collect, for example en, de, fr - each gets its own pass. Leave empty (or "all") for reviews in every language. Note that trustpilot.com itself shows only English reviews unless told otherwise.

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

Only reviews with these star ratings, any of 1, 2, 3, 4, 5. Leave empty for all.

## `maxUpstreamRequests` (type: `integer`):

Hard ceiling on the requests this run sends to Trustpilot, browser page loads included. At the ceiling collection stops - what was not reached is written with partialReason "upstream_request_cap" and the run then ends normally. Leave empty and the Actor works a ceiling out from your input, so a run is never unbounded.

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

The proxy the browser reaches Trustpilot through. The default (Apify Proxy, datacenter) is the cheapest and is what this Actor is measured on; residential works too and costs more traffic.

## Actor input object example

```json
{
  "businessUrls": [
    "https://www.trustpilot.com/review/www.booking.com"
  ],
  "maxReviewsPerBusiness": 100,
  "languages": [
    "all"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "businessUrls": [
        "https://www.trustpilot.com/review/www.booking.com"
    ],
    "languages": [
        "all"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lanternlab318/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 = {
    "businessUrls": ["https://www.trustpilot.com/review/www.booking.com"],
    "languages": ["all"],
}

# Run the Actor and wait for it to finish
run = client.actor("lanternlab318/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 '{
  "businessUrls": [
    "https://www.trustpilot.com/review/www.booking.com"
  ],
  "languages": [
    "all"
  ]
}' |
apify call lanternlab318/trustpilot-reviews --silent --output-dataset

```

## MCP server setup

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