# G2 Scraper - Reviews, Products, Analytics & Discussions (`kaix/g2-scraper`) Actor

🔥 ~$0.05/1K reviews 🔥 Scrape G2.com software reviews, products, analytics, comparisons, and discussions. Faceted filtering, facet-value discovery, 72 review fields, NLP sentiment, switching intelligence.

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

## Pricing

from $0.04 / 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.
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 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

## G2 Scraper

Scrape G2.com software reviews, products, analytics, comparisons, and discussions. Rich faceted filtering (primary region, review source, response type, sentiment themes, discount), facet-value discovery, 72 review fields, NLP sentiment themes, and switching intelligence. No proxy needed.

### Why use this scraper?

- Scrape a product's full review history (`maxReviewsPerProduct: 0` for no limit), no anti-bot bypass needed.
- Structured pros/cons/benefits parsed from each review.
- Per-dimension ratings: ease of use, setup, support, security, and more.
- NLP-extracted sentiment themes (what users love/hate).
- Competitive switching intelligence (what products users switched from and why).
- Faceted filtering: narrow reviews by primary region, review source, response type, loved/hated/switching themes, and discount.
- Facet-value discovery: list the valid values for any text facet before filtering.
- Analytics mode with aggregations, percentiles, and significant terms.
- Side-by-side product comparisons in a single request.
- Q&A discussion threads per product.

### Use cases

- Compare competitors by sentiment, ratings, and switching patterns.
- Feed structured review data into NLP / AI pipelines.
- Track review trends over time for market research.
- Segment reviews by region, company size, review source, or sentiment theme.
- Find products by category, vendor, or keyword search.
- Search across all reviews for specific topics.

### How to use

#### Scrape reviews for a product

