# G2 Reviews Scraper — SaaS Ratings, Switching & Monitor (`crawloop/g2-reviews-scraper`) Actor

Scrape G2 product reviews into JSON: star ratings, pros/cons, switching, reviewer role and company size. Monitor new reviews with webhooks. A G2 API alternative for Python, Node.js, and MCP.

- **URL**: https://apify.com/crawloop/g2-reviews-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** AI, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.49 / 1,000 g2 reviews

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

Learn more: https://docs.apify.com/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

## G2 Reviews Scraper — SaaS Ratings, Switching & Monitor

> Unofficial tool for publicly accessible G2 product and review pages. G2 and related names are trademarks of their respective owners. Not affiliated with, sponsored by, or endorsed by G2.com, Inc. For informational, research, and competitive-intelligence use only. Respect applicable terms of use and law.

**G2 Reviews Scraper** ◄── you are here

Scrape **G2 product reviews** into structured JSON: **star ratings**, **pros/cons**, **switching data**, **reviewer role**, **company size**, and an LLM-ready markdown field. Paste **product slugs** or **review / seller / category / search URLs**. Run **incremental monitor** mode so scheduled jobs emit only **new reviews and rating deltas**. A practical **G2 API alternative** — call from **Python**, **Node.js**, **cURL**, or **Apify MCP**.

Ideal for **SaaS competitive intel**, **win-loss research**, **sales battlecards**, **product ops**, and **review monitoring**.

> **Crawloop Reviews Suite** — B2B G2 + consumer Trustpilot + employer Glassdoor.

