# Trustpilot All Reviews Scraper 💰$0.5+ · No Cap · AI Insights (`memo23/trustpilot-scraper-ppe`) Actor

\[From 💰$0.50/1K] Export every Trustpilot review — past the ~200-review web cap. Incremental mode: pull only reviews newer than a date, so daily syncs stay cheap. 40+ fields, company replies, ratings, reviewer country. Filter by star, language, date, verified. Brand search, regional domains.

- **URL**: https://apify.com/memo23/trustpilot-scraper-ppe.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Lead generation, Agents, MCP servers
- **Stats:** 2,541 total users, 825 monthly users, 99.9% runs succeeded, 41 bookmarks
- **User rating**: 4.80 out of 5 stars

## Pricing

from $0.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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

## Trustpilot Reviews Scraper — AI Review Intelligence, No 200-Review Limit

Scrape **every** review from any Trustpilot company, brand search, or reviewer profile — past Trustpilot's ~200-review web cap — and turn them into product intelligence in the same run. You get ratings, full review text, company replies, reviewer country and verification, dates, and **40+ flattened fields**, with server-side filters for star, language, date, verified-only and replies-only. Export JSON, CSV, or Excel.

**What sets this scraper apart**

- 🧠 **AI pain-point analysis** — one AI pass clusters every complaint into ranked themes with severity and recurrence, then surfaces the missing features users keep asking for. Reviews in, "what to fix and build next" out. No other Trustpilot actor on the Store does this.
- 🔓 **No 200-review limit** — an iOS mobile-gateway pipeline pulls the full review history where the web stops at ~200.
- 🌍 **Regional domain sweep** — one input captures `nike.com` + `.de` + `.uk` + every regional sibling.
- 🔎 **Brand-name search** — paste `nike`, no URL needed; autosuggest resolves it.
- 📊 **Authoritative company data** — the real `basicLinkRate` from the transparency page, plus consumer-alert and incentivised-review flags.
- ⭐ **Live and battle-tested since 2024** — 4.9/5 from paying users, pure HTTP, no headless browser.

> **Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Trustpilot A/S or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.

### 🧠 AI Pain-Point Analysis — reviews → product intel

Flip on **`painPointAnalysis`** and the actor doesn't just hand you reviews — it hands you the **answer to "what should we fix and build next"**. After scraping, one AI pass per company clusters every complaint into ranked themes and pulls out the missing features users keep begging for:

> *Amazon, 50 reviews →* **Delivery delays / missed Prime promises** (severity 5, 54% of reviews) · **Unresponsive customer support** (severity 5, 42%) · missing: *real-time delivery tracking, multi-channel support* · quick win: *auto-credit for Prime failures*.