```json
{
  "products": ["https://www.g2.com/products/slack/reviews"]
}
````

#### Search for products and scrape their reviews

```json
{
  "search": "project management",
  "maxProducts": 5,
  "maxReviewsPerProduct": 50
}
```

#### Browse a category

```json
{
  "category": "CRM",
  "maxProducts": 10,
  "maxReviewsPerProduct": 20
}
```

#### Browse by vendor

```json
{
  "vendor": "Salesforce",
  "maxProducts": 5,
  "maxReviewsPerProduct": 10
}
```

#### Compare products side-by-side

```json
{
  "compare": ["slack", "clickup", "jira"]
}
```

#### Get analytics (no individual reviews)

```json
{
  "products": ["slack"],
  "analytics": true
}
```

#### Global review search across all products

```json
{
  "reviewSearch": "terrible customer support",
  "maxReviews": 50
}
```

#### Find similar reviews

```json
{
  "similarTo": "The API was difficult to integrate and documentation was poor",
  "maxReviews": 20
}
```

#### Filter by date, rating, and company size

```json
{
  "products": ["slack"],
  "dateFrom": "2025-01-01",
  "ratings": ["1", "2"],
  "companySegment": ["enterprise"],
  "maxReviewsPerProduct": 100
}
```

#### Filter by facets (region, source, themes)

```json
{
  "products": ["slack"],
  "primaryRegions": ["Americas"],
  "sourceTypes": ["organic"],
  "responseTypes": ["video"],
  "maxReviewsPerProduct": 50
}
```

#### Discover valid facet values

Returns the distinct values for each facet to the `metadata` dataset, so you know what to pass to the facet filters above. No reviews are scraped in this mode.

```json
{
  "enumFields": ["source_type", "response_type"]
}
```

#### Search within reviews with highlights

```json
{
  "products": ["slack"],
  "reviewSearch": "customer support",
  "includeHighlights": true,
  "maxReviewsPerProduct": 20
}
```

#### Include Q\&A discussions

```json
{
  "products": ["slack"],
  "maxReviewsPerProduct": 10,
  "includeDiscussions": true
}
```

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `products` | string\[] | | Product URLs, slugs, or category URLs |
| `search` | string | | Find products by keyword |
| `category` | string | | Browse products by G2 category |
| `vendor` | string | | Browse products by vendor name |
| `compare` | string\[] | | Compare products side-by-side (analytics) |
| `maxProducts` | number | `10` | Max products in search/category/vendor mode |
| `sortBy` | select | `DATE_DESC` | `DATE_DESC`, `DATE_ASC`, `RATING_DESC`, `RATING_ASC`, `HELPFUL_DESC`, `G2_DEFAULT` |
| `ratings` | string\[] | `["1","2","3","4","5"]` | Filter by star rating; values `"1"`–`"5"` |
| `maxReviewsPerProduct` | number | `20` | Max reviews per product (0 = unlimited) |
| `companySegment` | string\[] | | `small_business`, `mid_market`, `enterprise` |
| `dateFrom` | string | | ISO date, reviews from this date |
| `dateTo` | string | | ISO date, reviews until this date |
| `primaryRegions` | select\[] | | `Americas`, `Asia Pacific`, `EMEA` |
| `sourceTypes` | string\[] | | Filter by how the review was collected; use `enumFields` to list valid values |
| `responseTypes` | string\[] | | Filter by review medium (e.g. `text`, `video`) |
| `loveThemes` | string\[] | | Filter by themes reviewers praised |
| `hateThemes` | string\[] | | Filter by themes reviewers criticized |
| `switchingThemes` | string\[] | | Filter by reasons reviewers switched products |
| `discounts` | string\[] | | Filter by reported discount |
| `reviewSources` | string\[] | | Filter by review source channel |
| `reviewSearch` | string | | Search within review text. Alone = global search |
| `similarTo` | string | | Find reviews similar to this text |
| `reviewIds` | string\[] | | Fetch specific reviews by ID |
| `maxReviews` | number | `100` | Max reviews for global/similar search |
| `enumFields` | select\[] | | Discover distinct values for facets; writes to the `metadata` dataset instead of scraping reviews |
| `analytics` | boolean | `false` | Return aggregation analytics instead of reviews |
| `collapseByProduct` | boolean | `false` | One review per product in global search |
| `includeNonPublic` | boolean | `false` | Include non-public/rejected reviews |
| `includeDiscussions` | boolean | `false` | Fetch Q\&A discussion threads per product |
| `includeHighlights` | boolean | `true` | Highlight matching text in search results |

At least one input mode is required (`products`, `search`, `category`, `vendor`, `reviewSearch`, `similarTo`, `reviewIds`, `compare`, `enumFields`, or `analytics`). Filters apply to all matched reviews.

### Output

#### Datasets

| Dataset | When | Content |
|---------|------|---------|
| `reviews` (default) | Most modes | Individual review records |
| `products` | Product-based modes | Product profiles |
| `analytics` | `analytics` or `compare` mode | Aggregation statistics |
| `discussions` | `includeDiscussions: true` | Q\&A threads |
| `metadata` | `enumFields` mode | Distinct facet values |

#### Review fields

```json
{
  "id": "13038740",
  "productId": 3437,
  "productName": "Slack",
  "reviewUrl": "https://www.g2.com/products/slack/reviews/13038740",
  "title": "One-Click Integrations That Just Work for slack",
  "pros": "Integration with other apps has to be 1 click",
  "cons": "UI when you send the messages. The typing window should be adjustable",
  "benefits": "connect and chatting with the team One-Click Integrations That Just Work for slack",
  "rawText": "Integration with other apps has to be 1 click\nUI when you send the messages. The typing window should be adjustable\nconnect and chatting with the team One-Click Integrations That Just Work for slack",
  "responseType": "text",
  "nps": 8,
  "npsScore": 4,
  "easeOfUse": 5,
  "easeOfSetup": 5,
  "easeOfAdmin": 5,
  "easeOfDoingBusinessWith": 4,
  "meetsRequirements": 5,
  "qualityOfSupport": 3,
  "securityConfidence": 3,
  "securityImportance": 7,
  "direction": null,
  "userName": "Sameer G.",
  "country": "India",
  "region": "Asia",
  "primaryRegion": "Asia Pacific",
  "companySegment": 180,
  "companySegmentLabel": "Mid-Market (51-1000 emp.)",
  "industry": 313,
  "industryLabel": "Information Technology and Services",
  "role": 6,
  "roleLabel": "Consultant",
  "loveTheme": null,
  "loveThemeHumanized": null,
  "loveThemeParentHumanized": null,
  "hateTheme": null,
  "hateThemeHumanized": null,
  "hateThemeParentHumanized": null,
  "switchedFromOtherProduct": "unknown",
  "switchedFromProductIds": null,
  "switchedReason": null,
  "switchingThemes": null,
  "switchingThemesNested": null,
  "submittedAt": "2026-06-26T17:10:48.781-05:00",
  "publishedAt": "2026-06-26T19:30:00.900-05:00",
  "reviewSource": "user_profile",
  "sourceType": "user_profile",
  "helpful": 0,
  "englishAvailable": true,
  "contractLength": null,
  "discount": null,
  "price": 5,
  "status": "approved",
  "isPublic": true,
  "published": true,
  "productPaidProfile": false,
  "productIds": [3437],
  "categoryIds": [2174, 2360, 2363],
  "defaultSort": 8.525176115868225,
  "templateKeyword": "react",
  "videoReviewSubmittedAt": null,
  "editionIds": [],
  "expertiseIds": [],
  "serviceLocation": null,
  "contractLengthWeight": null,
  "discountWeight": null,
  "everApproved": true,
  "isInLimbo": false,
  "read": false,
  "reportable": true,
  "userUpdatedAt": "2026-06-26T17:10:48.965-05:00",
  "highlightedSnippets": null,
  "scrapedAt": "2026-06-28T06:00:34.982Z"
}
```

#### Analytics output

Aggregated over all of a product's reviews. `nps`/`easeOfUse`/etc. each carry `avg`, `stdDev`, `min`, `max`, and `count`; the full record also includes `easeOfSetup`, `easeOfAdmin`, `qualityOfSupport`, `meetsRequirements`, `easeOfDoingBusinessWith`, `securityConfidence`, `securityImportance`, `direction`, `topHateThemes`, `uniquelyHated`, and `bySourceType`. The theme, demographic, and `reviewsOverTime` arrays are trimmed below for brevity.

```json
{
  "productId": 3437,
  "productName": "Slack",
  "productSlug": "slack",
  "totalReviews": 20201,
  "totalHelpfulVotes": 69,
  "nps": { "avg": 9.211870699470323, "stdDev": 1.1668658162744323, "min": 0, "max": 10, "count": 20201 },
  "easeOfUse": { "avg": 6.549680122289532, "stdDev": 0.7953808393082141, "min": 1, "max": 7, "count": 17663 },
  "ratingDistribution": { "1": 40, "2": 93, "3": 468, "4": 3646, "5": 15954 },
  "npsPercentiles": { "p10": 8, "p25": 9, "p50": 10, "p75": 10, "p90": 10 },
  "uniqueCountries": 140,
  "uniqueIndustries": 145,
  "topLoveThemes": [
    { "theme": "Chat", "count": 3436, "sampleReviews": [{ "title": "Slack Review", "userName": "Hunter C.", "npsScore": 4 }] },
    { "theme": "Collaboration", "count": 2254, "sampleReviews": [{ "title": "\"Ping\" From Your Creative Side", "userName": "Daniel G.", "npsScore": 5 }] }
  ],
  "uniquelyLoved": [
    { "theme": "Chat", "score": 3.472215696777018, "count": 3436 },
    { "theme": "Collaboration", "score": 1.2096931571663356, "count": 2254 }
  ],
  "switchingReasons": [
    { "reason": "Ease of use", "count": 126 },
    { "reason": "Communication Features", "count": 108 }
  ],
  "bySegment": [
    { "code": 179, "label": "Small Business (50 or fewer emp.)", "count": 8191 },
    { "code": 180, "label": "Mid-Market (51-1000 emp.)", "count": 8141 },
    { "code": 181, "label": "Enterprise (>1000 emp.)", "count": 3516 }
  ],
  "byRegion": [
    { "region": "Americas", "count": 12760 },
    { "region": "Asia Pacific", "count": 4821 },
    { "region": "EMEA", "count": 2526 }
  ],
  "reviewsOverTime": [
    { "month": "2014-02", "count": 1 },
    { "month": "2026-06", "count": 73 }
  ]
}
```

#### Facet values output (`metadata` dataset)

```json
{
  "field": "source_type",
  "type": "enum_values",
  "values": [
    "ai_assisted_review", "api_collect", "g2_incentivized", "g2_nonincentivized",
    "g2gives", "influitive", "organic", "pop_up", "referral", "review_referral",
    "review_widget", "stale_reviews_callout", "thank_you_page", "un_survey",
    "unincentivized", "user_profile", "vendor", "vendor_nonincentivized",
    "vendor_self", "vendor_self_nonincentivized", "vendor_self_sendoso"
  ],
  "count": 21
}
```

### Limitations

- Reviewer job titles and avatar URLs are not available.
- `industry` and `role` are returned as numeric category codes with a human-readable label for common values only; they are not available as filters.
- `country` and `region` are not available as filters because their values are not normalized across languages. Use `primaryRegion` (`Americas` / `Asia Pacific` / `EMEA`) for consistent geography filtering.
- `similarTo` returns at most 1,000 reviews per run (a single relevance-ranked fetch; it does not paginate).
- A product's `reviewCount` reflects G2's total across all reviews; review scraping and analytics return only public, approved reviews, so their counts are typically lower.
- Some reviews have unstructured text (no clear pros/cons/benefits separation).

# Actor input Schema

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

G2 product URLs (e.g. https://www.g2.com/products/slack/reviews) or just slugs (e.g. slack). Also accepts category URLs.

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

Maximum number of reviews to scrape per product. Set to 0 for no limit (all reviews).

## `sortBy` (type: `string`):

How to sort reviews.

## `ratings` (type: `array`):

Only include reviews with these star ratings. Leave empty for all ratings.

## `companySegment` (type: `array`):

Filter by company size.

## `dateFrom` (type: `string`):

ISO date, only reviews submitted on or after this date.

## `dateTo` (type: `string`):

ISO date, only reviews submitted on or before this date.

## `primaryRegions` (type: `array`):

Filter by reviewer primary region.

## `sourceTypes` (type: `array`):

Filter by how the review was collected (e.g. organic, g2\_incentivized). Discover values via enumFields: source\_type.

## `responseTypes` (type: `array`):

Filter by review medium (e.g. text, video). Discover values via enumFields: response\_type.

## `loveThemes` (type: `array`):

Filter by what reviewers liked (e.g. Automation, Analytics). Discover values via enumFields: love\_theme\_humanized.

## `hateThemes` (type: `array`):

Filter by what reviewers disliked. Discover values via enumFields: hate\_theme\_humanized.

## `switchingThemes` (type: `array`):

Filter by why reviewers switched products. Discover values via enumFields: switching\_theme\_humanized.

## `discounts` (type: `array`):

Filter by reported discount. Discover values via enumFields: discount.

## `reviewSources` (type: `array`):

Filter by review source channel. Discover values via enumFields: review\_source.

## `reviewSearch` (type: `string`):

Full-text search within review text. When used without products, searches globally across all products.

## `search` (type: `string`):

Find products by keyword search (e.g. 'project management').

## `category` (type: `string`):

Find products in a G2 category (e.g. 'CRM', 'Project Management').

## `vendor` (type: `string`):

Find all products by vendor name (e.g. 'Salesforce').

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

Maximum products to scrape in search/category/vendor mode.

## `compare` (type: `array`):

Compare products side-by-side with analytics (e.g. \['slack', 'teams', 'discord']).

## `analytics` (type: `boolean`):

Return aggregation analytics per product instead of individual reviews.

## `enumFields` (type: `array`):

Return the distinct values for these review facets (saved to the metadata dataset) instead of scraping reviews. Use the values to populate the reviewer-facet filters.

## `similarTo` (type: `string`):

Find reviews similar to this text.

## `reviewIds` (type: `array`):

Fetch specific reviews by their G2 review ID.

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

Max total reviews for global search or similar mode. Set to 0 for no limit.

## `collapseByProduct` (type: `boolean`):

Deduplicate global search results to one review per product.

## `includeDiscussions` (type: `boolean`):

Also fetch Q\&A discussion threads per product.

## `includeHighlights` (type: `boolean`):

Include highlighted matching snippets when using reviewSearch.

## `includeNonPublic` (type: `boolean`):

Include non-public and rejected reviews.

## Actor input object example

```json
{
  "products": [
    "https://www.g2.com/products/slack/reviews"
  ],
  "maxReviewsPerProduct": 20,
  "sortBy": "DATE_DESC",
  "ratings": [
    "1",
    "2",
    "3",
    "4",
    "5"
  ],
  "maxProducts": 10,
  "analytics": false,
  "maxReviews": 100,
  "collapseByProduct": false,
  "includeDiscussions": false,
  "includeHighlights": true,
  "includeNonPublic": false
}
```

# 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": [
        "https://www.g2.com/products/slack/reviews"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kaix/g2-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 = { "products": ["https://www.g2.com/products/slack/reviews"] }

# Run the Actor and wait for it to finish
run = client.actor("kaix/g2-scraper").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 '{
  "products": [
    "https://www.g2.com/products/slack/reviews"
  ]
}' |
apify call kaix/g2-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "G2 Scraper - Reviews, Products, Analytics & Discussions",
        "description": "🔥 ~$0.05/1K reviews 🔥 Scrape G2.com software reviews, products, analytics, comparisons, and discussions. Faceted filtering, facet-value discovery, 72 review fields, NLP sentiment, switching intelligence.",
        "version": "0.1",
        "x-build-id": "09Pt0q1i9kcpBy5Jy"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/kaix~g2-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-kaix-g2-scraper",
                "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/kaix~g2-scraper/runs": {
            "post": {
                "operationId": "runs-sync-kaix-g2-scraper",
                "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/kaix~g2-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-kaix-g2-scraper",
                "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",
                "properties": {
                    "products": {
                        "title": "Product URLs or slugs",
                        "type": "array",
                        "description": "G2 product URLs (e.g. https://www.g2.com/products/slack/reviews) or just slugs (e.g. slack). Also accepts category URLs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxReviewsPerProduct": {
                        "title": "Max reviews per product",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum number of reviews to scrape per product. Set to 0 for no limit (all reviews).",
                        "default": 20
                    },
                    "sortBy": {
                        "title": "Sort reviews by",
                        "enum": [
                            "DATE_DESC",
                            "DATE_ASC",
                            "RATING_DESC",
                            "RATING_ASC",
                            "HELPFUL_DESC",
                            "G2_DEFAULT"
                        ],
                        "type": "string",
                        "description": "How to sort reviews.",
                        "default": "DATE_DESC"
                    },
                    "ratings": {
                        "title": "Star ratings to include",
                        "type": "array",
                        "description": "Only include reviews with these star ratings. Leave empty for all ratings.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "1",
                                "2",
                                "3",
                                "4",
                                "5"
                            ],
                            "enumTitles": [
                                "1 star",
                                "2 stars",
                                "3 stars",
                                "4 stars",
                                "5 stars"
                            ]
                        },
                        "default": [
                            "1",
                            "2",
                            "3",
                            "4",
                            "5"
                        ]
                    },
                    "companySegment": {
                        "title": "Company size filter",
                        "type": "array",
                        "description": "Filter by company size.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "small_business",
                                "mid_market",
                                "enterprise"
                            ],
                            "enumTitles": [
                                "Small Business",
                                "Mid-Market",
                                "Enterprise"
                            ]
                        }
                    },
                    "dateFrom": {
                        "title": "Reviews from date",
                        "type": "string",
                        "description": "ISO date, only reviews submitted on or after this date."
                    },
                    "dateTo": {
                        "title": "Reviews to date",
                        "type": "string",
                        "description": "ISO date, only reviews submitted on or before this date."
                    },
                    "primaryRegions": {
                        "title": "Primary region",
                        "type": "array",
                        "description": "Filter by reviewer primary region.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Americas",
                                "Asia Pacific",
                                "EMEA"
                            ],
                            "enumTitles": [
                                "Americas",
                                "Asia Pacific",
                                "EMEA"
                            ]
                        }
                    },
                    "sourceTypes": {
                        "title": "Review source type",
                        "type": "array",
                        "description": "Filter by how the review was collected (e.g. organic, g2_incentivized). Discover values via enumFields: source_type.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "responseTypes": {
                        "title": "Response type",
                        "type": "array",
                        "description": "Filter by review medium (e.g. text, video). Discover values via enumFields: response_type.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "loveThemes": {
                        "title": "Loved themes",
                        "type": "array",
                        "description": "Filter by what reviewers liked (e.g. Automation, Analytics). Discover values via enumFields: love_theme_humanized.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "hateThemes": {
                        "title": "Hated themes",
                        "type": "array",
                        "description": "Filter by what reviewers disliked. Discover values via enumFields: hate_theme_humanized.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "switchingThemes": {
                        "title": "Switching themes",
                        "type": "array",
                        "description": "Filter by why reviewers switched products. Discover values via enumFields: switching_theme_humanized.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "discounts": {
                        "title": "Discount",
                        "type": "array",
                        "description": "Filter by reported discount. Discover values via enumFields: discount.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "reviewSources": {
                        "title": "Review source channel",
                        "type": "array",
                        "description": "Filter by review source channel. Discover values via enumFields: review_source.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "reviewSearch": {
                        "title": "Search within reviews",
                        "type": "string",
                        "description": "Full-text search within review text. When used without products, searches globally across all products."
                    },
                    "search": {
                        "title": "Search products",
                        "type": "string",
                        "description": "Find products by keyword search (e.g. 'project management')."
                    },
                    "category": {
                        "title": "Browse by category",
                        "type": "string",
                        "description": "Find products in a G2 category (e.g. 'CRM', 'Project Management')."
                    },
                    "vendor": {
                        "title": "Browse by vendor",
                        "type": "string",
                        "description": "Find all products by vendor name (e.g. 'Salesforce')."
                    },
                    "maxProducts": {
                        "title": "Max products",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum products to scrape in search/category/vendor mode.",
                        "default": 10
                    },
                    "compare": {
                        "title": "Compare products",
                        "type": "array",
                        "description": "Compare products side-by-side with analytics (e.g. ['slack', 'teams', 'discord']).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "analytics": {
                        "title": "Analytics mode",
                        "type": "boolean",
                        "description": "Return aggregation analytics per product instead of individual reviews.",
                        "default": false
                    },
                    "enumFields": {
                        "title": "Discover facet values",
                        "type": "array",
                        "description": "Return the distinct values for these review facets (saved to the metadata dataset) instead of scraping reviews. Use the values to populate the reviewer-facet filters.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "source_type",
                                "response_type",
                                "love_theme_humanized",
                                "hate_theme_humanized",
                                "switching_theme_humanized",
                                "discount",
                                "review_source"
                            ]
                        }
                    },
                    "similarTo": {
                        "title": "Find similar reviews",
                        "type": "string",
                        "description": "Find reviews similar to this text."
                    },
                    "reviewIds": {
                        "title": "Fetch reviews by ID",
                        "type": "array",
                        "description": "Fetch specific reviews by their G2 review ID.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxReviews": {
                        "title": "Max reviews (global/similar search)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Max total reviews for global search or similar mode. Set to 0 for no limit.",
                        "default": 100
                    },
                    "collapseByProduct": {
                        "title": "One review per product",
                        "type": "boolean",
                        "description": "Deduplicate global search results to one review per product.",
                        "default": false
                    },
                    "includeDiscussions": {
                        "title": "Include discussions",
                        "type": "boolean",
                        "description": "Also fetch Q&A discussion threads per product.",
                        "default": false
                    },
                    "includeHighlights": {
                        "title": "Include search highlights",
                        "type": "boolean",
                        "description": "Include highlighted matching snippets when using reviewSearch.",
                        "default": true
                    },
                    "includeNonPublic": {
                        "title": "Include non-public reviews",
                        "type": "boolean",
                        "description": "Include non-public and rejected reviews.",
                        "default": false
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
