# Reviews Scraper & AI Insights — 5 Sources in One (`almoutasem_nabil/review-intelligence`) Actor

All public reviews for a company or app across Trustpilot, G2, Capterra, the App Store and Google Play in one schema, with ratings, dates and company replies. Optional AI insights: themes, pain points, praise, feature requests and competitor mentions, in English or Arabic.

- **URL**: https://apify.com/almoutasem\_nabil/review-intelligence.md
- **Developed by:** [Al Moutasem Nabil](https://apify.com/almoutasem_nabil) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

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

## Reviews Scraper & AI Insights — Trustpilot, G2, Capterra, App Store & Google Play

All public reviews for a company or app across five sources in one schema, with ratings, dates and
company replies. Optional AI insights: themes, pain points, praise, feature requests and competitor
mentions, in English or Arabic. Alerts for new and negative reviews.

جمع تقييمات ومراجعات أي شركة أو تطبيق من آب ستور وجوجل بلاي وترست بايلوت في مخطط واحد موحّد، مع تحليل
ذكي للمواضيع ونقاط الألم وطلبات الميزات — بالعربية الفصحى أو الإنجليزية، وتنبيهات فورية للمراجعات
السلبية الجديدة.

### Who it's for

- **Product teams** turning hundreds of reviews into a themed backlog instead of reading them all.
- **CX and support leads** who need to know within a day when a bad review lands.
- **Agencies and competitive-intel analysts** tracking several companies at once.
- **Investors** checking whether a portfolio company's ratings are trending up or down.
- **App publishers** watching Gulf storefronts (sa, ae, eg) alongside us and gb.

### What makes it different

- **Five sources, one schema.** A Trustpilot review and an App Store review come back with the same
  fields and the same 1–5 rating scale.
- **Company replies included**, so you can see which complaints were answered.
- **Arabic and English insights.** Analysis is written in Modern Standard Arabic when you ask for
  it, while quotes stay in the language they were written in.
- **Alerts, not dumps.** Change mode returns only new reviews, negative reviews, rating drops and
  newly added replies.
- **Anonymized at the source.** No reviewer names, handles, avatars or profile links ever enter the
  dataset — they are stripped in the source adapters, before a record is built.

### Output

Four item types, told apart by `itemType`, all documented in `.actor/dataset_schema.json`: `review`,
`summary` (per target × source), `insights` (per target) and `alert` (change mode). The Console
shows **Reviews**, **Insights** and **Alerts** views.

A review, from a real run:

```json
{
    "itemType": "review",
    "source": "googleplay",
    "target": "Notion",
    "productName": "Notion: Notes, Tasks, AI",
    "reviewId": "5f56eb4a-baf7-4ff8-b2ae-e33c15873454",
    "rating": 1,
    "title": null,
    "text": "when I try to open the settings page it will stuck",
    "language": "en",
    "publishedAt": "2026-09-06T16:07:11.184Z",
    "country": "us",
    "appVersion": "0.6.4114",
    "helpfulCount": 2,
    "companyReply": null,
    "scrapedAt": "2026-09-07T06:00:00.000Z"
}
```

An insights item (shape; requires an LLM key — see Limitations):

```json
{
    "itemType": "insights",
    "target": "Notion",
    "overallSentiment": -0.15,
    "themes": [
        {
            "theme": "Sync reliability",
            "sentiment": -0.6,
            "count": 14,
            "shortQuotes": ["sync stops working after a few hours"]
        }
    ],
    "painPoints": ["Offline mode loses edits"],
    "praise": ["Flexible database views"],
    "featureRequests": ["Native Arabic RTL support"],
    "competitorMentions": [{ "competitor": "Obsidian", "count": 4, "context": "cited as faster for local notes" }],
    "suggestedActions": ["Investigate sync failures on Android 14"],
    "sourceBreakdown": { "appstore": 40, "googleplay": 40 },
    "reviewsAnalyzed": 80,
    "language": "en"
}
```

### Alerts and scheduling

1. Set `emitChangesOnly` and a `trackingId`, then **Save as task**.
2. Add a **Schedule** — daily is typical, hourly if you are in a launch week.
3. Under **Integrations**, send results to Slack, Email, a Webhook, Make or Zapier on
   *Run succeeded*. In change mode the dataset is empty when nothing happened, so you only hear from
   it when something did.
4. Route by `type`: send `negative_review` and `rating_drop` to a human, log `new_review`.

The first run for a tracking ID records a baseline **silently**, so your first alert is a real one.

#### n8n and Make

Use the Apify node with *Run Actor and get dataset*, then filter on
`type == "negative_review"` to open a ticket, or on `rating_drop` to notify a lead.

### Use as an API / MCP tool

With **Standby** enabled:

```
GET https://<your-actor>.apify.actor/?target=Notion&sources=appstore,googleplay&aiInsights=1
```

Parameters mirror the input (`target`, `website`, `sources`, `countries`, `lastNDays`,
`maxReviewsPerSource`, `aiInsights`, `insightsLanguage`, `trackingId`). `GET /health` returns
`{"ok":true}`.

### Pricing

Pay-per-event. You pay for sources read, reviews returned and analysis produced.

| Event            | Price  | When                                                                |
| ---------------- | ------ | ------------------------------------------------------------------- |
| Source checked   | $0.005 | Per target × source fetched successfully. A blocked source is free. |
| Review           | $0.002 | Per normalized review stored.                                       |
| AI insight batch | $0.03  | Per batch of 10 reviews analyzed; the rollup is included.           |
| Alert            | $0.01  | Change mode, per alert. Source errors are free.                     |

- **500 reviews across 3 sources** for one company: 3 × $0.005 + 500 × $0.002 = **$1.015**.
- **AI insights over those 500 reviews** (50 batches): **$1.50**.
- **Daily alerts for 10 competitors**: about **$0.15 a day**, plus $0.01 per new review.

Default memory 512 MB is enough; the Actor makes no browser calls.

### Per-source notes and limitations

- **Apple App Store** — Apple's public customer-reviews feed, per storefront. Reliable and fast. The
  feed carries no developer replies, so `companyReply` is null for App Store reviews.
- **Google Play** — through the maintained `google-play-scraper` package, including replies. A Play
  breakage is usually fixed by bumping that dependency.
- **Trustpilot** — read from the page's embedded JSON rather than CSS, so it survives redesigns. It
  is fronted by bot protection that **refuses most datacenter traffic**; if you see a source error,
  switch `proxyConfiguration` to residential proxies.
- **G2 and Capterra** — **off by default.** Both block automated traffic aggressively and publish no
  feed. Selecting them will normally return a source error rather than reviews. They are listed so
  the input is honest about what exists, not because they work reliably today.
- **AI insights need a key.** Without `OPENROUTER_API_KEY` or `OPENAI_API_KEY` set on the Actor,
  `aiInsights` is skipped with a warning and nothing is charged for it.
- Reviews with no date are kept rather than dropped, so a source that omits dates is not silently
  filtered away by `lastNDays`.

### Related actors

- **[Hiring Signals Monitor](../hiring-signals-monitor)** — track companies' career pages.
- **[Ad Library Intelligence](../ad-library-intelligence)** — track competitors' live ads.
- **[Website Change Monitor](../page-change-monitor)** — track any page for changes.

### Legal note

The Actor reads publicly published reviews — the same content any visitor sees — and never logs in
or sends cookies. It collects **no reviewer identity**: names, handles, avatars and profile links are
stripped in the source adapters before a record is built, and contact details pasted into review
text are redacted. Quotes inside AI insights are short excerpts of at most 15 words, never whole
reviews. Review text remains the work of its authors and the property of the platform that hosts it;
use the output for analysis in line with each source's terms and the laws that apply to you.
Trustpilot, G2, Capterra, Apple and Google are trademarks of their owners; this Actor is not
affiliated with them.

# Actor input Schema

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

Each entry is { name, website, trustpilotDomain, g2Url, capterraUrl, appStoreId, appStoreUrl, googlePlayId, googlePlayUrl }. Only 'name' is required — 'website' is enough for Trustpilot, and app ids are looked up from the name when omitted.

## `sources` (type: `array`):

Which review sources to read. G2 and Capterra are off by default: both block automated traffic aggressively, so selecting them usually returns a source error rather than reviews.

## `countries` (type: `array`):

Storefronts to read for the App Store and Google Play, as ISO-2 codes. Each storefront has its own reviews, so adding sa/ae/eg is how you get Gulf and Egyptian feedback.

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

Keep only reviews in these languages (ISO-639-1, e.g. en, ar). Leave empty for all.

## `lastNDays` (type: `integer`):

Ignore reviews older than this. Reviews with no date are kept, so a source that omits dates is not silently dropped.

## `minRating` (type: `integer`):

Keep only reviews at or above this rating, on the normalized 1-5 scale.

## `maxRating` (type: `integer`):

Keep only reviews at or below this rating. Set to 2 to collect complaints only.

## `maxReviewsPerSource` (type: `integer`):

Stop after this many reviews per target per source. This is the main control on cost.

## `includeCompanyReplies` (type: `boolean`):

Include the company's public reply to a review where the source publishes one.

## `aiInsights` (type: `boolean`):

Turn the collected reviews into themes, pain points, praise, feature requests, competitor mentions and suggested actions. Billed per batch of 10 reviews analyzed.

## `insightsLanguage` (type: `string`):

Language for the AI insights. 'ar' produces Modern Standard Arabic; review quotes stay in the language they were written in.

## `emitChangesOnly` (type: `boolean`):

Return only what is new since the last run under the same tracking ID: new reviews, negative reviews, rating drops and newly added company replies. Off = return the reviews themselves.

## `trackingId` (type: `string`):

Name of this watch. Required when 'Emit alerts only' is on. Snapshots are stored under this key in the 'review-intel-state' key-value store.

## `emitBaselineAsNew` (type: `boolean`):

On the first run for a tracking ID, report every review as new. Off = the first run records a baseline silently so your first alert is a real one.

## `negativeAlertMaxRating` (type: `integer`):

A new review at or below this rating also raises a separate negative\_review alert — the one you route to a human.

## `ratingDropThreshold` (type: `number`):

Raise a rating\_drop alert when a source's average rating falls by at least this much since the last run.

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

How many target x source pairs are fetched in parallel.

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

Proxies for the requests. Datacenter is enough for the App Store and Google Play; Trustpilot often needs residential.

## Actor input object example

```json
{
  "targets": [
    {
      "name": "Notion",
      "website": "https://notion.so",
      "appStoreId": "1232780281",
      "googlePlayId": "notion.id"
    },
    {
      "name": "Slack",
      "website": "https://slack.com",
      "appStoreId": "618783545",
      "googlePlayId": "com.Slack"
    }
  ],
  "sources": [
    "trustpilot",
    "appstore",
    "googleplay"
  ],
  "countries": [
    "us",
    "gb",
    "sa",
    "ae",
    "eg"
  ],
  "lastNDays": 90,
  "maxReviewsPerSource": 200,
  "includeCompanyReplies": true,
  "aiInsights": false,
  "insightsLanguage": "en",
  "emitChangesOnly": false,
  "emitBaselineAsNew": false,
  "negativeAlertMaxRating": 2,
  "ratingDropThreshold": 0.3,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Reviews, per-source summaries, AI insights and change-mode alerts, told apart by the 'itemType' field.

## `state` (type: `string`):

Review ids and average ratings seen per target and source under each tracking ID, so the next run can raise alerts for what is new. One record per tracking ID.

## `summary` (type: `string`):

Sources checked and failed, reviews found, alerts by type, model cost for AI insights and the charged-event tally.

# 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": [
        {
            "name": "Notion",
            "website": "https://notion.so",
            "appStoreId": "1232780281",
            "googlePlayId": "notion.id"
        },
        {
            "name": "Slack",
            "website": "https://slack.com",
            "appStoreId": "618783545",
            "googlePlayId": "com.Slack"
        }
    ],
    "sources": [
        "trustpilot",
        "appstore",
        "googleplay"
    ],
    "countries": [
        "us",
        "gb",
        "sa",
        "ae",
        "eg"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("almoutasem_nabil/review-intelligence").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": [
        {
            "name": "Notion",
            "website": "https://notion.so",
            "appStoreId": "1232780281",
            "googlePlayId": "notion.id",
        },
        {
            "name": "Slack",
            "website": "https://slack.com",
            "appStoreId": "618783545",
            "googlePlayId": "com.Slack",
        },
    ],
    "sources": [
        "trustpilot",
        "appstore",
        "googleplay",
    ],
    "countries": [
        "us",
        "gb",
        "sa",
        "ae",
        "eg",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("almoutasem_nabil/review-intelligence").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": [
    {
      "name": "Notion",
      "website": "https://notion.so",
      "appStoreId": "1232780281",
      "googlePlayId": "notion.id"
    },
    {
      "name": "Slack",
      "website": "https://slack.com",
      "appStoreId": "618783545",
      "googlePlayId": "com.Slack"
    }
  ],
  "sources": [
    "trustpilot",
    "appstore",
    "googleplay"
  ],
  "countries": [
    "us",
    "gb",
    "sa",
    "ae",
    "eg"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call almoutasem_nabil/review-intelligence --silent --output-dataset

```

## MCP server setup

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

```

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/MKEaOPSbeiAb2hTIt/builds/K3Uc5wvvTPMRklyRx/openapi.json
