# Chrome Web Store Reviews Scraper — Extension Reviews (`fabrikit/chrome-web-store-reviews-scraper`) Actor

Scrape reviews of any Chrome extension: rating, full text, author, ISO dates, helpful votes, extension version and the developer's reply, plus listing metadata. Any of 39 review languages or all of them at once. US$0.60 per 1,000 reviews.

- **URL**: https://apify.com/fabrikit/chrome-web-store-reviews-scraper.md
- **Developed by:** [Fabrikit](https://apify.com/fabrikit) (community)
- **Categories:** Developer tools, Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 review results

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

## Chrome Web Store Reviews Scraper — Extension Reviews

Scrape **every review of any Chrome extension** into clean, analysis-ready JSON: star rating, full review text, author, ISO timestamps, helpful / not-helpful votes, the **extension version the user was on**, the review's language, and the **developer's public reply** — plus the listing's own metadata (name, average rating, total ratings, weekly users, category, current version, developer).

This is not HTML scraping. The modern Chrome Web Store is an Angular app that serves reviews from Google's internal JSON-RPC transport; this Actor talks to that endpoint directly, the same one the page itself calls. No browser, no login, no API key, no proxies — so it is fast, cheap and immune to visual redesigns.

What you get from a single run:

- **Complete review histories**, not the first page. Reviews come back 200 per request with unlimited token pagination — verified deep into extensions with tens of thousands of written reviews.
- **Developer replies**, matched to the review they answer, with their own author and timestamp — the field most review datasets drop.
- **All 39 review languages, merged.** The Store partitions reviews by language: its English page hides the Spanish, Russian and Portuguese reviews entirely. Set `language: "all"` and this Actor sweeps every language and deduplicates into one dataset. On a mid-size extension that is often **40% more reviews** than the English listing shows.
- **Version-tagged feedback.** Every review carries the extension version it was written against, so you can see exactly which release caused a rating drop.

Example output item (real review, unedited):

```json
{
    "reviewId": "fae2c3ca-68f6-4467-937d-4c642918096d",
    "extensionId": "gighmmpiobklfepjocnamgkkbiglidom",
    "extensionName": "AdBlock — block ads across the web",
    "extensionUrl": "https://chromewebstore.google.com/detail/gighmmpiobklfepjocnamgkkbiglidom",
    "extensionIcon": "https://lh3.googleusercontent.com/mgNKV-3VMXD556WVUiWSbcukQQN-il4Zlqq03efTjG2B5j9YP7Fxr3idTQ_G0JFD7E6o4TMwvTQTleDn_8UdFLf5VQ",
    "extensionSummary": "Block ads on YouTube and your favorite sites for free",
    "extensionCategory": "productivity/workflow",
    "extensionVersion": "6.45.2",
    "extensionUpdatedAt": "2026-08-18T14:10:09.000Z",
    "extensionRating": 4.473629640346254,
    "extensionRatingCount": 290307,
    "extensionReviewCount": 37963,
    "extensionUserCount": 60000000,
    "extensionDeveloper": "AdBlock",
    "extensionWebsite": "http://getadblock.com/",
    "rating": 1,
    "text": "Adblock (getadblock.com) changed its revenue scheme, which means poorer ad-blocking performance to drive users to a subscription.",
    "author": "Giovanni",
    "authorAvatar": "https://lh3.googleusercontent.com/a-/ALV-UjWK1nx3jX4QdSeoABCET5WvamXrfD-_BiWcwb4KeqPfgHubZ4eJ=s32",
    "publishedAt": "2026-08-04T06:33:42.000Z",
    "updatedAt": "2026-08-04T06:33:42.000Z",
    "edited": false,
    "helpfulCount": 7,
    "notHelpfulCount": 0,
    "totalVotes": 7,
    "version": "6.44.0.1",
    "language": "en",
    "requestedLanguage": "en",
    "developerReply": "Thanks for sharing your thoughts. While we have added new functionality for our Premium users, we continue to provide the same free in-browser ad blocking that you rely on. Our filter list authors are always monitoring for issues and make frequent updates to our free ad-blocking filters. If you have questions, please reach out to us at help@getadblock.com. We'd love to connect with you.",
    "developerReplyAuthor": "AdBlock Support",
    "developerReplyAt": "2026-08-04T18:48:25.000Z",
    "scrapedAt": "2026-08-21T03:13:50.174Z"
}
```

### How to scrape Chrome Web Store reviews

1. Paste one or more **extension URLs** — `https://chromewebstore.google.com/detail/<slug>/<id>`, the old `chrome.google.com/webstore/detail/...` form, or just the bare 32-character id. Up to 100 extensions per run.
2. Set **max reviews per extension**, pick a **language** (or `all`) and a **sort order**.
3. Press **Start**. Results land in the dataset and export to JSON, CSV or Excel, or sync to Google Sheets, Zapier, Make, a webhook or the Apify API.

#### Example input

```json
{
    "extensionUrls": [
        "https://chromewebstore.google.com/detail/adblock-block-ads-across-the-web/gighmmpiobklfepjocnamgkkbiglidom",
        "kbfnbcaeplbcioakkpcpgfkobkghlhen"
    ],
    "maxReviewsPerExtension": 2000,
    "language": "en",
    "sort": "newest"
}
```

- **extensionUrls** — Chrome Web Store listing URLs or bare extension ids. Anything containing a 32-character id works; entries without one are skipped with a warning.
- **maxReviewsPerExtension** — cap per extension (not per run). With `language: "all"` the cap covers all languages together.
- **language** — `en` by default. One of 39 codes, or `all` to sweep every language and merge. The Store returns *only* reviews written in the requested language.
- **sort** — `newest` (default), `most_relevant`, `lowest_rating`, `highest_rating`.
- **proxyConfiguration** — off by default; the Store answers plain requests.

### Output fields

| Field | Type | Description |
|---|---|---|
| `reviewId` | string | Stable review UUID — use it to diff runs and deduplicate |
| `extensionId` | string | 32-character Chrome extension id |
| `extensionName` | string | null | Listing title |
| `extensionUrl` | string | Link to the listing |
| `extensionIcon` | string | null | Icon URL |
| `extensionSummary` | string | null | Short description shown under the title |
| `extensionCategory` | string | null | Store category, e.g. `productivity/workflow` |
| `extensionVersion` | string | null | Version currently published |
| `extensionUpdatedAt` | string | null | ISO date the listing was last updated |
| `extensionRating` | number | null | Average star rating (full precision, e.g. `4.4736`) |
| `extensionRatingCount` | number | null | Total star ratings, including ratings with no text |
| `extensionReviewCount` | number | null | **Written** reviews available in the requested language |
| `extensionUserCount` | number | null | Users reported by the Store |
| `extensionDeveloper` | string | null | Publisher name |
| `extensionWebsite` | string | null | Developer website |
| `rating` | number | null | This review's rating, 1–5 |
| `text` | string | null | Full review text, newlines preserved |
| `author` | string | null | Reviewer's display name |
| `authorAvatar` | string | null | Reviewer's avatar URL |
| `publishedAt` | string | null | ISO 8601 UTC timestamp the review was posted |
| `updatedAt` | string | null | ISO 8601 UTC timestamp of the last edit |
| `edited` | boolean | `true` when the review was edited after posting |
| `helpfulCount` | number | Users who marked the review helpful |
| `notHelpfulCount` | number | Users who marked it not helpful |
| `totalVotes` | number | `helpfulCount + notHelpfulCount` — the "N out of M" the page shows |
| `version` | string | null | Extension version the reviewer was running |
| `language` | string | null | Language the Store detected for the review |
| `requestedLanguage` | string | Language bucket this review was fetched from |
| `developerReply` | string | null | Developer's public reply, when there is one |
| `developerReplyAuthor` | string | null | Name the developer replies under |
| `developerReplyAt` | string | null | ISO 8601 UTC timestamp of the reply |
| `scrapedAt` | string | ISO 8601 UTC timestamp of this run |

A run summary (per extension, per language, reported totals and any errors) is stored in the run's key-value store under `SUMMARY`.

### What can you do with Chrome extension review data?

- **Competitor teardown.** Pull `lowest_rating` on a rival extension and you have its bug backlog, its churn reasons and its angriest users, ranked, in one table.
- **Release-quality tracking.** Group by `version` and watch average rating per release — the fastest way to prove which build broke things.
- **Monetization backlash monitoring.** Extensions that go freemium light up in the review feed within hours; schedule daily runs and alert on 1-star spikes.
- **Support triage.** `developerReply` is null on every review nobody answered — filter for unanswered 1- and 2-star reviews and you have a work queue.
- **Market research.** Scrape the whole category, aggregate `extensionRating`, `extensionUserCount` and review sentiment, and find the underserved niche.
- **LLM training and sentiment sets.** Multilingual, labelled with a star rating, dated, version-tagged — with `language: "all"` you get real coverage instead of an English-only sample.

### Integrations

Every Apify dataset exports to **CSV, Excel, JSON, XML or HTML** with one click, or syncs to **Google Sheets**, and the Actor plugs into **Zapier, Make, webhooks, MCP** and the Apify API:

```python
## Python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("fabrikit/chrome-web-store-reviews-scraper").call(run_input={
    "extensionUrls": ["gighmmpiobklfepjocnamgkkbiglidom"],
    "maxReviewsPerExtension": 1000,
    "language": "all",
    "sort": "lowest_rating",
})
for review in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(review["rating"], review["version"], "—", review["text"][:80])
```

```javascript
// Node.js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('fabrikit/chrome-web-store-reviews-scraper').call({
    extensionUrls: [
        'https://chromewebstore.google.com/detail/adblock-block-ads-across-the-web/gighmmpiobklfepjocnamgkkbiglidom',
    ],
    maxReviewsPerExtension: 2000,
    sort: 'newest',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'reviews');
```

### Performance & limits

- **Plain HTTP JSON, no browser.** A verified benchmark: **6,000 reviews from 3 extensions in 37 seconds** (AdBlock, Grammarly, Honey — 2,000 each).
- **200 reviews per request**, token pagination with no depth limit. Pagination ends cleanly: an extension with 347 English reviews returns exactly 347, zero duplicates.
- **Reviews are deduplicated by `reviewId`** within a run, including across languages when `language: "all"` (the Store aliases `pt-BR` onto `pt` and `zh-TW` onto `zh-CN`; both are handled).
- **A missing or unpublished extension never kills the run** — it is logged, recorded in `SUMMARY`, and the remaining extensions continue.
- Requests are paced at ~3/second. No proxies needed; the endpoint accepts anonymous requests.
- **Written reviews are a subset of ratings.** AdBlock has 290,307 star ratings but 37,963 written English reviews — `extensionRatingCount` vs `extensionReviewCount` tells you which is which before you set a cap.

### Tips for best results

- **Use `language: "all"` when the extension is global.** English-only runs silently miss the majority on many extensions: Raindrop.io returns 347 English reviews but **489 across all languages**.
- **`sort: "lowest_rating"` is the money setting** for competitor research and bug mining — it front-loads every complaint instead of making you page through praise.
- **For daily monitoring**, use `sort: "newest"` with a small `maxReviewsPerExtension` (50–200) and diff on `reviewId`. You only pay for reviews actually delivered.
- **Set the cap from `extensionReviewCount`, not `extensionRatingCount`** — the second number is 5–10× larger and counts silent star ratings you can never fetch.
- **Track releases** by grouping on `version`; note it is null on ~7% of reviews (the Store simply did not record it), so treat it as optional in your pipeline.
- Batch up to 100 extensions in one run to amortize the start fee across a whole category.

### Pricing — US$0.60 per 1,000 reviews

This Actor uses Apify's **pay-per-event** model: **US$0.0006 per review delivered** (event `review-result`) — **US$0.60 per 1,000 reviews** — plus a **US$0.00005 run-start fee**, on top of standard Apify platform usage. No subscription, no rental fee. You only pay for reviews actually pushed to your dataset.

### FAQ

**Is there an official Chrome Web Store API for reviews?**
No. Google publishes no public reviews API, and the reviews are not in the page's HTML either — the Store is an Angular app that loads them from an internal JSON-RPC endpoint. This Actor calls that endpoint the same way the page does, and re-reads the endpoint's identifier from the live page on every run, so a Google-side rotation does not silently break it.

**Can I get all reviews of an extension, not just the first page?**
Yes. Pagination is unlimited and verified deep into extensions with tens of thousands of reviews. Set `maxReviewsPerExtension` high and `language: "all"` for full coverage.

**Why does the review count not match the number of ratings?**
Most people rate without writing. `extensionRatingCount` counts every star rating; `extensionReviewCount` counts written reviews in the requested language. Only written reviews can be fetched.

**Does country or region change the results?**
No — the Store varies reviews by **language**, not country. A `gl` (country) parameter has no effect at all, so the Actor does not pretend to offer one.

**Are the dates real timestamps?**
Yes: `publishedAt`, `updatedAt` and `developerReplyAt` are true ISO 8601 UTC timestamps from the Store's own data, not parsed "3 months ago" strings.

**Do I need proxies or a Google account?**
Neither. The endpoint answers anonymous requests with no cookies. `proxyConfiguration` is available if a very large run ever hits rate limits.

**Does it collect personal data?**
It collects only what the Chrome Web Store publishes on a public product page: the display name and avatar the reviewer chose to show alongside a public review. No emails, no accounts, no private data. How you process it is your own compliance call.

**Which extensions work?**
Any public listing — extensions, themes and apps. Unpublished or removed items are skipped with a warning rather than failing the run.

### Support

Missing a field the Store publishes, or need a filter that isn't there? Open an issue in the **Issues** tab — issues are typically answered **within 24 hours**, and new fields are cheap to add because the Actor reads structured JSON, not HTML.

### More scrapers by Fabrikit

- **[Google Play Reviews Scraper](https://apify.com/fabrikit/google-play-reviews-scraper)** — Android app reviews with rating, version, helpful votes and developer replies, any country and language.
- **[App Reviews Scraper — App Store & Google Play](https://apify.com/fabrikit/app-reviews-unified)** — both mobile stores in one normalized dataset.
- **[ATS Jobs Scraper — Greenhouse, Lever, Ashby & SmartRecruiters](https://apify.com/fabrikit/ats-jobs-api)** — job postings from the four biggest ATS platforms.

### Technical details

- Data source: the Chrome Web Store's own `batchexecute` JSON-RPC endpoint (`/_/ChromeWebStoreConsumerFeUi/data/batchexecute`), plus one HTML request per extension to read the listing metadata and re-discover the RPC identifiers the page declares for itself.
- No browser, no CSS selectors, no HTML parsing of reviews — a visual redesign of the Store changes nothing.
- Timestamps arrive as epoch seconds and are converted to ISO 8601 UTC.
- `helpfulCount` / `notHelpfulCount` reproduce the page's "N out of M found this helpful" exactly.
- The dataset schema in `.actor/actor.json` is generated from the scraper's own item builder and verified in both directions before every push, so no item is ever rejected for a field the code does not produce.

# Actor input Schema

## `extensionUrls` (type: `array`):

One or more Chrome Web Store extensions. Paste the full listing URL (`https://chromewebstore.google.com/detail/<slug>/<id>`), the old `chrome.google.com/webstore/detail/...` URL, or just the bare 32-character extension id. Up to 100 extensions per run.

## `maxReviewsPerExtension` (type: `integer`):

Stop after this many reviews for each extension. Reviews are fetched 200 per request and pagination is unlimited, so popular extensions (tens of thousands of written reviews) can be pulled in full.

## `language` (type: `string`):

The Chrome Web Store splits reviews by language: a request for `en` returns only English reviews. Pick one language, or `all` to sweep 39 languages and merge them into one deduplicated dataset (the only way to get every written review an extension has).

## `sort` (type: `string`):

`newest` is the right choice for monitoring pipelines. `lowest_rating` puts complaints first — the fastest way to mine bug reports and churn reasons. `most_relevant` mirrors the order the Store shows by default on the listing page.

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

The Chrome Web Store answers plain requests with no cookies, no login and no API key, so proxies are off by default. Turn on Apify RESIDENTIAL proxies only if very large runs start returning HTTP 429.

## Actor input object example

```json
{
  "extensionUrls": [
    "https://chromewebstore.google.com/detail/adblock-block-ads-across-the-web/gighmmpiobklfepjocnamgkkbiglidom"
  ],
  "maxReviewsPerExtension": 200,
  "language": "en",
  "sort": "newest",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `reviews` (type: `string`):

All reviews collected during the 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 = {
    "extensionUrls": [
        "https://chromewebstore.google.com/detail/adblock-block-ads-across-the-web/gighmmpiobklfepjocnamgkkbiglidom"
    ],
    "maxReviewsPerExtension": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("fabrikit/chrome-web-store-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 = {
    "extensionUrls": ["https://chromewebstore.google.com/detail/adblock-block-ads-across-the-web/gighmmpiobklfepjocnamgkkbiglidom"],
    "maxReviewsPerExtension": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("fabrikit/chrome-web-store-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 '{
  "extensionUrls": [
    "https://chromewebstore.google.com/detail/adblock-block-ads-across-the-web/gighmmpiobklfepjocnamgkkbiglidom"
  ],
  "maxReviewsPerExtension": 200
}' |
apify call fabrikit/chrome-web-store-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fabrikit/chrome-web-store-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/HlSvQkE1znle3bsuu/builds/axGWUdek1OTRrKyDr/openapi.json