| G2 (SaaS product reviews) | Trustpilot (consumer reputation) | Glassdoor (employer intel) |
| :--- | :--- | :--- |
| **G2 Reviews Scraper** ◄── you are here | [Trustpilot Scraper](https://apify.com/crawloop/trustpilot-scraper) | [Glassdoor Scraper](https://apify.com/crawloop/glassdoor-scraper) |

### When to use this Actor

- You need a **G2 reviews scraper** for one or many products as JSON
- You want **switching / pros / cons** fields for battlecards without cleaning HTML
- You schedule **new-review monitoring** with webhooks instead of re-downloading full histories
- You want a **G2 API alternative** from Python, Node.js, or an MCP / AI assistant
- You map a **G2 category or search** first, then pull reviews for the shortlist

### When not to use this Actor

- **Consumer Trustpilot reviews** — use [Trustpilot Scraper](https://apify.com/crawloop/trustpilot-scraper)
- **Employer reviews / salaries / jobs** — use [Glassdoor Scraper](https://apify.com/crawloop/glassdoor-scraper)
- G2 vendor portal, authenticated surveys, or writing reviews — public pages only
- Guaranteed tens of thousands of reviews per product in one cheap HTTP run — G2 uses DataDome; this Actor uses a stealth browser + residential proxies

### Modes

| Mode | What it does |
| :--- | :--- |
| `reviews` | Product reviews (optional product profile + alternatives) |
| `products` | Search or category catalog rows |
| `monitor` | Named KV watermarks; emit only new reviews and rating/count deltas |

### Key features

- **Reviews + catalog + monitor** in one Actor — product URLs/slugs, search, category, seller pages
- **Typed dataset rows** — `product`, `review`, `alternative`, `monitor_event`
- **Battlecard fields** — likes/dislikes, problems solved, recommendations, switched-from
- **Star / date / keyword filters** — `publishedAfter` accepts `2026-08-01` or `7 days`
- **Incremental monitor** — named KV watermarks, early-stop, Slack/Discord/Telegram alerts
- **LLM-ready `markdownContent`** per review (omit with compact mode)
- **Camoufox + US residential** — DataDome bypass; no G2 login

### Input

| Parameter | Description |
| :--- | :--- |
| `mode` | `reviews` / `products` / `monitor` |
| `startUrls` / `productSlugs` | Review pages or slugs (`slack`) |
| `searchQuery` / `categorySlug` | Catalog discovery (products mode) |
| `maxReviews` / `maxProducts` / `maxItems` | Caps |
| `sortOrder` | `newest` / `helpful` / `highest` / `lowest` |
| `starRatings` / `publishedAfter` / `reviewSearchQuery` | Filters |
| `includeProductProfile` / `includeAlternatives` | Extra row kinds |
| `monitorStoreName` / `monitorBaselineOnly` / `earlyStopAfterKnown` | Monitor KV |
| `webhookUrl` / Telegram fields | Alerts |
| `proxyConfiguration` | Use **Apify Residential** (US) |

#### Example — recent Slack reviews

```json
{
  "mode": "reviews",
  "productSlugs": ["slack"],
  "maxReviews": 100,
  "sortOrder": "newest",
  "includeProductProfile": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

#### Example — only 1–2 star reviews since last week

```json
{
  "mode": "reviews",
  "startUrls": [{ "url": "https://www.g2.com/products/jira/reviews" }],
  "sortOrder": "lowest",
  "starRatings": ["1", "2"],
  "publishedAfter": "7 days",
  "maxReviews": 200
}
```

#### Example — monitor baseline then schedule

```json
{
  "mode": "monitor",
  "productSlugs": ["slack", "microsoft-teams"],
  "monitorStoreName": "g2-reviews-monitor",
  "monitorBaselineOnly": true,
  "earlyStopAfterKnown": 5,
  "notifyOnNewReviews": true,
  "notifyOnNegativeReviewsOnly": true
}
```

After the baseline run, set `monitorBaselineOnly` to `false`. Schedule hourly or daily — later runs emit only new reviews and rating/count deltas.

#### Example — category catalog

```json
{
  "mode": "products",
  "categorySlug": "crm",
  "maxProducts": 50
}
```

### Output

Each dataset row has a `type` field: `product`, `review`, `alternative`, or `monitor_event`.

| Field | Description |
| :--- | :--- |
| `type` | Row kind |
| `productSlug` / `productName` | G2 product identity |
| `reviewId` | Stable review id |
| `starRating` | 1–5 score |
| `date` | Publish date (`YYYY-MM-DD`) |
| `title` / `text` | Headline and full body |
| `likes` / `dislikes` | Pros / cons when present |
| `problemsSolved` / `recommendations` | Extra survey answers |
| `switchedFrom` / `switchedReason` | Prior product and why |
| `reviewerName` / `reviewerTitle` | Reviewer |
| `companySize` / `reviewerIndustry` | Firmographics |
| `reviewUrl` | Canonical review URL when G2 exposes it |
| `markdownContent` | LLM-ready block (omit with `compact`) |
| `reviewCount` / `vendorName` / `categoryNames` | Product-row fields |

```json
{
  "type": "review",
  "reviewId": "1234567",
  "productSlug": "slack",
  "productName": "Slack",
  "starRating": 4.5,
  "date": "2026-05-12",
  "title": "Best team chat we have used",
  "likes": "Channels keep work organized; integrations with Jira are seamless.",
  "dislikes": "Notification volume is high until you tune it.",
  "switchedFrom": "Microsoft Teams",
  "reviewerName": "Sarah M.",
  "reviewerTitle": "Marketing Manager",
  "companySize": "Mid-Market (51-1000 emp.)",
  "reviewUrl": "https://www.g2.com/products/slack/reviews/slack-review-1234567"
}
```

### Use cases

| Use case | What you get |
| :--- | :--- |
| **Competitor battlecards** | Pros/cons + switched-from on your product and 3 rivals |
| **Detractor mining** | 1–2★ sort + negative-only webhooks |
| **Win-loss research** | Switching reasons and firmographics (role, size, industry) |
| **RAG / LLM pipelines** | `markdownContent` chunks with product/rating metadata |
| **Scheduled monitoring** | Only new reviews after a KV baseline |
| **Category mapping** | Top products in a G2 category before a review pull |

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('crawloop/g2-reviews-scraper').call({
  mode: 'reviews',
  productSlugs: ['slack'],
  maxReviews: 100,
  sortOrder: 'newest',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token="YOUR_APIFY_TOKEN")
run = client.actor("crawloop/g2-reviews-scraper").call(
    run_input={
        "mode": "reviews",
        "productSlugs": ["hubspot"],
        "maxReviews": 200,
        "sortOrder": "helpful",
    }
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("title"), item.get("starRating"))
```

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/crawloop~g2-reviews-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"products","searchQuery":"CRM","maxProducts":25}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call `crawloop/g2-reviews-scraper`.

Example prompts:

- "Run G2 Reviews Scraper for Slack, max 50 newest reviews, and return stars, likes, dislikes, and switchedFrom as JSON"
- "Scrape 1- and 2-star Jira G2 reviews from the last 30 days and summarize the top complaints"
- "Chain G2 Reviews Scraper for HubSpot then Trustpilot Scraper for hubspot.com and compare B2B vs consumer sentiment"

### Suite next step

After a G2 pull, run [Trustpilot Scraper](https://apify.com/crawloop/trustpilot-scraper) on the same vendor domain for consumer reputation, or [Glassdoor Scraper](https://apify.com/crawloop/glassdoor-scraper) for employer-brand context on the vendor.

### FAQ

**Do I need a G2 login or official API key?** No. The Actor reads public product and review pages only. G2’s partner API is separate and not required.

**Can I scrape G2 reviews with Python or Node.js?** Yes. Use the Apify client snippets above, or call the Actor from an MCP / AI assistant.

**Why residential proxies?** G2 sits behind DataDome. Datacenter IPs usually get a CAPTCHA. Use Apify Residential (US).

**How is this different from other G2 scrapers?** Monitor mode with KV watermarks and webhooks, switching/pros/cons fields, catalog + reviews in one Actor, and a suite chain to Trustpilot and Glassdoor.

**Can I scrape a whole category?** Yes — `mode=products` with `categorySlug` or `searchQuery`, then feed the slugs back in `reviews` mode.

**Does monitor mode re-download the full history every run?** No. After a baseline, later runs emit new reviews and rating/count deltas and can stop early once known reviews appear.

### Related Actors

- [Trustpilot Scraper](https://apify.com/crawloop/trustpilot-scraper)
- [Glassdoor Scraper](https://apify.com/crawloop/glassdoor-scraper)

# Actor input Schema

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

reviews = product reviews (and optional product row); products = search/category catalog; monitor = incremental new reviews + rating deltas.

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

G2 product, reviews, seller, category, or search URLs. Bare slugs such as slack are also accepted.

## `productSlugs` (type: `array`):

G2 product slugs (slack) or full product/review URLs. Used in reviews and monitor modes.

## `searchQuery` (type: `string`):

Keyword for G2 product search (products mode). Example: CRM, project management.

## `categorySlug` (type: `string`):

G2 category slug (e.g. crm, project-management). Used in products mode.

## `maxReviews` (type: `integer`):

Cap reviews collected per product. 0 = until pages run out (still bounded by maxPages).

## `maxProducts` (type: `integer`):

Cap product catalog rows in products/search/category mode.

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

Hard cap on pushed dataset rows (all types). 0 = unlimited.

## `maxPages` (type: `integer`):

Safety cap on review or catalog pages per target.

## `sortOrder` (type: `string`):

G2 review sort. newest is best for monitoring and publishedAfter.

## `starRatings` (type: `array`):

Only keep these star ratings (1–5). Empty = all stars.

## `publishedAfter` (type: `string`):

Keep reviews on/after this date (YYYY-MM-DD) or period (7 days, 2 weeks, 1 month). Newest-first pagination stops when older reviews appear.

## `reviewSearchQuery` (type: `string`):

Keep reviews whose title/body/pros/cons contain all of these words (AND).

## `verifiedOnly` (type: `boolean`):

Keep reviews tagged Validated Reviewer or Verified Current User.

## `includeProductProfile` (type: `boolean`):

In reviews mode, also push a product row (rating, review count, categories).

## `includeAlternatives` (type: `boolean`):

Also scrape the product alternatives / competitors listing.

## `compact` (type: `boolean`):

Drop markdownContent and long optional fields (token-efficient for MCP / LLM pipelines).

## `monitorStoreName` (type: `string`):

Named Key-Value Store for incremental watermarks (per-product seen review IDs).

## `monitorBaselineOnly` (type: `boolean`):

First run: seed KV fingerprints and review IDs without emitting deltas / webhooks.

## `resetMonitorState` (type: `boolean`):

Clear MONITOR\_STATE in the named store before this run.

## `earlyStopAfterKnown` (type: `integer`):

In monitor mode, stop pagination after this many consecutive already-seen reviews (newest-first).

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

Slack / Discord / custom HTTPS endpoint for monitor alerts (JSON POST).

## `telegramToken` (type: `string`):

Optional Telegram bot token for monitor alerts.

## `telegramChatId` (type: `string`):

Telegram chat/user ID for alerts (requires token).

## `notifyOnNewReviews` (type: `boolean`):

Send webhook/Telegram when a new review appears (monitor mode).

## `notifyOnNegativeReviewsOnly` (type: `boolean`):

If enabled, new-review notifications fire only for 1–2 star reviews.

## `notifyOnRatingChange` (type: `boolean`):

Send webhook/Telegram when the product fingerprint (stars or review count) changes.

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

DataDome blocks datacenter IPs. Use Apify Residential proxies (US).

## Actor input object example

```json
{
  "mode": "reviews",
  "startUrls": [
    {
      "url": "https://www.g2.com/products/slack/reviews"
    }
  ],
  "productSlugs": [
    "slack"
  ],
  "maxReviews": 100,
  "maxProducts": 25,
  "maxItems": 0,
  "maxPages": 50,
  "sortOrder": "newest",
  "verifiedOnly": false,
  "includeProductProfile": true,
  "includeAlternatives": false,
  "compact": false,
  "monitorStoreName": "g2-reviews-monitor",
  "monitorBaselineOnly": false,
  "resetMonitorState": false,
  "earlyStopAfterKnown": 5,
  "notifyOnNewReviews": true,
  "notifyOnNegativeReviewsOnly": false,
  "notifyOnRatingChange": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

Default dataset items.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.g2.com/products/slack/reviews"
        }
    ],
    "productSlugs": [
        "slack"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/g2-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.g2.com/products/slack/reviews" }],
    "productSlugs": ["slack"],
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/g2-reviews-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.g2.com/products/slack/reviews"
    }
  ],
  "productSlugs": [
    "slack"
  ]
}' |
apify call crawloop/g2-reviews-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/2mNq5Pr9ZJauPh4xu/builds/D6maWaQkRVzo7tDDA/openapi.json
