# Trustpilot Review Monitor - Rating Drop & New Review Alerts (`berkaydev/trustpilot-review-monitor`) Actor

Monitor Trustpilot reviews and get ONLY what changed since the last check: new reviews, rating drops, replies. You pass no date - it remembers what it already showed you. One verdict per company with severity and complaint themes. Slack, webhook or AI agent. About $1 per company/month.

- **URL**: https://apify.com/berkaydev/trustpilot-review-monitor.md
- **Developed by:** [Gezgin Data](https://apify.com/berkaydev) (community)
- **Categories:** Agents, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 company checkeds

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 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 Review Monitor

**Monitor Trustpilot reviews** for any company and get alerted only when something actually
changes: **new reviews, rating drops**, review-count jumps and vendor replies. Built for
**competitor review tracking** — point it at your rivals, at your own listing, or at both, and
send the result to Slack, a webhook, or an AI agent.

A scraper tells you what is on a review page. This Actor remembers what was there last time, so
every run returns only the difference — plus a one-line verdict on whether it matters.

### What it does

On its first run against a company, the monitor records the current state and returns a short
confirmation of what it found — the current rating and review count — rather than replaying a year
of history into a freshly connected Slack channel. From then on, each run compares reality against
that stored baseline and emits only the differences.

It detects four kinds of change. A **new review** appears when a review ID shows up that was not
there before. A **reply** is flagged when a company answers a review you had already seen, which
is how you tell whether a competitor actually engages with unhappy customers. A **rating move**
fires when the aggregate score shifts by more than a threshold you set, filtering out rounding
noise. And a **review count change** catches bursts of activity even before individual reviews
surface.

Because it is built on scraping rather than official partner APIs, it is not limited to whichever
platforms have granted API access. New sources are added as adapters without changing anything
else.

### A verdict, not a data dump

Raw change rows leave the interpreting to you. Five one-star reviews about billing are a very
different signal from five about downtime, so every run also produces a digest per company: how
many reviews arrived and how negative they were, how far the rating moved, whether the volume is
unusual compared to that company's own recent history, and which complaint themes dominate.

```
Notion: 6 new reviews averaging 2.5★, 3 negative; rating down 0.4 to 2.3.
Themes: payment, account, deleted, invoice. Volume 6.0x the usual.
```

Each digest carries a severity of none, low, medium or high, derived from stated thresholds rather
than a black box — a rating drop past 0.3, three or more negative reviews, or negative reviews
arriving during a volume spike.

This matters especially if an **AI agent or automation** is the consumer. Set `outputMode` to
`digest` and the Actor returns one compact verdict per company instead of every row, so the agent
gets an answer rather than a pile of text it has to re-read and reason over.

### Why monitor competitors, not just yourself

Most reputation tools are built around managing your own listing, and treat competitor tracking as
an afterthought. That is backwards for sales and product teams. A competitor collecting a wave of
one-star reviews about a missing feature is a signal you can act on this week. A rating that
quietly slides for two months is a market opening. This Actor treats every target the same way,
so watching five competitors is exactly as easy as watching yourself.

### How to use it

Add one line per company under **What to watch**, written as `source:identifier` — for example
`trustpilot:notion.so`. A bare domain works too and defaults to Trustpilot. Run it once to
establish the baseline, then schedule it hourly or daily; each run reports only what moved since
the previous one.

To be told only about bad news, set **Only alert on reviews at or below this rating** to 2 and you
will hear about one- and two-star reviews only. Paste a Slack incoming webhook URL to get a
readable digest in the channel your team already watches, or a plain webhook URL to feed n8n,
Make, your own backend or an AI agent with the raw JSON.

### Input

The only required field is `targets`. Everything else has a sensible default. `firstRun` controls
whether the first run stays silent or reports everything it finds. `minScoreDelta` sets how big a
rating move has to be before it counts. `maxReviewsPerCheck` controls how deep each scan goes —
reviews are read newest-first, so a shallow scan is normally enough and keeps the cost per check
low. Raise it only if a target collects more reviews between two runs than the scan window.

State is kept in a named key-value store so it survives between runs. Use different
`stateStoreName` values to keep separate watchlists apart, and `resetBaseline` to start over after
changing what you monitor.

### Output

Each detected change becomes one dataset row carrying the change type, the company, the full
review where applicable, and before/after values for rating and count changes. You can download
the dataset as JSON, CSV, Excel or HTML.

```json
{
  "changeType": "new_review",
  "source": "trustpilot",
  "targetName": "Notion",
  "rating": 1,
  "title": "Charged after deleting my account",
  "publishedDate": "2026-08-04T10:13:26.000Z",
  "reviewUrl": "https://www.trustpilot.com/reviews/…",
  "detectedAt": "2026-08-07T12:47:37+00:00"
}
```

```json
{
  "changeType": "score_changed",
  "targetName": "Notion",
  "previousValue": 2.5,
  "currentValue": 2.3,
  "delta": -0.2
}
```

Every run also writes a `RUN_STATUS` record to the key-value store, stating per target whether the
check succeeded and why it did not. This matters more than it sounds: a monitor that silently
returns "no changes" when its scraper is broken is worse than one that fails loudly, because an
empty result reads as a fact and gets acted on. A failed read never overwrites a good baseline
either, so a temporary outage cannot cause the next run to replay everything as new.

### Cost

You pay per check performed and per change detected, not per monitored company. Watching many
companies therefore does not multiply a subscription — a monitor that finds nothing on a quiet day
costs almost nothing. Trustpilot needs no residential proxy, so monitoring runs on Apify's free
tier.

### Sources and roadmap

Trustpilot is supported today. G2 support is written and tested but waits on residential proxy
access, since G2 hard-blocks datacenter IP addresses. Capterra and app store reviews follow the
same adapter pattern.

### Notes and support

The Actor reads publicly visible review pages only. Please make sure your use complies with the
terms of the sites you monitor and with applicable data protection law, particularly if you store
reviewer names. Found a bug or need another source? Open an issue on the Actor's Issues tab.

# Actor input Schema

## `targets` (type: `array`):

One entry per company to monitor, written as `source:identifier`. Example: `trustpilot:notion.so`. A bare domain like `notion.so` uses Trustpilot. Watch your competitors, not just yourself — that is what this is built for.

## `firstRun` (type: `string`):

There is nothing to compare against on the first run. `baseline` records the current state and returns a short confirmation of the rating and review count found (recommended — otherwise a freshly connected Slack channel gets flooded with history). `emitAll` reports every review it currently sees.

## `alertMaxRating` (type: `integer`):

Set to 2 to be told only about 1- and 2-star reviews. Leave at 0 to report every new review.

## `outputMode` (type: `string`):

`digest` returns one verdict per company — severity, counts, rating move and the dominant complaint themes — and nothing else. Best for AI agents and automations, since it answers the question instead of handing over rows to re-analyse. `changes` returns the individual reviews only. `both` returns the verdict first, then the detail.

## `trackReplies` (type: `boolean`):

Detects that a vendor answered a review you had already seen. Useful for watching how responsive a competitor is.

## `minScoreDelta` (type: `number`):

Report a rating change only once it moves by at least this much. Filters out meaningless rounding noise.

## `slackWebhookUrl` (type: `string`):

Optional. Detected changes are posted as a readable digest to this Slack channel.

## `webhookUrl` (type: `string`):

Optional. Receives the raw JSON change list — for n8n, Make, your own backend, or an AI agent.

## `maxReviewsPerCheck` (type: `integer`):

Reviews are scanned newest-first, so a shallow scan is enough to catch what is new — and keeps the cost per check low. Raise it only if a target gets more reviews than this between two runs.

## `stateStoreName` (type: `string`):

Named key-value store holding the baseline between runs. Use different names to keep separate watchlists apart.

## `resetBaseline` (type: `boolean`):

Ignore what was stored and start over from the current state. Use after changing what you monitor.

## `maxRunTimeSecs` (type: `integer`):

The run stops cleanly before this limit, keeping results and baselines intact.

## Actor input object example

```json
{
  "targets": [
    "trustpilot:notion.so"
  ],
  "firstRun": "baseline",
  "alertMaxRating": 0,
  "outputMode": "both",
  "trackReplies": true,
  "minScoreDelta": 0.1,
  "maxReviewsPerCheck": 40,
  "stateStoreName": "review-monitor-state",
  "resetBaseline": false,
  "maxRunTimeSecs": 1800
}
```

# 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 = {
    "targets": [
        "trustpilot:notion.so"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("berkaydev/trustpilot-review-monitor").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 = { "targets": ["trustpilot:notion.so"] }

# Run the Actor and wait for it to finish
run = client.actor("berkaydev/trustpilot-review-monitor").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 '{
  "targets": [
    "trustpilot:notion.so"
  ]
}' |
apify call berkaydev/trustpilot-review-monitor --silent --output-dataset

```

## MCP server setup

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

```

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/al2zochxlLsvdlloN/builds/lFuvGYz37GRRAYsse/openapi.json