One `painPointAnalysis` row per company, straight from real reviews — no prompts, no second tool. Paid plans only, billed per company analyzed. [See the full output →](#ai-pain-point-analysis)

### Overview

This scraper extracts reviews from Trustpilot.com for any business, domain, search term, or user profile. You get detailed review records including text, rating, verification metadata, consumer info, company replies, and optional company-level data (alerts, BasicLink rate, transparency stats). Designed for sentiment analysis, competitive monitoring, fraud-detection workflows, and brand reputation tracking.

### What's new

- **🧠 AI pain-point analysis** (`painPointAnalysis: true`, paid plans) — one AI report per company: ranked complaint themes with severity + recurrence, missing features, quick wins, sentiment. See [AI pain-point analysis](#ai-pain-point-analysis).
- **Trustpilot `/search?query=…` URLs are now accepted as start URLs** — paste the URL directly from Trustpilot's own search bar and the actor extracts the query and resolves it via autosuggest.
- **Authoritative `basicLinkRate` opt-in** (`includeCompanyAdditionalFields: true`). The exact percentage Trustpilot shows on the transparency page, not a sample-derived approximation. See [Optional company enrichment](#optional-company-enrichment) below.
- **`consumerAlert` / `hasCollectedIncentivisedReviews` flags** in the `company` block (also gated on `includeCompanyAdditionalFields`).
- **Brand-name search** via the `searchTerms` input — pass `["nike", "adidas"]` instead of URLs.
- **Regional domain expansion** — set `expandRegionalDomains: true` and the actor sweeps every regional sibling (`nike.com`, `nike.uk`, `nike.de`, …) under one input.
- **Country-targeted reviewer filter** — keep only reviews from specific reviewer countries via `filterCountries: ["US", "GB"]`.
- **Multi-axis filters** — star ratings, languages, date range, verified-only, replies-only — all applied server-side at the gateway where possible.
- **Mobile JWT rotation flow** — paste a fresh Bearer JWT via `mobileBearerToken` if the bundled one expires (see [Token rotation](#token-rotation)).

### Why use this scraper (vs other Apify Trustpilot actors)

This scraper has been live and battle-tested since 2024. Here's how it stacks up against newer entrants:

| Capability | This actor | Typical alternative |
|---|---|---|
| ★ rating | **4.9 / 5** (with paying-user reviews) | 0.0 (no reviews yet) |
| Output fields per review | **40+** (incl. flattened CSV columns) | ~30 |
| Mobile-gateway pipeline (iOS app endpoints) | **Yes** — bypasses 200-review web limit | Limited to web's 200-per-stream cap |
| Brand-name search (no URL needed) | **Yes** — autosuggest + autoresolve | URL only |
| Regional domain expansion (nike.com + .de + .uk + …) | **Yes** — one input → all siblings | Manual per-URL |
| Authoritative `basicLinkRate` (transparency page) | **Yes** — AWS WAF SDK bypass | Sample-derived estimate |
| `consumerAlert` / `hasCollectedIncentivisedReviews` | **Yes** | No |
| Multi-language auto-sweep on huge BUs | **Yes** — won't truncate at >800 reviews | Single-stream only |
| Server-side filters (stars, language, date, verified, replies) | **All 5** | Some |
| JWT rotation flow (no code change to refresh token) | **Yes** — paste fresh token in input field | Re-deploy required |
| Trustpilot `/search?query=…` URLs accepted | **Yes** | Often rejected |
| User-profile reviews (`/users/{id}`) | **Yes** | Often missing |

**Depth, measured.** "Only gives back the first page" is the most common complaint filed against other Trustpilot actors on this Store. Re-checked 2026-08-24 against a live business unit: a 60-review request returned 60 rows, all 60 unique, against a web page size of 20. Pagination is not a first-page sample here, and the requested count is honoured exactly rather than rounded to a page boundary.

> **Why the price premium?** Cheaper alternatives skip the iOS mobile pipeline, the AWS WAF transparency-page bypass, and the regional expansion — so you trade $0.50/1k savings for losing reviews past the 200 cap, missing `basicLinkRate`, and having to manually enumerate every regional sibling. If you're scraping a tiny BU with <200 reviews and don't need company-level enrichment, save the money. If you're doing competitive monitoring, fraud detection, or anything multi-region — the extra fields pay back the price difference immediately.

### Features

- **Three input formats — all accepted in the same `startUrls` list:**
  - Business review page: `https://www.trustpilot.com/review/example.com`
  - User profile: `https://www.trustpilot.com/users/53d12345000064000180b423`
  - Search URL: `https://www.trustpilot.com/search?query=Cialis` *(extracts the query and resolves via autosuggest)*
  - …plus bare slugs (`bankfive`) and plain domains (`example.com`).
- **Or use the `searchTerms` field** to look up brands by name without typing URLs (`["nike", "noom", "marcovasco"]`).
- **Optional company enrichment**:
  - `includeCompanyDetails: true` adds a `company` block (display name, identifying domain, categories, trust score, …)
  - `includeStats: true` adds star distribution + total count
  - `includeTransparency: true` adds collecting-method distribution, reply behavior, monthly trends
  - `includeCompanyAdditionalFields: true` adds `consumerAlert`, `consumerAlerts`, `hasCollectedIncentivisedReviews`, and the **authoritative `basicLinkRate`** (sourced from Trustpilot's transparency page; falls back to a sample-derived approximation when the BU's data isn't reachable, with `basicLinkRateSource: "trustpilot" | "derived"` distinguishing the two)
- **Filters** (all optional, composable):
  - `filterStars: ["1", "2"]` — keep only those star ratings *(gateway server-side)*
  - `filterLanguages: ["en", "de"]` — restrict to specific languages *(gateway server-side)*
  - `filterDateRange: "last30days" | "last3months" | "last6months" | "last12months" | "all"` *(gateway server-side)*
  - `filterCountries: ["US", "GB"]` — keep only reviews from these reviewer countries *(client-side, since the gateway has no country param)*
  - `filterVerifiedOnly: true`, `filterRepliesOnly: true` *(both gateway server-side)*
  - `startDate: "YYYY-MM-DD"` — exact chronological cutoff
- **Regional expansion** (`expandRegionalDomains: true`, default) — when scraping a brand like `nike`, also pull from regional siblings (`nike.de`, `nike.uk`, …) under one shared `maxItems` budget.
- **Smart language coverage** — multi-language sweep automatically fires on huge BUs (>800 reviews) so the gateway's per-stream cap doesn't truncate non-English reviews.
- **Locale-aware default language** — when `scrapeAllReviews: false`, the actor derives the language from the BU's country (`bancamediolanum.it` → `it`, `darty.fr` → `fr`) so non-English BUs return their locale-native reviews by default.
- **Output parity** with the major Trustpilot scrapers on the Apify Store — same field names, types, and CSV-friendly flattened columns (`reviewerName`, `businessUrl`, `scrapedAt`, …) plus 5+ exclusive fields.
- **Limits**: `maxItems` per input (not global), with budget shared across regional siblings.
- **Proxies**: full proxy configuration support. Residential strongly recommended for high-volume runs; required for the WAF-protected `basicLinkRate` enrichment (which uses Evomi sticky sessions).

### How to Use

1. **Set Up**: Apify account, access to the actor.
2. **Pick your input style** — any of the following are accepted in the same run, even mixed together:
   - Business review URL: `https://www.trustpilot.com/review/example.com`
   - User profile URL: `https://www.trustpilot.com/users/53d12345000064000180b423`
   - **Trustpilot search URL**: `https://www.trustpilot.com/search?query=Cialis` *(new — the query is extracted and resolved through autosuggest)*
   - Just the domain: `example.com` (with or without `https://`)
   - Bare slug: `bankfive` (resolved via autosuggest)
   - Or use the **`searchTerms`** field to list brand names directly: `["nike", "noom"]`
3. **Apply filters as needed**:
   - Star ratings (`filterStars`), languages (`filterLanguages`), reviewer countries (`filterCountries`)
   - Rolling date window (`filterDateRange`) or hard chronological cutoff (`startDate`)
   - Verified-only / replies-only toggles
4. **Pick your enrichment level**:
   - `includeCompanyDetails: true` for business info
   - `includeStats: true` for star distribution
   - `includeTransparency: true` for collecting-method + reply-behavior stats
   - `includeCompanyAdditionalFields: true` for `consumerAlert` + `hasCollectedIncentivisedReviews` + authoritative `basicLinkRate` *(see [Optional company enrichment](#optional-company-enrichment))*
5. **Run the Scraper**: monitor progress in the Apify console.
6. **Data Collection**: extracted data available as JSON, CSV, Excel, or via the dataset API.

### Input Data

Five common input shapes — pick whichever fits your workflow:

#### A. Mixed URLs (single batch)

```json
{
    "startUrls": [
        { "url": "https://www.trustpilot.com/review/navimow.segway.com" },
        { "url": "https://www.trustpilot.com/users/53d12345000064000180b423" },
        { "url": "https://www.trustpilot.com/search?query=Nike" },
        { "url": "noom.com" }
    ],
    "maxItems": 200,
    "includeCompanyDetails": true,
    "includeStats": true
}
```

#### B. Brand search by name (no URLs needed)

```json
{
    "searchTerms": ["nike", "adidas", "puma"],
    "filterCountries": ["US"],
    "filterStars": ["1", "2"],
    "maxItems": 100,
    "includeCompanyDetails": true
}
```

#### C. Negative-review monitoring (last 30 days, 1-2★ only)

```json
{
    "startUrls": [{ "url": "https://www.trustpilot.com/review/yourbusiness.com" }],
    "filterStars": ["1", "2"],
    "filterDateRange": "last30days",
    "sortBy": "recent",
    "maxItems": 1000
}
```

#### D. Full company snapshot with authoritative `basicLinkRate`

```json
{
    "startUrls": [{ "url": "https://www.trustpilot.com/review/bancamediolanum.it" }],
    "includeCompanyDetails": true,
    "includeCompanyAdditionalFields": true,
    "includeStats": true,
    "includeTransparency": true,
    "maxItems": 50
}
```

#### E. Regional brand expansion

```json
{
    "searchTerms": ["nike"],
    "expandRegionalDomains": true,
    "maxItems": 5000
}
```

#### Input Fields Explanation

**Input sources**

- `startUrls` (array): Each entry can be a Trustpilot `/review/`, `/users/`, or `/search?query=…` URL, a bare slug (`bankfive`), or a domain (`noom.com`). Localized hosts (`fr.trustpilot.com`, …) auto-normalize to `www.trustpilot.com`.
- `searchTerms` (array): Brand names to resolve via autosuggest. Composable with `startUrls`.

**Scope & filters**

- `scrapeAllReviews` (boolean, default `true`): When `true`, force `language=all` for maximum coverage. When `false`, derive language from the BU's country code (Italian BU → Italian reviews) so non-English BUs return locale-native content. Overridden by an explicit `filterLanguages`.
- `filterStars` (array of `"1"`-`"5"`): Server-side star filter.
- `filterLanguages` (array of ISO 639-1 codes): `["en", "de"]`. Server-side.
- `filterCountries` (array of ISO 3166-1 alpha-2): `["US", "GB"]`. Reviewer-country, client-side.
- `filterDateRange` (`"all" | "last30days" | "last3months" | "last6months" | "last12months"`): Server-side rolling window.
- `filterVerifiedOnly` (boolean): Server-side.
- `filterRepliesOnly` (boolean): Server-side.
- `sortBy` (`"auto" | "relevancy" | "recent"`): `"auto"` picks recent when `startDate` is set, relevancy otherwise.
- `startDate` (`YYYY-MM-DD`): Hard chronological cutoff. Pagination short-circuits as soon as it crosses this date.
- `expandRegionalDomains` (boolean, default `true`): Auto-fetch regional siblings of each brand.

**Enrichment**

- `includeCompanyDetails` (boolean): Add a `company` block to every review record.
- `includeStats` (boolean): Add `stats` block (star distribution + total).
- `includeTransparency` (boolean): Add `transparency` block (collecting-method distribution, reply-behavior, monthly trends).
- `includeCompanyAdditionalFields` (boolean): Add `consumerAlert`, `consumerAlerts`, `hasCollectedIncentivisedReviews`, and authoritative `basicLinkRate` to the `company` block. See [Optional company enrichment](#optional-company-enrichment).
- `painPointAnalysis` (boolean, **paid plans only, billed per company**): After scraping, an AI pass over each company's reviews adds one `painPointAnalysis` row per company — clustered complaint themes with severity + recurrence, missing features users ask for, quick wins, and overall sentiment. The "what should we fix / build" teardown, straight from the reviews (uses up to 200 reviews per company). See [AI pain-point analysis](#ai-pain-point-analysis).

**Limits & performance**

- `maxItems` (integer): Per-input cap. Shared budget across regional siblings.
- `maxConcurrency` (integer, default 10): Max parallel inputs.
- `minConcurrency` (integer, default 1): Minimum parallelism.
- `maxRequestRetries` (integer, default 100): Retry budget for failed mobile-gateway requests.

**Mobile gateway auth** (advanced — only set if the bundled token expires)

- `mobileBearerToken` (string): Override the bundled Bearer JWT. See [Token rotation](#token-rotation).
- `mobileApiKey` (string): Override the bundled `apikey` header.
- `mobileBearerAllRequests` (boolean, default `false`): Attach Bearer on every request instead of just page 1.

### AI pain-point analysis

With **`painPointAnalysis: true`** (paid plans only), after the reviews are scraped the actor runs one AI pass per company and appends a `painPointAnalysis` row — the recurring complaints clustered into themes, the features users keep asking for, and quick wins. It reads up to 200 reviews per company and is billed per company analyzed.

```jsonc
{
  "rowType": "painPointAnalysis",
  "company": "videotron.com",
  "reviewsAnalyzed": 200,
  "topThemes": [
    { "theme": "Billing issues and unauthorized charges", "severity": 5, "mentionSharePct": 30,
      "exampleQuotes": ["charged twice and no one could explain why"] },
    { "theme": "Frequent internet outages", "severity": 5, "mentionSharePct": 25, "exampleQuotes": ["down again for the third time this month"] }
  ],
  "missingFeatures": ["Real-time outage notifications", "Loyalty rewards for long-term customers"],
  "quickWins": ["Faster first-response on support tickets"],
  "overallSentiment": "negative",
  "summary": "Systemic issues across service reliability, billing transparency and support consistency drive most 1-star reviews.",
  "generatedAt": "2026-07-08T21:00:00.000Z"
}
```

### Output Structure

The output data includes detailed information about each review. Here's a sample of the structure:

```json
{
    "id": "671d4064ff600a8a63bcea11",
    "filtered": false,
    "pending": false,
    "text": "The manager was awesome in helping my brother & me in the loss of our younger brother regarding his accounts. DuGood also came through & helped us with another issue when no one else would. We truly appreciate your knowledge & caring toward your customers. It did not go unnoticed & you now have several family members who are new customers because of it. Thank you again!",
    "rating": 5,
    "labels": {
        "merged": null,
        "verification": {
            "isVerified": true,
            "createdDateTime": "2024-10-26T21:17:56.000Z",
            "reviewSourceName": "AFSv2",
            "verificationSource": "invitation",
            "verificationLevel": "verified",
            "hasDachExclusion": false
        }
    },
    "title": "The manager was awesome in helping my…",
    "likes": 8,
    "dates": {
        "experiencedDate": "2024-10-23T00:00:00.000Z",
        "publishedDate": "2024-10-26T21:17:56.000Z",
        "updatedDate": null
    },
    "report": null,
    "hasUnhandledReports": false,
    "consumer": {
        "id": "671d4063422e94eeb1028118",
        "displayName": "Cheryl",
        "imageUrl": "",
        "numberOfReviews": 1,
        "countryCode": "US",
        "hasImage": false,
        "isVerified": false
    },
    "reply": {
        "text": "Hi Cheryl,\n\nIt's heartwarming to hear about the support you received during such a difficult time. We are dedicated to our members and we're glad we could help you and your family. Thank you for sharing your touching experience with us.",
        "publishedDate": "2024-10-30T17:25:46.000Z",
        "updatedDate": null
    },
    "consumersReviewCountOnSameDomain": 1,
    "consumersReviewCountOnSameLocation": null,
    "productReviews": [],
    "language": "en",
    "location": null,
    "source": "AFSv2",
    "isVerified": true,
    "verificationLevel": "verified",
    "publishedDate": "2024-10-26T21:17:56.000Z",
    "experiencedDate": "2024-10-23T00:00:00.000Z",
    "updatedDate": null,
    "reviewerName": "Cheryl",
    "reviewerCountry": "US",
    "reviewerNumberOfReviews": 1,
    "url": "https://www.trustpilot.com/reviews/671d4064ff600a8a63bcea11",
    "businessUrl": "https://www.trustpilot.com/review/www.dugood.org",
    "businessName": "DuGood Credit Union",
    "scrapedAt": "2026-05-23T15:30:42.000Z"
}
```

#### Output Fields Explanation

**Core review fields**

- `id`: Unique identifier for the review.
- `filtered`: Boolean — `true` if Trustpilot has hidden the review (moderation).
- `isPending`: Boolean — `true` if the review is awaiting publication.
- `text`: Review content.
- `rating`: 1–5 stars.
- `title`: Short review title.
- `language`: ISO 639-1 language code (`"en"`, `"de"`, …).
- `source`: Review source channel (`"BasicLink"`, `"InvitationApi"`, `"Organic"`, `"BusinessGeneratedLink"`, …).
- `likes` / `numberOfLikes`: Helpful-vote count.

**Dates** (also duplicated at top level for CSV-friendly flat columns)

- `dates.publishedDate`, `dates.experiencedDate`, `dates.updatedDate`, `dates.submittedDate`
- Top-level: `publishedDate`, `experiencedDate`, `updatedDate`

**Verification & labels**

- `isVerified` (top-level): authoritative — `true` when the review is verified.
- `verificationLevel`: `"verified"`, `"invited"`, `"organic"`, `"not-verified"`, …
- `labels.verification.*`: raw verification block (createdDateTime, reviewSourceName, verificationSource, verificationLevel, hasDachExclusion).
- `labels.merged`: merge metadata (usually `null`).

**Consumer / reviewer** (nested + flattened)

- `consumer.{id, displayName, imageUrl, numberOfReviews, countryCode, hasImage, isVerified, verified}`
- Top-level flattened: `reviewerName`, `reviewerCountry`, `reviewerNumberOfReviews`

**Business reply** (when present)

- `reply.{text, publishedDate, updatedDate}` — also aliased as `companyReply` for legacy consumers.

**Reports & moderation**

- `report`: Report metadata if any (usually `null`).
- `hasUnhandledReports`: Boolean.

**Volume signals**

- `consumersReviewCountOnSameDomain`: How many other reviews this user left for this BU.
- `consumersReviewCountOnSameLocation`: Same scoped to BU location.

**Product / location**

- `productReviews`: Linked product reviews (usually `[]`).
- `location`: Physical-location info (usually `null`).

**Convenience links**

- `url`: Direct link to the review page on Trustpilot.
- `businessUrl`: Link to the BU's review page.
- `businessName`: BU display name.
- `scrapedAt`: ISO timestamp when this record was emitted by the actor.

#### Company Details Output (If `includeCompanyDetails` is set to true)

```json
"company": {
    "id": "592855190000ff0005a33f85",
    "displayName": "DuGood Credit Union",
    "identifyingName": "www.dugood.org",
    "numberOfReviews": 4105,
    "trustScore": 4.8,
    "websiteUrl": "https://www.dugood.org/",
    "websiteTitle": "www.dugood.org",
    "profileImageUrl": "//s3-eu-west-1.amazonaws.com/tpd/logos/592855190000ff0005a33f85/0x0.png",
    "customHeaderUrl": "",
    "promotion": null,
    "hideCompetitorModule": false,
    "stars": 5,
    "categories": [
        {
            "id": "federal_credit_union",
            "name": "Federal Credit Union",
            "rank": "1",
            "cardinality": "3",
            "isPrimary": false
        },
        {
            "id": "credit_union",
            "name": "Credit Union",
            "rank": "1",
            "cardinality": "7",
            "isPrimary": true
        }
    ],
    "breadcrumb": {
        "topLevelId": "money_insurance",
        "topLevelDisplayName": "Money & Insurance",
        "midLevelId": "credit_debt_services",
        "midLevelDisplayName": "Credit & Debt Services",
        "bottomLevelId": "credit_union",
        "bottomLevelDisplayName": "Credit Union"
    },
    "isClaimed": true,
    "isClosed": false,
    "isTemporarilyClosed": false,
    "locationsCount": 0,
    "isCollectingReviews": true,
    "verification": {
        "verifiedByGoogle": true,
        "verifiedBusiness": true,
        "verifiedPaymentMethod": true,
        "verifiedUserIdentity": false
    },
    "contactInfo": {
        "email": "marketing@dugood.org",
        "address": "7505 Eastex Frwy",
        "city": "Beaumont",
        "country": "US",
        "phone": "(409) 899-3430",
        "zipCode": "77708"
    }
}
```

#### Company Fields Explanation

- `id`: Unique identifier for the company.
- `displayName`: Display name of the company.
- `identifyingName`: The identifying name of the company, typically the website URL.
- `numberOfReviews`: Total number of reviews for the company.
- `trustScore`: Trust score of the company on Trustpilot.
- `websiteUrl`: Official website URL of the company.
- `websiteTitle`: Title of the company’s website.
- `profileImageUrl`: URL of the company’s profile image.
- `customHeaderUrl`: URL for any custom header image (if applicable).
- `categories`: Array of categories the company belongs to, including rank and primary status.
- `breadcrumb`: Hierarchical classification of the company's industry or sector.
- `isClaimed`: Boolean indicating if the company profile is claimed on Trustpilot.
- `verification`: Object containing verification details about the company.
  - `verifiedByGoogle`, `verifiedBusiness`, `verifiedPaymentMethod`: Various verification types.
- `contactInfo`: Contact details of the company, including email, address, city, country, phone, and zip code.

#### Statistics Output (If `includeStats` is set to true)

```json
"stats": {
    "total": 4105,
    "one": 43,
    "two": 15,
    "three": 46,
    "four": 168,
    "five": 3833,
    "totalNumberOfReviews": 3450
}
```

#### Statistics Fields Explanation

- `total`: Total number of reviews collected.
- `one`: Number of 1-star reviews.
- `two`: Number of 2-star reviews.
- `three`: Number of 3-star reviews.
- `four`: Number of 4-star reviews.
- `five`: Number of 5-star reviews.
- `totalNumberOfReviews`: Total number of reviews that were actually processed.

### Optional company enrichment

When you set `includeCompanyDetails: true` **and** `includeCompanyAdditionalFields: true`, each review's `company` block gains four extra fields:

```json
"company": {
    "displayName": "Banca Mediolanum",
    "countryCode": "IT",
    "consumerAlert": null,
    "consumerAlerts": [],
    "hasCollectedIncentivisedReviews": false,
    "activity": {
        "basiclinkRate": 72,
        "basiclinkRateSource": "trustpilot"
    }
}
```

- `consumerAlert` / `consumerAlerts`: Trustpilot's "suspicious activity" alerts (null/empty when a BU has none).
- `hasCollectedIncentivisedReviews`: `true` if the BU has historically collected reviews via incentives.
- `activity.basiclinkRate`: percentage of the BU's reviews that came in via the BasicLink channel.
- `activity.basiclinkRateSource`:
  - `"trustpilot"` — authoritative value from Trustpilot's own transparency surface.
  - `"derived"` — local approximation computed from the scraped review sample (used when the transparency page can't be reached).

#### How it works (and why it costs a bit more)

`basicLinkRate` only lives on Trustpilot's transparency page, which is behind an AWS WAF SDK-mode challenge from datacenter IPs. The actor bundles a NetworkBandwidth-challenge solver that runs through an Evomi sticky-session residential proxy to fetch the page once per business unit. Adds ~3-5 seconds + one residential proxy connection per **unique** BU (cached for the rest of the run). Free users without an Evomi proxy gracefully fall back to the derived value.

The flag is opt-in. Leave it off if you don't need this field; the rest of the actor's behavior is unchanged.

### Token rotation

The actor bundles a Trustpilot iOS Bearer JWT used to authenticate against the mobile gateway. The token has a fixed expiry — once it lapses, every mobile API call returns 401 and the actor stops working. Token rotation is the actor maintainer's responsibility, not yours; you should normally never need to touch it.

The runtime log at the start of every run shows how much runway the bundled token has:

```
[mobile-api] ⚠️  Bearer JWT expires in N days (on YYYY-MM-DDTHH:MM:SS.000Z).
              Plan to rotate via the `mobileBearerToken` input or `TRUSTPILOT_BEARER_TOKEN` env var
              before then to avoid 401s.
```

If the bundled token is already past expiry, the run's dashboard status will show:

> ⚠️ Mobile gateway Bearer JWT expired on … — Set `mobileBearerToken` to fix.

In the unlikely event the dashboard ever shows that EXPIRED banner before the maintainer has rotated the bundled token, you can self-recover by pasting a fresh token into the `mobileBearerToken` input field (see below). Otherwise contact support — most rotations happen before the bundled token expires.

**To self-rotate** (advanced): capture a fresh `Authorization: Bearer …` header value from any Trustpilot iOS-app request to `consumermobile-apigateway.trustpilot.com` (using mitmproxy, Charles, or any HTTPS-inspecting iOS debugger), strip the `Bearer ` prefix, and paste it into the **`mobileBearerToken`** input field. No code changes required.

### Usage Tips

1. For bulk scraping, use the "Bulk edit" feature to input multiple profile URLs or usernames.
2. Adjust concurrency settings based on your network capabilities and Trustpilot's rate limits.
3. Use proxy configuration for large-scale scraping to avoid IP blocks. Residential is recommended; required if you enable `includeCompanyAdditionalFields`.
4. To monitor a single brand for negative reviews, combine `filterStars: ["1", "2"]` + `filterDateRange: "last30days"` + `sortBy: "recent"`.
5. For competitive analysis across multiple brands, use `searchTerms` rather than hunting down each `/review/` URL.
6. If `basicLinkRateSource` is `"derived"` in your output, the actor couldn't reach the transparency page for that BU — either enable a residential proxy (Evomi recommended) or accept the sample-based approximation.

### Explore More Scrapers

Scraping reviews across platforms? You may also need our other **review-site scrapers** — same quality, same author, same export format:

- **G2** — software reviews, ratings, products, vendor & competitor data: [G2 Scraper](https://apify.com/memo23/g2-scraper)
- **Capterra** — software reviews & product profiles: [Capterra Scraper](https://apify.com/memo23/capterra-scraper)
- **Gartner Peer Insights** — enterprise software reviews: [Gartner Scraper](https://apify.com/memo23/apify-gartner-scraper-ppr)
- **Yelp** — local business reviews, ratings & details: [Yelp Scraper](https://apify.com/memo23/yelp-scraper)

Plus jobs & real-estate scrapers (Naukri, Idealista, LinkedIn, Y Combinator, and more) at [memo23's Apify profile](https://apify.com/memo23).

### Support

- For issues or feature requests, please use the [Issues](https://console.apify.com/actors/HYuOke00wY4emLHz1/issues) section of this actor.
- If you need customization or have questions, feel free to contact the author:
  - Author's website: <https://muhamed-didovic.github.io/>
  - Email: <muhamed.didovic@gmail.com>

### Additional Services

- Request customization or whole dataset: <muhamed.didovic@gmail.com>
- If you need anything else scraped, or this actor customized, email: <muhamed.didovic@gmail.com>
- For API services of this scraper (no Apify fee, just usage fee for the API), contact: <muhamed.didovic@gmail.com>
- Email: muhamed.didovic@gmail.com

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/trustpilot-scraper-ppe`).

**Purpose:** Scrapes Trustpilot.com reviews for any business, brand name, or user profile — one dataset row per review — via Trustpilot's mobile gateway, which returns reviews past the 200-review web limit.

**Minimal input:**

```json
{
  "startUrls": ["https://www.trustpilot.com/review/apify.com"],
  "maxItems": 50
}
```

Search mode (no URL needed): `{ "searchTerms": ["nike"], "maxItems": 50 }` — `startUrls` and `searchTerms` can be combined; every URL and term is processed independently.

**Output:** one row per review — id, title, text, rating, language, source, isVerified, verificationLevel, publishedDate, experiencedDate, updatedDate, likes, reply {text, publishedDate, updatedDate}, consumer {id, displayName, countryCode, numberOfReviews}, reviewerName, reviewerCountry, reviewerNumberOfReviews, url, businessUrl, businessName, scrapedAt — plus opt-in company, stats, and transparency blocks.

**Behaviors an agent should know:**

- Always set `maxItems` — it is a per-input cap (default 10000), and the budget is shared across regional siblings when `expandRegionalDomains` is on (default `true`; set it `false` to scrape only the exact domain you passed).
- `startUrls` accepts `/review/`, `/users/`, and `/search?query=` URLs, bare slugs (`bankfive`), and plain domains (`noom.com`); locale hosts normalize to `www.trustpilot.com`, so use `filterLanguages` to restrict language.
- `filterStars`, `filterLanguages`, `filterDateRange`, `filterVerifiedOnly`, and `filterRepliesOnly` are applied server-side; `filterCountries` is applied client-side after fetch.
- Enrichment is opt-in: `includeCompanyDetails`, `includeStats`, `includeTransparency`; `includeCompanyAdditionalFields` only takes effect when `includeCompanyDetails` is also enabled.
- Inputs that return zero reviews are reported in a side dataset `inputStatus-<runId>` (toggle `emitInputStatus`, default on), which is never billed.
- Pay-per-event billing — see the Pricing tab on the actor page. `reviewInsights` and `painPointAnalysis` are each billed per company analyzed; `painPointAnalysis` requires a paid Apify plan.

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Trustpilot A/S or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available Trustpilot review, company, and reviewer-profile pages — it does not bypass authentication, does not use private or paid endpoints, and does not reach content behind the Trustpilot login wall. Users are responsible for ensuring their use complies with Trustpilot's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.

### SEO Keywords

trustpilot scraper, trustpilot reviews scraper, trustpilot api, trustpilot reviews export, trustpilot data extractor, scrape trustpilot reviews, trustpilot company data, trustpilot business reviews, trustpilot review aggregator, trustpilot competitor analysis, brand reputation monitoring, online review monitoring, sentiment analysis trustpilot, trustpilot user profile scraper, trustpilot fraud detection, basiclink rate trustpilot, trustpilot transparency data, trustpilot mobile api, trustpilot ios scraper, trustpilot regional domains, multi-language trustpilot scraper, trustpilot star rating filter, trustpilot verified reviews, trustpilot consumer alerts, trustpilot incentivised reviews, trustpilot jwt rotation, trustpilot json export, trustpilot csv export, e-commerce review intelligence, brand reputation tool, online reputation management, trustpilot scraper apify, customer review insights, review platform scraper, business intelligence reviews, marketing research tool, competitor intelligence reviews

***

### 🤖 Related MCP servers for AI agents

Building an AI agent, or using Claude, Cursor or ChatGPT? Skip the scraping setup — connect our hosted **MCP servers** (no API keys, billed per call):

- **[Reviews MCP Server](https://apify.com/memo23/reviews-mcp-server)** — search companies, read real Trustpilot review texts, and pull multi‑platform ratings (Trustpilot + App Store + Google Play) straight from your assistant.
- **[Reddit MCP Server](https://apify.com/memo23/reddit-mcp-server)** — search Reddit, browse subreddits, read comment threads.
- **[Email Finder & Verifier MCP](https://apify.com/memo23/email-mcp-server)** — find and verify company emails.
- **[Video Transcripts MCP](https://apify.com/memo23/transcripts-mcp-server)** — full YouTube & TikTok transcripts.

# Actor input Schema

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

Enter one item per row. Each value can be a Trustpilot `/review/` or `/users/` URL, a Trustpilot `/search?query=…` URL (the query is extracted and resolved via autosuggest, same as the Search filters field), a company URL, or a bare slug such as `bankfive`. Wrong `/review/` slugs trigger a Trustpilot search fallback. **Note on locale subdomains:** localized hosts (e.g. `fr.trustpilot.com`, `it.trustpilot.com`) are normalized to `www.trustpilot.com` so you don't accidentally miss reviews — Trustpilot's main `.com` page is multilingual and contains every review the locale subdomains do, plus more. If you want reviews in one specific language, use the **Languages to include** filter (`filterLanguages`) instead; submitting a locale subdomain alone won't restrict by language.

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

One brand name per row, e.g. `nike`, `noom`, `marcovasco`. The scraper resolves each to its canonical business unit and (when 'Expand regional domains' is on) also sweeps every regional sibling on Trustpilot's index.

## `reviewInsights` (type: `boolean`):

Adds one `review_insights` row per company: rating breakdown & sentiment split, the recurring consumer complaint themes (delivery, refunds, support, billing, trust…), top negative-review terms, and request snippets. Deterministic — instant, no AI credits or keys required. Billed per company analyzed.

## `painPointAnalysis` (type: `boolean`):

Adds a single `painPointAnalysis` row per company alongside the reviews: the top complaint themes (each with a severity score and how often it recurs), the missing features users keep asking for, quick wins, overall sentiment, and a short summary — the 'what should we fix / build next' teardown, straight from real reviews. Analyzes up to 200 reviews per company. Requires a paid Apify plan; billed per company analyzed.

## `enrichEmails` (type: `boolean`):

If enabled, finds a contact email for each result from its own website (or by discovering it from the name). Adds contactEmail + contactWebsite columns plus a detailed emailEnrichment object. Best-effort.

## `qualifyByPayment` (type: `boolean`):

Requires "Enrich with contact emails". Scans each business's website — reusing the pages already fetched for email discovery, so no extra cost or time — for payment processors and e-commerce platforms (Stripe, Shopify, PayPal, Paddle, Lemon Squeezy, WooCommerce, Square, Chargebee and more). Adds takesPayments (is this a real paying business?), paymentProcessors (which stack), stripeLiveKey (the public key if exposed) and paymentConfidence. Turn raw contacts into monetization-qualified leads. No extra charge — included with each enriched company.

## `scrapeAllReviews` (type: `boolean`):

Controls the language scope requested from Trustpilot. **Enabled (default)**: requests every language available on the BU — maximizes coverage but mixes locales (e.g. a `.com` URL returns Italian, French, German reviews alongside English). **Disabled**: the scraper derives a single language from the BU's country code (e.g. `bancamediolanum.it` → Italian, `darty.fr` → French, `nike.de` → German) so you get the locale-native slice — what a local visitor would see in their browser. If the BU's country doesn't have a known language mapping, no specific language is requested and Trustpilot returns its own default. The multi-language sweep that fires on huge BUs is also skipped when disabled. For a specific language regardless of BU country, use **Languages to include** below — an explicit filter overrides this setting.

## `filterStars` (type: `array`):

Limit reviews to specific star ratings. Leave empty to include all ratings (1–5).

## `sampling` (type: `string`):

Only matters when **Limit** is smaller than the brand's review count. **Balanced** (default) gives each star rating an equal share of the budget, so you see plenty of rare 1★ and 2★ reviews. **Representative** splits the budget to match the brand's actual rating mix — if a brand is 80% five-star, so is your sample. Choose Representative when you'll compute an average rating, a distribution, or any percentage from the results, because an even split would otherwise skew those numbers. Ignored when no limit binds (you get everything) or when you've set an explicit star filter.

## `filterLanguages` (type: `array`):

ISO 639-1 codes (e.g. `en`, `de`, `fr`, or `unknown` for reviews Trustpilot couldn't classify). Leave empty to auto-discover and sweep all languages found on each business unit. **This is the right knob to use if you want to restrict results to one language** — locale subdomains in start URLs (e.g. `it.trustpilot.com`) are intentionally normalized away to avoid silently losing reviews, so language filtering must be explicit here.

## `filterDateRange` (type: `string`):

Server-side rolling date window. Equivalent to Trustpilot's own 'Date posted' filter. Only these values are accepted; anything else is rejected. For an exact cutoff, use the 'Only scrape reviews newer than' field below — they compose (the more restrictive one wins).

## `filterVerifiedOnly` (type: `boolean`):

Equivalent to Trustpilot's own 'Verified reviews' toggle. Applied server-side, so non-verified reviews are filtered out before they reach you — no wasted requests. The canonical output's `isVerified` reflects truth (derived from `verificationLabel.type === 'verified'`; the raw response boolean is misleading).

## `filterRepliesOnly` (type: `boolean`):

Equivalent to Trustpilot's own 'Reviews with replies' toggle. Applied server-side, so reviews without replies are filtered out before they reach you.

## `filterCountries` (type: `array`):

ISO 3166-1 alpha-2 country codes to keep, e.g. `US`, `GB`, `DE`. Matched against the reviewer's profile country (`consumer.countryCode`). Leave empty to keep all countries. Trustpilot has no server-side country filter, so this is applied client-side — non-matching reviews still cost a request and the drop count is logged in the per-URL summary.

## `sortBy` (type: `string`):

How each review stream is ordered. `auto` uses `recent` (`createdAt:desc`), which pages to the end of a business's review history. `Most relevant` is capped by Trustpilot at 200 reviews per rating bucket, so pick it only when you specifically want their relevance ranking and are happy with a 200-item slice.

## `expandRegionalDomains` (type: `boolean`):

After resolving each input, also fetch every regional sibling on Trustpilot's index that matches the same brand (e.g. `nike` → `nike.com`, `nike.uk`, `nike.de`, `nike.dk`, …). Strict displayName matching keeps unrelated brands out. Shared `maxItems` budget across siblings.

## `strictNameMatch` (type: `boolean`):

When ON, reject autosuggest hits whose business name doesn't look like your query (e.g. `FACTORHY Avocats` → `Omega Avocats` is rejected because the only shared word is the generic `avocats`). Useful when you'd rather see `BU not found` than reviews from an adjacent-but-wrong company. When OFF (default), accept whatever Trustpilot's autosuggest returns — some data is better than none.

## `splitDatasets` (type: `boolean`):

When ON, reviews go to the default dataset (clean, one row per review, no embedded `company`/`stats`/`transparency`) and BU metadata goes to a per-run sibling dataset named `businessUnits-<runId>` (one row per unique BU). Each review carries a `businessUnitId` you can JOIN on. The exact dataset id is written to this run's `OUTPUT` record (`businessUnitsDatasetId`). Solves the 95%-duplicated-data problem on large runs (a 1,500-review BU sweep no longer repeats ~3 KB of metadata 1,500 times). When OFF (default), preserve the legacy embedded-per-row shape so existing pipelines don't break.

## `flattenCompanyData` (type: `boolean`):

When ON, each review gets flat top-level company columns — `companyName`, `companyDomain`, `companyWebsite`, `companyTrustScore`, `companyStars`, `companyTotalReviews`, `companyCountryCode`, `companyUrl` — instead of (or alongside) the nested `company` object. Ideal for CSV/Excel exports where nested objects flatten into awkward `company/score/trustScore` columns. Works even without `includeCompanyDetails` (these are derived from the business unit we already resolved, at no extra cost). When OFF (default), output shape is unchanged.

## `emitInputStatus` (type: `boolean`):

When ON (default), any input that returns no reviews (brand not found on Trustpilot, empty business unit, or everything excluded by your filters) gets one diagnostic row in a per-run dataset named `inputStatus-<runId>` — with a machine-readable `reason` and a human-readable `detail`. The exact dataset id is written to this run's `OUTPUT` record (`inputStatusDatasetId`). Lets you see exactly which of your inputs came back empty and why, instead of silently missing from the output. This is a side channel: it never adds rows to your reviews dataset and is never billed. Turn OFF to suppress.

## `lastDays` (type: `integer`):

Scrape only reviews published in the last N days — e.g. **7** for a weekly run, **1** for daily. The window is recalculated every run, so a scheduled task always picks up exactly what's new without you editing a date. Ideal for keeping a database in sync. Leave empty to ignore. If you also set an exact date below, whichever is more recent wins. Note this is cheap: the scraper stops paging as soon as it passes your cutoff, so a 7-day run costs the same on a huge brand as on a small one.

## `startDate` (type: `string`):

Format YYYY-MM-DD, e.g., 2022-02-20. Used as a hard chronological cutoff: when set, the scraper switches to `sort=createdAt:desc` and short-circuits pagination as soon as it crosses the date.

## `includeCompanyDetails` (type: `boolean`):

When enabled, each review item is enriched with the `company` block (display name, identifying domain, country, total review count, …).

## `includeStats` (type: `boolean`):

When enabled, each review item is enriched with the `stats` block (total review count, per-star rating distribution, …).

## `includeTransparency` (type: `boolean`):

When enabled, each review item is enriched with the `transparency` block (collecting method distribution, stars breakdown by method, monthly data, etc.).

## `includeCompanyAdditionalFields` (type: `boolean`):

On-demand enrichment. When enabled, each review's `company` block is augmented with `subscription` — Trustpilot's own published plan flags for that company (`isPayingCustomer`, `hasSubscription`, `isClaimed`, `claimedDate`, `isAskingForReviews`, `isUsingAIResponses` and more) — plus `consumerAlert`, `consumerAlerts`, `hasCollectedIncentivisedReviews`, and (when still exposed by Trustpilot) `basiclinkRate`. Every `subscription` flag is `true`, `false`, or `null` when the page did not state it, so an unavailable page is never reported as 'not a customer'. Costs one extra HTTP request per unique business unit. Has no effect unless 'Include company details in output' is also enabled.

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

Per-input cap. With 3 inputs and `maxItems=30`, you can collect up to 90 reviews total (30 per input). When 'Expand regional domains' is on, this budget is shared across the primary BU and all its regional siblings.

## `maxConcurrency` (type: `integer`):

Maximum number of inputs being processed in parallel (each input runs many sequential page fetches).

## `minConcurrency` (type: `integer`):

Minimum number of inputs that will be processed at the same time.

## `maxRequestRetries` (type: `integer`):

Number of times the scraper will retry a failed request before giving up.

## `proxy` (type: `object`):

Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies.

## Actor input object example

```json
{
  "startUrls": [
    "bankfive",
    "www.dugood.org",
    "https://www.trustpilot.com/users/5f3a1c9e8b2c4a0007d1e2f3",
    "https://fr.trustpilot.com/review/eminence.fr",
    "https://www.trustpilot.com/review/kindlewritinghub.com",
    "https://www.trustpilot.com/review/www.vans.com",
    "https://www.trustpilot.com/review/shop.missha-deutschland.de",
    "https://www.trustpilot.com/review/dior.co.uk",
    "https://www.trustpilot.com/review/www.barxparx.com",
    "https://www.trustpilot.com/review/oshalafarm.com",
    "https://www.trustpilot.com/review/www.nomador.com?sort=recency",
    "https://www.trustpilot.com/review/apify.com",
    "https://www.trustpilot.com/review/swiftpromining.org",
    "https://www.trustpilot.com/review/couplehoodies.com",
    "https://www.trustpilot.com/review/rosecjewels.com",
    "https://www.trustpilot.com/review/jerseywatch.com"
  ],
  "searchTerms": [],
  "reviewInsights": false,
  "painPointAnalysis": false,
  "enrichEmails": false,
  "qualifyByPayment": false,
  "scrapeAllReviews": true,
  "filterStars": [],
  "sampling": "balanced",
  "filterLanguages": [],
  "filterDateRange": "all",
  "filterVerifiedOnly": false,
  "filterRepliesOnly": false,
  "filterCountries": [],
  "sortBy": "auto",
  "expandRegionalDomains": true,
  "strictNameMatch": false,
  "splitDatasets": false,
  "flattenCompanyData": false,
  "emitInputStatus": true,
  "includeCompanyDetails": false,
  "includeStats": false,
  "includeTransparency": false,
  "includeCompanyAdditionalFields": false,
  "maxItems": 10000,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 100
}
```

# 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 = {
    "startUrls": [
        "bankfive",
        "www.dugood.org",
        "https://www.trustpilot.com/users/5f3a1c9e8b2c4a0007d1e2f3",
        "https://fr.trustpilot.com/review/eminence.fr",
        "https://www.trustpilot.com/review/kindlewritinghub.com",
        "https://www.trustpilot.com/review/www.vans.com",
        "https://www.trustpilot.com/review/shop.missha-deutschland.de",
        "https://www.trustpilot.com/review/dior.co.uk",
        "https://www.trustpilot.com/review/www.barxparx.com",
        "https://www.trustpilot.com/review/oshalafarm.com",
        "https://www.trustpilot.com/review/www.nomador.com?sort=recency",
        "https://www.trustpilot.com/review/apify.com",
        "https://www.trustpilot.com/review/swiftpromining.org",
        "https://www.trustpilot.com/review/couplehoodies.com",
        "https://www.trustpilot.com/review/rosecjewels.com",
        "https://www.trustpilot.com/review/jerseywatch.com"
    ],
    "searchTerms": [],
    "filterLanguages": [],
    "filterCountries": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/trustpilot-scraper-ppe").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 = {
    "startUrls": [
        "bankfive",
        "www.dugood.org",
        "https://www.trustpilot.com/users/5f3a1c9e8b2c4a0007d1e2f3",
        "https://fr.trustpilot.com/review/eminence.fr",
        "https://www.trustpilot.com/review/kindlewritinghub.com",
        "https://www.trustpilot.com/review/www.vans.com",
        "https://www.trustpilot.com/review/shop.missha-deutschland.de",
        "https://www.trustpilot.com/review/dior.co.uk",
        "https://www.trustpilot.com/review/www.barxparx.com",
        "https://www.trustpilot.com/review/oshalafarm.com",
        "https://www.trustpilot.com/review/www.nomador.com?sort=recency",
        "https://www.trustpilot.com/review/apify.com",
        "https://www.trustpilot.com/review/swiftpromining.org",
        "https://www.trustpilot.com/review/couplehoodies.com",
        "https://www.trustpilot.com/review/rosecjewels.com",
        "https://www.trustpilot.com/review/jerseywatch.com",
    ],
    "searchTerms": [],
    "filterLanguages": [],
    "filterCountries": [],
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/trustpilot-scraper-ppe").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 '{
  "startUrls": [
    "bankfive",
    "www.dugood.org",
    "https://www.trustpilot.com/users/5f3a1c9e8b2c4a0007d1e2f3",
    "https://fr.trustpilot.com/review/eminence.fr",
    "https://www.trustpilot.com/review/kindlewritinghub.com",
    "https://www.trustpilot.com/review/www.vans.com",
    "https://www.trustpilot.com/review/shop.missha-deutschland.de",
    "https://www.trustpilot.com/review/dior.co.uk",
    "https://www.trustpilot.com/review/www.barxparx.com",
    "https://www.trustpilot.com/review/oshalafarm.com",
    "https://www.trustpilot.com/review/www.nomador.com?sort=recency",
    "https://www.trustpilot.com/review/apify.com",
    "https://www.trustpilot.com/review/swiftpromining.org",
    "https://www.trustpilot.com/review/couplehoodies.com",
    "https://www.trustpilot.com/review/rosecjewels.com",
    "https://www.trustpilot.com/review/jerseywatch.com"
  ],
  "searchTerms": [],
  "filterLanguages": [],
  "filterCountries": []
}' |
apify call memo23/trustpilot-scraper-ppe --silent --output-dataset

```

## MCP server setup

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

```

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/HYuOke00wY4emLHz1/builds/9571P0FBMsIrlzuFz/openapi.json
