# Trustpilot Scraper 2026 — Delta Monitor (Birdeye alt, PPE) (`zhorex/trustpilot-brand-watch`) Actor

Monitor Trustpilot reviews on a daily or hourly cron and receive ONLY new reviews since the previous run. Watermark-based delta engine, 8 locales (.com/.de/.fr/.it/.es/.nl/.se/.dk), Pay-Per-Event at $0.0015/review. Replaces $299/mo Birdeye Starter at $20-50/mo per brand.

- **URL**: https://apify.com/zhorex/trustpilot-brand-watch.md
- **Developed by:** [Sami](https://apify.com/zhorex) (community)
- **Categories:** Lead generation, Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 trustpilot review scrapeds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Brand Watch — delta-mode review monitor at $3.00 / 1K reviews

The Trustpilot review monitor your team actually leaves running. **Daily or hourly cron returns ONLY the new reviews since the previous run**, not the same 50,000 historical reviews every time. Pay-Per-Event at **$0.003 per review + $0.10 per scheduled snapshot**. Multi-locale (.com / .de / .fr / .it / .es / .nl / .se / .dk). Crisis-monitoring filter built in (`minStarRating`). Built for Customer Experience and Reputation Managers running real reputation monitoring, not bulk dumps.

> **Pricing anchor:** Birdeye Starter runs **$299/mo per location** for review monitoring. Reputation.com starts at $1,400/mo per location. This Actor monitors **10 brands daily on a cron for ~$30-100/mo** — still a meaningful reduction in cost-per-monitored-brand vs. the SaaS incumbents, with the same headline workflow: cron → new reviews → Slack / email digest.

---

### How to monitor your Trustpilot reputation in 3 easy steps

1. **Pick the domains you want to watch** — `["stripe.com", "ramp.com", "zalando.de"]`. They're the exact strings that appear in the Trustpilot URL (`trustpilot.com/review/<domain>`).
2. **Choose your locale and rating filter.** `com` for global English brands, `de` for DACH brand health, `es` for Iberian. Set `minStarRating: 1` if you want crisis alerts (catch 1- and 2-star reviews); set `4` if you only want positive testimonials.
3. **Schedule a daily or hourly run.** Apify Saved Tasks → Schedules → cron string (e.g. `0 9 * * *` for 9am daily). Delta mode is the default — only new reviews since the last run are returned and charged.

That's it. The watermark is persisted automatically in the Actor's key-value store; you do not need to track timestamps yourself.

---

### Enterprise inquiry

Running >10K reviews per month, monitoring across all 8 locales, or need a schema SLA for downstream pipelines? Contact the author through the Actor page — custom dataset views, webhook integrations, and dedicated proxy pools are available on request. Typical enterprise lift turnaround is one week.

---

### Who buys this Actor

| Buyer persona | Typical monthly spend | Why this Actor wins |
|---|---|---|
| Customer Experience Manager at a 50-500 person DTC brand | $30-100/mo per brand monitored | Replaces $299/mo Birdeye Starter with the same daily-digest workflow |
| Reputation Manager at a B2B SaaS | $50-200/mo across 5-10 product lines | Per-brand budget bookkeeping, locale separation for EU subsidiaries |
| Trust & Safety analyst (marketplace / fintech) | $100-500/mo | Crisis alerts on 1-star reviews mentioning specific keywords — push to PagerDuty |
| Competitive intelligence at a Series B startup | $80-250/mo | Tracks 8-15 competitors' review velocity + sentiment trend |
| LLM training pipeline (sentiment, intent classification) | $200-2,000/mo | Multilingual, structured, dated reviews with verified-purchase flag |
| M&A diligence consultancy | $500-3,000/one-off | Bulk pull of acquisition-target review history across all 8 locales |

---

### Example use cases

1. **Crisis monitoring** — `minStarRating: 1, mode: "delta"` on a 30-minute cron. Any new 1- or 2-star review pages on-call inside half an hour, before a viral thread forms.
2. **Daily customer-experience digest** — 10 brands on a 9am cron, push the delta via webhook into Slack `#cx-daily`. CX team starts the day with 100% of yesterday's new reviews already triaged.
3. **DACH locale brand health** — `locale: "de"` for German consumer-facing brands. Catches reviews on `de.trustpilot.com` that NEVER appear on the global `.com` feed.
4. **Competitor reputation watch** — daily delta across 8 competitor domains; build a weekly Slack report showing each competitor's rating trend + reply rate.
5. **M&A target diligence** — one-off `mode: "full"` run against an acquisition target across all 8 locales, full review history. Then switch to `delta` for ongoing post-LOI monitoring.
6. **Sentiment-classifier training data** — multilingual structured reviews with verified-purchase flag are gold-standard supervised training data. Pull 50K labeled reviews across `de` / `fr` / `it` / `es` for a multilingual sentiment model.

---

### Pricing (Pay-Per-Event)

| Event | Price | When it fires |
|---|---|---|
| `review-scraped` | **$0.003 / review** | One charge per genuinely-new review returned (duplicates suppressed by the delta watermark are free) |
| `scheduled-domain-snapshot` | **$0.10 / domain / run** | Once per (domain, locale) per scheduled run — covers orchestration even on quiet days when zero new reviews appeared |

#### Realistic monthly cost examples

| Workflow | Volume | Monthly cost |
|---|---|---|
| 1 brand, daily cron, ~20 new reviews/day | 600 reviews + 30 snapshots | **~$5 / month** |
| 5 brands, daily cron, ~10 new reviews/brand/day | 1,500 reviews + 150 snapshots | **~$20 / month** |
| 10 brands, hourly cron, crisis monitoring (~5 new/brand/day) | 1,500 reviews + 7,200 snapshots | **~$725 / month** ⚠ |
| 10 brands, 6× daily cron (every 4h) | 1,500 reviews + 1,800 snapshots | **~$185 / month** |
| 10 brands, daily cron | 3,000 reviews + 300 snapshots | **~$40 / month** vs. Birdeye $2,990/mo for 10 locations |
| One-off M&A diligence (full mode, 1 brand, 8 locales) | 50,000 reviews + 8 snapshots | **~$151 one-off** |

> **Cron-frequency tip:** the per-snapshot price is what funds the orchestration cost on quiet days. For most reputation-monitoring workflows, daily or 4-hourly is the sweet spot. Hourly is only economical for crisis-watch on a small handful of high-risk brands.

In Apify Console, the built-in `apify-default-dataset-item` event is set to **$0.00001** to avoid double-billing — your actual line items are the two events in the table above.

---

### Python example

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("zhorex/trustpilot-brand-watch").call(run_input={
    "domains": ["stripe.com", "ramp.com", "mercury.com"],
    "locale": "com",
    "mode": "delta",
    "minStarRating": 1,
    "maxReviewsPerDomain": 500,
    "includeReply": True,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["isNew"] and item["starRating"] <= 2:
        ## Page on-call: a 1- or 2-star review just landed.
        notify_pagerduty(item)
````

### JavaScript example

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

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

const run = await client.actor('zhorex/trustpilot-brand-watch').call({
    domains: ['zalando.de', 'aboutyou.de', 'asos.com'],
    locale: 'de',
    mode: 'delta',
    minStarRating: 1,
    includeReply: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const newOnly = items.filter(r => r.isNew);
console.log(`${newOnly.length} new reviews since last run`);
```

***

### Scheduled / recurring runs — the money section

Delta mode + Apify Saved Tasks + a cron schedule is the entire point of this Actor. The recipe:

1. **Run once with `mode: "full"`** to backfill historical reviews (one-time cost).
2. **Save as a Task** with `mode: "delta"` and your desired domains / locale / filter.
3. **Open the Task → Schedules → New Schedule** with one of the cron strings below.
4. **Add a webhook** to the Schedule to push the dataset into Slack / Discord / Zapier / your data warehouse.

| Use case | Cron string | What you'll spend |
|---|---|---|
| Daily 9am digest, 10 brands | `0 9 * * *` | ~$40/mo |
| Crisis watch every 4 hours, 5 brands | `0 */4 * * *` | ~$95/mo |
| Twice-daily DACH locale, 20 brands | `0 9,17 * * *` | ~$130/mo |
| Hourly crisis-only watch on 3 brands | `0 * * * *` | ~$220/mo |
| Weekly competitor report, 8 brands | `0 9 * * 1` | ~$19/mo |

Pair the schedule with an Apify webhook → Slack incoming-webhook URL and you have a sub-$50 alternative to a $299/mo SaaS reputation tool.

***

### Example input

```json
{
    "domains": ["stripe.com", "ramp.com"],
    "locale": "com",
    "mode": "delta",
    "minStarRating": 1,
    "maxReviewsPerDomain": 500,
    "includeReply": true
}
```

### Example output (one record per review)

```json
{
    "reviewId": "65f8a2c1d9b4e1234567890a",
    "domain": "stripe.com",
    "locale": "com",
    "reviewerName": "Sarah K.",
    "reviewerCountry": "US",
    "reviewerProfileUrl": "https://www.trustpilot.com/users/abc123",
    "starRating": 5,
    "reviewTitle": "Smoothest payments integration",
    "reviewText": "We migrated from a legacy gateway and the onboarding took 2 days...",
    "reviewLanguage": "en",
    "verifiedPurchase": true,
    "reviewedAt": "2026-05-17T08:14:00+00:00",
    "reviewUrl": "https://www.trustpilot.com/reviews/65f8a2c1d9b4e1234567890a",
    "helpfulVotes": 4,
    "companyReply": {
        "text": "Thanks Sarah! Glad the migration went smoothly.",
        "repliedAt": "2026-05-17T09:02:00+00:00"
    },
    "isNew": true,
    "scrapedAt": "2026-05-17T10:00:00+00:00"
}
```

***

### Output schema reference

| Field | Type | Notes |
|---|---|---|
| `reviewId` | string | Stable Trustpilot ID — use as primary key for downstream dedup |
| `domain` | string | The brand domain you submitted |
| `locale` | string | The Trustpilot locale (`com`, `de`, `fr`, `it`, `es`, `nl`, `se`, `dk`) |
| `reviewerName` | string | null | Display name (Trustpilot allows partial anonymization) |
| `reviewerCountry` | string | null | ISO country code |
| `reviewerProfileUrl` | string | null | Link to the reviewer's profile |
| `starRating` | int (1-5) | |
| `reviewTitle` | string | null | |
| `reviewText` | string | |
| `reviewLanguage` | string | ISO 639-1 language code (`und` if Trustpilot did not tag) |
| `verifiedPurchase` | bool | True if Trustpilot tagged the review as verified |
| `reviewedAt` | ISO 8601 | UTC timestamp of when the consumer published the review |
| `reviewUrl` | string | Permalink to the individual review |
| `helpfulVotes` | int | Community "helpful" up-votes |
| `companyReply.text` | string | null | The brand's official public reply, if any |
| `companyReply.repliedAt` | ISO 8601 | null | When the brand replied |
| `isNew` | bool | True if this is the first time this Actor has emitted the review in the current watermark cycle |
| `scrapedAt` | ISO 8601 | When the Actor extracted the record |

***

### Multi-locale support

Trustpilot operates per-locale subdomains. **The review pools do not overlap.** A German consumer reviewing `zalando.de` on `de.trustpilot.com` is NOT visible on `www.trustpilot.com/review/zalando.de`. For accurate brand-health metrics you must scrape the locale your audience uses.

| `locale` value | Host | Typical buyer use case |
|---|---|---|
| `com` | www.trustpilot.com | Global English-speaking brands, US / UK / AU / IE / CA / SG |
| `de` | de.trustpilot.com | DACH region — Germany, Austria, Switzerland — by far the highest-volume non-English locale |
| `fr` | fr.trustpilot.com | France + French-speaking Belgium and Quebec |
| `it` | it.trustpilot.com | Italy |
| `es` | es.trustpilot.com | Spain + LATAM-Spanish |
| `nl` | nl.trustpilot.com | Netherlands + Flemish Belgium |
| `se` | se.trustpilot.com | Sweden |
| `dk` | dk.trustpilot.com | Denmark (Trustpilot's home market — depth is excellent here) |

For a brand operating in multiple regions, run one Saved Task per locale. Watermarks are stored per (domain, locale) so the deltas stay independent.

***

### What this Actor is NOT

- **Not a Trustpilot API replacement.** Trustpilot has an official Business API for verified business accounts. If you OWN the brand on Trustpilot, that API gives you write access (invitations, replies). This Actor is for READ-only monitoring — your own brand, your competitors, or any public listing.
- **Not a profile-data scraper.** This Actor returns reviews. It does not crawl reviewer profile pages, friend graphs, or PII beyond what each review's metadata already publishes.
- **Not a real-time push.** It's polling, not subscriptions. The shortest practical cron interval is ~15 minutes for crisis-watch use cases.
- **Not a login bypass.** The optional `cookieString` only accepts a cookie YOU paste from your own logged-in session — there is no credential acceptance and no scraping of authenticated-only pages.

***

### Optional cookies

`cookieString` is an OPTIONAL input. Leave it empty for the default anonymous workflow — it works for typical monitoring loads.

Provide a cookie string only when:

- You're running heavy multi-domain bulk pulls (>30 domains in a single run) and want a higher per-IP rate ceiling.
- You're behind a corporate proxy that already provides Trustpilot cookies and you want to reuse them.

Format: paste the entire `Cookie:` header value from your browser DevTools `Network` tab while on `trustpilot.com`. The Actor uses it as-is and never logs it.

***

### FAQ

**Q: What's the best Trustpilot scraper in 2026?**
A: For one-shot bulk dumps, any of the existing Apify Trustpilot actors work. For ongoing **monitoring** with daily or hourly cron, this is the only one that returns ONLY new reviews per run — the rest re-scrape and re-charge for the full history every time. If your workflow is a cron, the math is decisive.

**Q: Is there a Trustpilot reviews API?**
A: Trustpilot's Business API exists but is gated to verified brand owners and is read+write for INVITATION management, not bulk reading. For monitoring third-party brands (competitors, marketplace tenants, etc.) you need a scraper — this Actor is it.

**Q: How is this a Birdeye alternative?**
A: Birdeye Starter is $299/mo per location for review monitoring + a Slack digest + sentiment alerts. The "review monitoring" piece is what this Actor replaces, at $30-100/mo per location. For the digest and sentiment layer, pipe the Actor's webhook into Slack and any sentiment classifier — you'll spend another $0-50/mo and have a fully replicated workflow.

**Q: How does the delta mode work technically?**
A: On every run, this Actor reads a watermark from Apify's key-value store (one per `domain + locale` pair). It then scrapes reviews newest-first and STOPS as soon as it hits a review at-or-before the watermark. Only the new reviews are emitted, charged, and pushed to the dataset. After the run, the watermark is updated to the newest review's timestamp. Net result: on a daily cron, you pay for ~20 new reviews/brand/day instead of ~5,000 historical ones.

**Q: What if I want to back-fill all reviews ever for a brand?**
A: Run once with `mode: "full"` (and a high `maxReviewsPerDomain`). The next run, switch to `mode: "delta"` — the watermark will already be set, so delta picks up cleanly from where full left off.

**Q: I'm running this on a casper11515 / parseforge / memo23 saved task that just got expensive — is this a drop-in replacement?**
A: Yes for the reading workflow, and substantially cheaper. The rental Trustpilot actors charge a flat monthly fee regardless of usage; this Actor is strict PPE so a quiet brand is essentially free to monitor. The output schema is a superset of the rental actors' schemas plus the `isNew` flag, so downstream pipelines need almost no changes.

**Q: What about the Apify Trustpilot rental sunset on Oct 1, 2026?**
A: Apify is deprecating the rental pricing model across the whole marketplace on Oct 1, 2026. Every Trustpilot rental actor (memo23, parseforge, casper11515) will have to migrate to PPE by then or shut down. This Actor was built PPE-first; there is no migration risk.

**Q: Will it scrape `de.trustpilot.com` if I give it `zalando.de`?**
A: Set `locale: "de"`. The Actor routes the request to `de.trustpilot.com/review/zalando.de`. Without the explicit `locale`, the default `com` will look on `www.trustpilot.com/review/zalando.de` — Trustpilot will return a separate (much smaller) review pool.

**Q: How fresh is the data?**
A: Reviews appear on Trustpilot in real time as consumers publish them. This Actor extracts whatever is published at the moment of the cron run, so freshness is bounded by your cron interval (typically 15min – 24h).

**Q: Does it return private / internal Trustpilot data?**
A: No. Only the public review content that any anonymous browser visitor sees on the public `trustpilot.com/review/<domain>` page. No login bypass, no internal endpoints.

**Q: Will it bypass Cloudflare?**
A: The HTTP layer uses browser-grade HTTP transport that matches real-browser fingerprints at the TLS layer, which is enough for the default residential Apify proxy. If Cloudflare gets aggressive on a specific locale during a campaign, the retry-with-backoff loop and the session warm-up usually clear it; in rare cases switching residential proxy country resolves it.

**Q: Is there a Trustpilot reviews PPE pricing benchmark?**
A: At $0.003/review this is competitively priced for a PPE-based Trustpilot scraper on Apify Store as of May 2026 — and the only one with delta-mode watermarking. Bulk-mode actors typically charge $0.001-$0.01/review, but they re-charge for the full history on every run; this Actor charges only for genuinely-new reviews.

***

### Compliance posture

- **Public data only** — same content any anonymous browser visitor sees on `trustpilot.com/review/<domain>` pages.
- **No login bypass** — does not attempt authenticated-only content. The optional `cookieString` is reserved for cookies the buyer pastes from their own logged-in session.
- **No PII harvesting beyond what Trustpilot itself publishes** — reviewer display names and country codes are the same fields Trustpilot makes public on every review card.
- **Respects robots.txt and rate-limit posture** — jittered request cadence, bounded concurrency, retry-with-backoff on 429.

Buyers running this commercially are responsible for downstream compliance with their own jurisdiction's data laws (GDPR, CCPA, etc.) regarding storage and processing of public review content.

***

### Roadmap

- **v0.2** — Webhook-shaped delta payload (single envelope per cron with a `newReviews` array, optimized for Slack/Discord/Zapier).
- **v0.3** — Sentiment-score field on each review using a lightweight classifier (multilingual).
- **v0.4** — Optional keyword-trigger event (`crisis-detected`) that fires a separate PPE event when a new ≤2★ review contains user-supplied keywords (e.g. "scam", "refund refused").
- **v0.5** — `daterange` mode for pulling a specific window (e.g. only reviews from last 90 days, for cohort comparisons).
- **v1.0** — Trustpilot Profile graph (companies the same reviewer has rated) — pending demand validation.

***

### Suite

Part of zhorex's **Reputation Intelligence Suite** — pair with the Booking.com Reviews Scraper (hospitality) and (forthcoming) G2 + Capterra delta monitors for full-stack B2B+DTC reputation coverage in one normalized schema.

If this Actor saves you time, **a 30-second review is the single most valuable thing you can do** — it brings the tool to other buyers and pays for continued maintenance. Thanks for trying it.

***

*Last updated: May 2026*

# Actor input Schema

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

List of company domains as they appear on Trustpilot (e.g. 'stripe.com', 'ramp.com', 'zalando.de'). One review feed per domain. Submit 1-200 domains per run; use a Saved Task + cron for ongoing monitoring.

## `locale` (type: `string`):

Which Trustpilot locale to query. Locales have SEPARATE review pools — German consumers leave reviews on de.trustpilot.com that don't appear on .com. For DACH brand health pick 'de'; for Iberian / LATAM-Spanish pick 'es'; default 'com' is global English.

## `mode` (type: `string`):

'delta' (default) returns ONLY reviews newer than the watermark stored from your last scheduled run — turns this Actor into a real-time reputation monitor and keeps PPE cost near zero on quiet days. 'full' returns every review up to maxReviewsPerDomain — use once for the initial backfill, then switch to delta for the cron.

## `minStarRating` (type: `integer`):

Only return reviews at or above this rating. Set 1 (default) to catch crisis-level 1- and 2-star reviews; set 4 if you only care about positive testimonials.

## `maxReviewsPerDomain` (type: `integer`):

Safety cap on the number of reviews extracted per domain per run. Delta mode usually returns far fewer (only new reviews); this cap mainly applies to 'full' mode backfills.

## `includeReply` (type: `boolean`):

If the brand has replied publicly on Trustpilot, include the reply text and timestamp. Default on — this is one of the most useful signals for customer-experience auditing.

## `watermarkKey` (type: `string`):

Override the default watermark key (auto-derived per domain+locale). Use this if you want two independent cron schedules over the same domain — e.g. a daily 'crisis' delta filtered to 1-star and a weekly 'highlights' delta filtered to 5-star.

## `cookieString` (type: `string`):

Optional. Paste a logged-in cookie header from your browser DevTools to raise per-IP rate limits on heavy multi-domain runs. Leave empty for anonymous browsing (works for typical workloads).

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

Apify residential proxy is recommended. Default pins to US residentials, which Trustpilot's Cloudflare edge waves through most reliably. For DACH-locale runs that get edge-challenged, override to apifyProxyCountry='DE' or 'GB'.

## Actor input object example

```json
{
  "domains": [
    "stripe.com"
  ],
  "locale": "com",
  "mode": "delta",
  "minStarRating": 1,
  "maxReviewsPerDomain": 500,
  "includeReply": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# 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 = {
    "domains": [
        "stripe.com"
    ],
    "mode": "delta"
};

// Run the Actor and wait for it to finish
const run = await client.actor("zhorex/trustpilot-brand-watch").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 = {
    "domains": ["stripe.com"],
    "mode": "delta",
}

# Run the Actor and wait for it to finish
run = client.actor("zhorex/trustpilot-brand-watch").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "domains": [
    "stripe.com"
  ],
  "mode": "delta"
}' |
apify call zhorex/trustpilot-brand-watch --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zhorex/trustpilot-brand-watch",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Trustpilot Scraper 2026 — Delta Monitor (Birdeye alt, PPE)",
        "description": "Monitor Trustpilot reviews on a daily or hourly cron and receive ONLY new reviews since the previous run. Watermark-based delta engine, 8 locales (.com/.de/.fr/.it/.es/.nl/.se/.dk), Pay-Per-Event at $0.0015/review. Replaces $299/mo Birdeye Starter at $20-50/mo per brand.",
        "version": "0.3",
        "x-build-id": "NrWIOLw9zT3O3gM4i"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/zhorex~trustpilot-brand-watch/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-zhorex-trustpilot-brand-watch",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/zhorex~trustpilot-brand-watch/runs": {
            "post": {
                "operationId": "runs-sync-zhorex-trustpilot-brand-watch",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/zhorex~trustpilot-brand-watch/run-sync": {
            "post": {
                "operationId": "run-sync-zhorex-trustpilot-brand-watch",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "domains"
                ],
                "properties": {
                    "domains": {
                        "title": "Company domains to monitor",
                        "type": "array",
                        "description": "List of company domains as they appear on Trustpilot (e.g. 'stripe.com', 'ramp.com', 'zalando.de'). One review feed per domain. Submit 1-200 domains per run; use a Saved Task + cron for ongoing monitoring.",
                        "default": [
                            "stripe.com"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "locale": {
                        "title": "Trustpilot locale",
                        "enum": [
                            "com",
                            "de",
                            "fr",
                            "it",
                            "es",
                            "nl",
                            "se",
                            "dk"
                        ],
                        "type": "string",
                        "description": "Which Trustpilot locale to query. Locales have SEPARATE review pools — German consumers leave reviews on de.trustpilot.com that don't appear on .com. For DACH brand health pick 'de'; for Iberian / LATAM-Spanish pick 'es'; default 'com' is global English.",
                        "default": "com"
                    },
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "delta",
                            "full"
                        ],
                        "type": "string",
                        "description": "'delta' (default) returns ONLY reviews newer than the watermark stored from your last scheduled run — turns this Actor into a real-time reputation monitor and keeps PPE cost near zero on quiet days. 'full' returns every review up to maxReviewsPerDomain — use once for the initial backfill, then switch to delta for the cron.",
                        "default": "delta"
                    },
                    "minStarRating": {
                        "title": "Minimum star rating",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Only return reviews at or above this rating. Set 1 (default) to catch crisis-level 1- and 2-star reviews; set 4 if you only care about positive testimonials.",
                        "default": 1
                    },
                    "maxReviewsPerDomain": {
                        "title": "Max reviews per domain (hard cap)",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Safety cap on the number of reviews extracted per domain per run. Delta mode usually returns far fewer (only new reviews); this cap mainly applies to 'full' mode backfills.",
                        "default": 500
                    },
                    "includeReply": {
                        "title": "Include company reply",
                        "type": "boolean",
                        "description": "If the brand has replied publicly on Trustpilot, include the reply text and timestamp. Default on — this is one of the most useful signals for customer-experience auditing.",
                        "default": true
                    },
                    "watermarkKey": {
                        "title": "Custom watermark key (optional)",
                        "type": "string",
                        "description": "Override the default watermark key (auto-derived per domain+locale). Use this if you want two independent cron schedules over the same domain — e.g. a daily 'crisis' delta filtered to 1-star and a weekly 'highlights' delta filtered to 5-star."
                    },
                    "cookieString": {
                        "title": "Optional Trustpilot cookie string",
                        "type": "string",
                        "description": "Optional. Paste a logged-in cookie header from your browser DevTools to raise per-IP rate limits on heavy multi-domain runs. Leave empty for anonymous browsing (works for typical workloads)."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify residential proxy is recommended. Default pins to US residentials, which Trustpilot's Cloudflare edge waves through most reliably. For DACH-locale runs that get edge-challenged, override to apifyProxyCountry='DE' or 'GB'.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
