# Competitor Review Intelligence – G2, Trustpilot & Capterra (`conceivable_extension/competitor-review-intelligence`) Actor

Scrapes G2, Trustpilot, and Capterra reviews and applies AI aspect-based sentiment analysis, classifying feedback by pricing, UX, support, integrations, and performance. Detects churn signals and competitor-switching intent at $0.015 per classified review.

- **URL**: https://apify.com/conceivable\_extension/competitor-review-intelligence.md
- **Developed by:** [joseph fadero](https://apify.com/conceivable_extension) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 review ai classifications

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Competitor Review Intelligence – G2, Trustpilot, Capterra & Bol.com

Turn competitor reviews into structured competitive intelligence. Which features drive 1-star ratings? Who are customers switching to? Which product gaps are your competitors failing to fix? AI-classified at $0.015/review instead of $300/month.

### Features

- **Multi-platform scraping** — G2, Trustpilot, Capterra, and Bol.com in one run
- **AI aspect classification** — GPT-4o-mini classifies each review by feature: pricing, UX, support, integrations, performance, onboarding, reliability (multilingual — works on Bol.com's Dutch/French reviews with no special handling)
- **Churn signal detection** — flags reviews with explicit competitor-switching intent ("moved to", "switching to", "migrated to")
- **Competitor name extraction** — identifies which alternatives reviewers mention
- **Star rating filters** — focus on 1-2 star reviews for product gap research, 4-5 star for praise mapping

### Inputs

| Field | Default | Description |
|-------|---------|-------------|
| `products` | `[]` | Array of `{name, g2Url?, trustpilotUrl?, capterraUrl?}` — required unless `bolComConfig` is set |
| `platforms` | `["g2","trustpilot"]` | Platforms to scrape. `sources` is an alias (below), taking precedence if both set |
| `sources` | — | Alias for `platforms`; include `"bol_com"` here to enable Bol.com |
| `bolComConfig` | — | `{ productUrls?: string[], searchKeyword?: string, maxReviewsPerProduct?: number }` — at least one of `productUrls`/`searchKeyword` needed |
| `maxReviewsPerProduct` | 100 | Max reviews per product per platform |
| `classifyAspects` | true | Enable AI aspect classification |
| `openaiApiKey` | — | Required for AI classification |
| `detectChurnSignals` | true | Flag competitor-switch mentions |
| `filterMinRating` | 1 | Minimum star rating to process |
| `filterMaxRating` | 5 | Maximum star rating to process |

### Output fields

Each review record includes: `productName`, `platform`, `rating`, `body`, `aspects[]`, `primaryComplaint`, `primaryPraise`, `hasChurnSignal`, `churnReason`, `mentionedAlternatives`, `overallSentiment`, `sentimentScore`, `reviewerName`, `reviewerRole`. Bol.com reviews additionally carry `pros[]`, `cons[]`, `language` (`"nl"`/`"fr"`), and `priceAtReview`.

### Pricing (PPE)

- `run-started` — £0.05 per run
- `review-scraped` — £0.003 per raw review collected
- `review-classified` — £0.015 per AI-classified review
- `churn-signal-detected` — £0.025 per churn-intent review

### Notes

G2 uses bot protection (Datadome). For best results, configure Apify residential proxies in your account settings. Trustpilot is scraped via the `memo23/trustpilot-scraper-ppe` sub-actor — live-verified during the Bol.com addendum build (this actor had never actually been run live before; two real pre-existing bugs were caught and fixed in the process: a missing `ApifyClient` token, and a reference to a Trustpilot sub-actor slug — `nikita.rol/trustpilot-reviews-scraper` — that no longer exists on the Apify Store).

### Bol.com — known limitation (read before relying on this source)

Bol.com is protected by Akamai's TLS-fingerprint-level bot detection (JA3/JA4) — a layer below the browser that Crawlee's fingerprint spoofing (which successfully passes the Cloudflare-class JS challenges used by other sources in this account's actors) cannot touch. Every request currently receives an immediate 403 with no challenge page.

Two real proxy configurations were tried live on the deployed platform (this Apify plan disables local proxy testing entirely):

1. An explicit `RESIDENTIAL` proxy group — this account has 0 available RESIDENTIAL sessions; still 403 on every retry.
2. Automatic/default proxy selection (in case it routes through the account's enabled `PROXY_UNBLOCKER` feature) — still 403 on every retry.

**What this means in practice**: Bol.com scraping is built and wired in end-to-end (search, bulk product URLs, JSON-LD + Bazaarvoice review parsing, NL/FR language detection, price extraction), but currently returns 0 reviews on this account, because Bol.com's page HTML is never actually reachable. This is not a fake or partial feature — it's real, correct extraction logic (built from Bol.com's confirmed real schema.org JSON-LD and Bazaarvoice CSS conventions) that will work the moment page access is available, without further code changes — e.g. a RESIDENTIAL proxy allocation, the correct `PROXY_UNBLOCKER` group name (undocumented, not found), or Bol.com's official partner API (real, confirmed via their CSP header, but requires a registered partner/seller account).

Existing G2, Trustpilot, and Capterra scraping is unaffected by this — verified unchanged.

# Actor input Schema

## `products` (type: `array`):

Product profile URLs or names to scrape reviews for. Each entry can include g2Url, trustpilotUrl, and/or capterraUrl.

## `platforms` (type: `array`):

Which review platforms to scrape. Valid values: g2, trustpilot, capterra, bol\_com. `sources` (below) is an alias for this field using the addendum's own naming — either works, `sources` takes precedence if both are set.

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

Alias for `platforms`, matching the addendum's own field name. Include "bol\_com" here (and configure bolComConfig below) to enable Bol.com.

## `bolComConfig` (type: `object`):

Required to scrape Bol.com. { productUrls: string\[], searchKeyword: string, maxReviewsPerProduct: number }. Either productUrls or searchKeyword (or both) can be set — searchKeyword pulls real product URLs from a live Bol.com search first. KNOWN LIMITATION (see README): Bol.com's real Akamai TLS-fingerprint bot protection currently blocks every proxy option available on this Apify account (tried live: RESIDENTIAL group and automatic/default selection, both 403). The extraction logic is real and correct but cannot currently reach live Bol.com pages — see README for full details and what would unblock this.

## `maxReviewsPerProduct` (type: `integer`):

Maximum number of reviews to collect per product per platform.

## `classifyAspects` (type: `boolean`):

Use GPT-4o-mini to extract which specific features each review praises or complains about.

## `openaiApiKey` (type: `string`):

Required when AI Aspect Classification is enabled. Your OpenAI API key for GPT-4o-mini calls.

## `detectChurnSignals` (type: `boolean`):

Flag reviews that mention switching to a competitor or cancelling due to specific issues.

## `filterMinRating` (type: `integer`):

Only process reviews at or above this star rating (1–5). Set to 1 to include all.

## `filterMaxRating` (type: `integer`):

Only process reviews at or below this star rating (1–5). Set to 5 to include all.

## Actor input object example

```json
{
  "products": [
    {
      "name": "Competitor Product",
      "g2Url": "https://www.g2.com/products/competitor/reviews",
      "trustpilotUrl": "https://www.trustpilot.com/review/competitor.com",
      "capterraUrl": "https://www.capterra.com/p/123456/competitor/"
    }
  ],
  "platforms": [
    "g2",
    "trustpilot"
  ],
  "maxReviewsPerProduct": 100,
  "classifyAspects": true,
  "detectChurnSignals": true,
  "filterMinRating": 1,
  "filterMaxRating": 5
}
```

# Actor output Schema

## `resultsDatasetUrl` (type: `string`):

Competitor reviews from G2, Trustpilot, Capterra and Bol.com, AI-classified by feature aspect (pricing, UX, support, integrations, performance, onboarding, reliability) with churn-signal and competitor-mention flags, produced by this run.

# 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 = {
    "products": [
        {
            "name": "Competitor Product",
            "g2Url": "https://www.g2.com/products/competitor/reviews",
            "trustpilotUrl": "https://www.trustpilot.com/review/competitor.com",
            "capterraUrl": "https://www.capterra.com/p/123456/competitor/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("conceivable_extension/competitor-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 = { "products": [{
            "name": "Competitor Product",
            "g2Url": "https://www.g2.com/products/competitor/reviews",
            "trustpilotUrl": "https://www.trustpilot.com/review/competitor.com",
            "capterraUrl": "https://www.capterra.com/p/123456/competitor/",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("conceivable_extension/competitor-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 '{
  "products": [
    {
      "name": "Competitor Product",
      "g2Url": "https://www.g2.com/products/competitor/reviews",
      "trustpilotUrl": "https://www.trustpilot.com/review/competitor.com",
      "capterraUrl": "https://www.capterra.com/p/123456/competitor/"
    }
  ]
}' |
apify call conceivable_extension/competitor-review-intelligence --silent --output-dataset

```

## MCP server setup

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