# Google Play Reviews Scraper - Replies, Versions, Monitor (`scrapersdelight/google-play-reviews-scraper`) Actor

$0.045 per 1,000 reviews, no start fee. Google Play reviews for any Android app: rating, text, author, date, thumbs-up, app version, developer reply, criteria. Many apps x languages x countries per run, star + date filters, newest-first early stop and a monitor mode that never bills a review twice.

- **URL**: https://apify.com/scrapersdelight/google-play-reviews-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Marketing, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.05 / 1,000 per review returneds

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

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

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Google Play Reviews Scraper — Developer Replies, App Versions, Monitor Mode

Turn any Android app's Google Play reviews into clean rows, read from the same endpoint the
Play Store website uses to render its own review list. One row per review: **rating, body,
userName, userImage, date, thumbsUp, appVersion, developerResponseBody,
developerResponseDate, developerResponseAuthor, criteria, reviewUrl** — plus the app's
**appName, appScore and appRatingsCount** on every row. Many apps × languages × countries in
one run, star and date filters, newest-first early stop, and a monitor mode that never bills
the same review twice. No login. No API key. No browser.

**$0.045 per 1,000 reviews** ($0.000045 each), no start fee.

```json
{
  "apps": ["com.whatsapp"],
  "languages": ["en"],
  "countries": ["us"],
  "sort": "newest",
  "maxReviewsPerApp": 200
}
```

That block is the input the Actor ships with. Press **Start** and you get WhatsApp's 200
newest English reviews for **$0.009** — measured on the live Actor 2026-09-23: 200 rows,
200 charged, 5 seconds.

This is the Android twin of our
[App Store Reviews Scraper](https://apify.com/scrapersdelight/appstore-reviews-scraper): the
same field names wherever the concept is the same (`body`, `userName`, `date`,
`appVersion`, `developerResponseBody`, `developerResponseDate`, `position`, `order`,
`appUrl`), so you can union the two datasets downstream.

***

### What makes it different

- **Languages, not just countries — measured, not assumed.** Google Play's review list is
  keyed by *language* far more than by *country*: WhatsApp's 200 newest English reviews were
  **87–100% identical** across the us, gb, in, au and de stores (measured 2026-09-23), while
  `hl=de` returns a different, German corpus. `languages` takes a list, every app is crossed
  with every language and country, and **a review already delivered for another country or
  language is dropped before billing** (`dedupeAcrossCountries`, on by default). A scraper
  that sweeps five English-speaking countries without this bills you for largely the same
  reviews five times.
- **Monitor mode that cannot skip a gap.** `onlyNewReviews` keeps a per app × language ×
  country bookmark in a named key-value store in your account. The next run reads newest-first
  only down to the bookmark (with a one-hour overlap, because Google's frontends can lag each
  other by minutes — observed), skips every review it already delivered, and **only advances
  the bookmark when the walk actually reached it** — a run cut short by a cap re-reads the
  gap next time instead of losing it. Measured: a second run 90 s after a 10,000-review
  baseline read 1 page, recognised 105 overlap reviews as already delivered, and billed $0.
- **App context on every row.** `appName`, `appScore` and `appRatingsCount` come from the app's
  own store page (its schema.org block), so a multi-app dataset is self-describing. The same
  read tells a **non-existent package** (HTTP 404 — skipped, $0, named in the run summary)
  apart from **an app with no reviews** in that language.
- **Integrity checks that end the run instead of shipping bad rows.** Every page's review ids
  are checked against the walk so far; a repeated continuation token or a page of nothing but
  repeats is a *pagination loop* and stops the walk. If Google changes the review format, the
  run fails loudly rather than delivering a page of nulls. At the end, charged events must
  equal delivered rows exactly.

***

### Read this before you buy rows

1. **`date` is when the review was written *or last edited*.** A developer reply can
   therefore be *older* than the review it answers — measured on Robinhood: replies from
   2022–2025 on reviews re-edited in September 2026. That is Google's data, not a bug.
2. **Google publishes reviews with a delay.** The newest review Google served on 2026-09-23
   \~05:00 UTC was stamped 2026-09-22 ~04:59 UTC — about a day old. A "last hour" window will
   usually be empty; that is the source, not the Actor.
3. **Country barely changes the newest list; language does.** See above. For a worldwide
   sweep, list languages (`en`, `es`, `pt-BR`, `de`, `fr`, `ja`…) with one country each.
   Countries do change the **most relevant** order (27–35% overlap between us and
   gb/in/au/de for Spotify, measured).
4. **Reviews are not ratings.** Spotify shows 36.4M ratings; the reviews Google serves are the
   written ones in the language you ask for. Home Assistant (English) ended at **1,574**
   reviews — the corpus end is a missing continuation token, and the run says "corpus
   exhausted at N reviews".
5. **`criteria` are Google's own raw keys** (`vaf_app_quality_usability`,
   `vaf_phase1_investing`…) with the number Google stores. Google does not publish what each
   number means, so the Actor passes them through untranslated rather than guess.
6. **Reviewer fields are a name and an avatar only.** `userName` is the public display name
   shown on the Play Store (sometimes a real name, sometimes "A Google user"); `userImage` is
   the public avatar URL. No email, phone or address exists in this data.

***

### What you get

One row per review. Dates are ISO-8601 UTC. `rating` is an integer 1–5.

| Group | Fields | Notes |
|---|---|---|
| **Identity** | `reviewId`, `appId`, `appName`, `language`, `country` | `language`/`country` are the values you requested — Google does not label a review's language, so the Actor never infers one |
| **Review** | `rating`, `body`, `date`, `thumbsUp` | `thumbsUp` = "helpful" votes; `0` is a real zero |
| **Reviewer** | `userName`, `userImage` | public display name + avatar URL |
| **Version** | `appVersion` | the app version the reviewer had installed; `null` when Google shows none |
| **Developer reply** | `developerResponseBody`, `developerResponseDate`, `developerResponseAuthor` | all three `null` together when there is no reply — never `""` |
| **Quality questions** | `criteria` | `[{criterion, rating}]`, Google's raw keys, or `null` |
| **App context** | `appScore`, `appRatingsCount` | from the app's store page (turn off with `includeAppDetails`) |
| **Provenance** | `position`, `order`, `starFilter`, `reviewUrl`, `appUrl`, `source`, `scrapedAt` | `position` = rank within its app × language × country walk |

***

### Field fill — measured on the live Actor, three frames

Frames were chosen to disagree on purpose (newest vs most relevant; ten apps vs one), so the
spread between them is the honest range.

| Field | A: 10 apps × 200 newest (2,000 rows) | B: same 10 apps × 200 most relevant (2,000) | C: WhatsApp 10,000 newest |
|---|---|---|---|
| `reviewId`, `rating`, `body`, `date`, `userName`, `userImage`, `thumbsUp`, `reviewUrl` | 100% | 100% | 100% |
| `appName`, `appScore`, `appRatingsCount` | 100% | 100% | 100% |
| **`appVersion`** | **81.8%** | **98.9%** | **82.2%** |
| **`developerResponseBody` / `Date` / `Author`** | **27.9%** | **27.3%** | **0.0%** |
| **`criteria`** | 19.6% | 35.4% | 25.8% |
| `thumbsUp` > 0 | 13.6% | 90.0% | 20.6% |

Developer replies are **publisher behaviour**, not a parser rate. Per app in frame A (of 200
newest): Booking.com 193, Robinhood 175, TikTok 157, Spotify 31, Uber 1 — and 0 for WhatsApp,
Netflix, Airbnb, Instagram and Duolingo. The offline validator checks the negative direction
too: every raw reply, version and criteria block in the captured bytes is emitted (0 parser
gaps across 400 fixture reviews). The ten apps were: WhatsApp, Spotify, Robinhood, Duolingo,
Uber, Instagram, Netflix, Airbnb, Booking.com, TikTok. **Every run prints its own fill in the
log and in `RUN_SUMMARY`.**

***

### How to run it

#### 1. The default — one app, newest 200

The shipped input above. $0.009.

#### 2. Complaint mining across competitors

```json
{
  "apps": ["com.spotify.music", "com.soundcloud.android", "deezer.android.app"],
  "languages": ["en"],
  "countries": ["us"],
  "stars": [1, 2],
  "maxReviewsPerApp": 2000
}
```

Stars are filtered **server-side** by Google (one star at a time, 1★ first; the per-app cap
is shared across them). 6,000 reviews max = $0.27.

#### 3. Support-behaviour audit — only reviews the developer answered

```json
{ "apps": ["com.booking"], "onlyWithDeveloperReply": true, "maxReviewsPerApp": 1000 }
```

Reviews without a reply are read but **never billed**.

#### 4. A date window, cheaply

```json
{ "apps": ["com.whatsapp"], "sort": "newest", "sinceDate": "2026-09-01", "untilDate": "2026-09-15", "maxReviewsPerApp": 0 }
```

With `sort: "newest"` paging stops at the first review older than `sinceDate`. (With the other
sorts, dates are applied row by row and paging cannot stop early — the log warns you.)

#### 5. Daily monitor across languages

```json
{
  "apps": ["com.yourcompany.app"],
  "languages": ["en", "es", "pt-BR", "de", "fr"],
  "countries": ["us"],
  "onlyNewReviews": true,
  "maxReviewsPerApp": 5000
}
```

Save it as a **Task**, attach a **Schedule** (`0 7 * * *`). The first run is your baseline
(it reads newest-first up to your caps and sets the bookmark); every later run delivers only
what is new. From the API:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~google-play-reviews-scraper/runs?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"apps":["com.whatsapp"],"languages":["en"],"onlyNewReviews":true}'
```

API callers used to other scrapers' inputs can send a single `"language": "de"` — it is
accepted and replaces `languages`.

***

### Sample row

A real row from the live run of 2026-09-23 (frame A, Robinhood, newest):

```json
{
  "reviewId": "398cee35-43b5-440f-8b02-5c2551876b84",
  "appId": "com.robinhood.android",
  "appName": "Robinhood: Trading & Investing",
  "country": "us",
  "language": "en",
  "rating": 4,
  "body": "Finally, updated and fixed all kinds of stuff. upgraded review from 2 to 4 stars, but now, it's got too much nonsense. 🤷‍♂️",
  "userName": "Christian Zagarskas",
  "userImage": "https://play-lh.googleusercontent.com/a-/ALV-UjUHIeC5rq2CH3qVdxD35VfDnE60V24nELfXX9mbOA1-OXnyqpNQ",
  "date": "2026-09-22T01:53:49.801Z",
  "thumbsUp": 4,
  "appVersion": "2026.37.4",
  "developerResponseBody": "Sorry to hear this wasn’t a great experience. If you’re up for it, send a note to reviews@robinhood.com with a few more details.",
  "developerResponseDate": "2026-09-22T03:31:00.382Z",
  "developerResponseAuthor": "Robinhood",
  "criteria": [{ "criterion": "vaf_phase1_investing", "rating": 1 }],
  "position": 2,
  "order": "newest",
  "starFilter": null,
  "reviewUrl": "https://play.google.com/store/apps/details?id=com.robinhood.android&reviewId=398cee35-43b5-440f-8b02-5c2551876b84",
  "appUrl": "https://play.google.com/store/apps/details?id=com.robinhood.android&hl=en&gl=us",
  "appScore": 4.624,
  "appRatingsCount": 574404,
  "source": "google-play-batchexecute",
  "scrapedAt": "2026-09-23T05:04:40.951Z"
}
```

***

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| **🎯 What to scrape** | | | |
| `apps` | string list | `["com.whatsapp"]` | Package names or Play Store links. A package that does not exist is reported and skipped, $0. Empty = the WhatsApp sample. |
| `languages` | string list | `["en"]` | `hl` codes, one per entry (`en`, `de`, `pt-BR`…). Each is its own corpus. |
| `countries` | string list | `["us"]` | `gl` codes, one per entry. |
| `sort` | select | `newest` | `newest`, `mostRelevant` (the store page's default) or `rating` (highest first). |
| **🎚️ Filters** (applied before billing) | | | |
| `stars` | integer list | `[]` (all) | e.g. `[1, 2]`. Server-side. |
| `sinceDate` / `untilDate` | date | — | UTC; a plain date covers the whole day. Early stop with `newest`. |
| `onlyWithDeveloperReply` | boolean | `false` | Only reviews carrying a developer reply. |
| `onlyNewReviews` | boolean | `false` | Monitor mode (above). Forces `newest`. |
| **📊 Output & cost** | | | |
| `maxReviewsPerApp` | integer | `200` | Per app × language × country. A review already delivered for another country/language fills a slot without being billed again. `0` = no cap. |
| `maxItems` | integer | `10000` | Hard cap for the whole run ($0.45). `0` = none. |
| `dedupeAcrossCountries` | boolean | `true` | Drop a review already delivered for another country or language. |
| **⚙️ Advanced** | | | |
| `includeAppDetails` | boolean | `true` | Adds appName/appScore/appRatingsCount and detects non-existent packages; one ~1.3 MB page per app. |
| `maxConcurrency` | integer | `3` | Parallel app × language × country walks, max 5. |
| `proxyConfiguration` | proxy | off | Direct from Apify's network by default; retries after two failures move to a RESIDENTIAL session automatically. |
| `saveRawResponses` | boolean | `false` | Debugging: stores up to 40 raw Google responses in the run's key-value store. |

***

### Pricing

**$0.000045 per review returned — $0.045 per 1,000.** Charged on the `review-scraped` event,
as rows are pushed. No start fee, no monthly fee from this Actor.

| Run | Reviews | Cost |
|---|---|---|
| The shipped default | 200 | **$0.009** |
| 10 apps × 200 newest | 2,000 | **$0.09** |
| One app's newest 10,000 | 10,000 | **$0.45** |
| A 100,000-review corpus | 100,000 | **$4.50** |

- **You pay for rows delivered.** Repeats, reviews removed by your star/date/reply filters,
  reviews a previous monitor run already delivered and packages that do not exist are never
  charged.
- A run's **maximum total charge** is honoured to the row: whole reviews, clean stop.
- Every run ends with a **billing integrity check** — charged events must equal delivered
  rows exactly, or the run errors instead of mis-billing.

***

### Honest limits

- **Only written reviews.** Star-only ratings are not public and not in any Play endpoint.
- **Language is Google's matching, not a detector.** Google serves reviews for the `hl` you
  ask; a few may be in another language. The `language` field states what was requested.
- **Replies depend on the publisher** — 0% for many large apps (see the fill table).
- **`criteria` values are unlabelled by Google** and passed through raw.
- **One Google field is not emitted:** about 1% of reviews carry a second short text next to
  the review body whose meaning Google does not label. Rather than guess a name for it, the
  Actor leaves it out.
- **Throughput:** measured 10,000 reviews in 37.6 s at the default 512 MB (one app, one walk). Continuation tokens
  are sequential by nature; parallelism comes from multiple app × language × country walks.
- **This is Google's internal web endpoint**, not a published API. If Google changes the
  response shape, the run fails loudly (it will not ship nulls) and the parser gets updated.

***

### How it works

The Actor POSTs to `play.google.com/_/PlayStoreUi/data/batchexecute` (rpc `UsvDTd`) — the
call the Play Store website makes when you scroll its review list — with the sort, the page
size (200), the star filter and the continuation token, and reads the JSON the page itself
renders from. The request and response shape were derived from bytes captured on
2026-09-23, and the offline test suite (29,553 assertions) runs the parser over real captured
pages: an 8-page corpus walked to its end (1,574 reviews, 0 duplicates, dates strictly
newest-first), star-filtered pages, a German store page, and a non-existent package.

**Transport, measured:** direct from Apify's network, 0 retries across every test run
(including 51 consecutive pages for a 10,000-review walk). A non-200, a body that is not a
batchexecute answer, or a Google "unusual traffic" page is treated as a **transport failure**
— retried with backoff and, from the third attempt, on a fresh RESIDENTIAL session — never
as "no more reviews".

***

### Support

Found an app that returns nothing, or need another field? Open an issue on the **Issues**
tab with the package name, language and country.

# Actor input Schema

## `apps` (type: `array`):

One or more Android apps, as package names (com.whatsapp) or Play Store links (https://play.google.com/store/apps/details?id=com.whatsapp). The package is the value after "id=" in any Play Store link. Every app is crossed with every language and country below. A package that does not exist is reported and skipped, never billed. Left empty, the Actor runs its WhatsApp sample so an API or agent call with no input still gets real rows.

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

Language codes of the reviews to read (the hl parameter), one per entry: en, de, es, fr, pt-BR, ja, zh-TW… Measured 2026-09-23: Google Play's review list is keyed by LANGUAGE far more than by country — WhatsApp's 200 newest English reviews were 87-100% identical across us/gb/in/au/de, while a different language is a different corpus. So to sweep a competitor worldwide, list languages; add countries only for country-specific most-relevant ordering. Every row's language field is the value requested — Google does not label a review's language, so the Actor never guesses one.

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

2-letter country codes of the Play Store to read (the gl parameter): us, gb, in, de, br, fr, jp, id, mx… One code per entry. Every app is crossed with every language and every country. Newest-first lists barely change by country (measured 87-100% overlap for English), so one country per language is usually enough; with "Drop repeats" on (default), a review already delivered for another country or language is never delivered or billed again.

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

Order Google Play returns reviews in. "newest" is the only order where a date window stops paging early (a daily monitor reads one page, not the whole history).

## `stars` (type: `array`):

For example \[1, 2] for complaints only, \[5] for testimonials. Filtered server-side by Google Play, one star at a time (so the per-app cap is shared across the stars, lowest star first). Empty = all ratings.

## `sinceDate` (type: `string`):

Only reviews written (or last edited) on or after this date, UTC. YYYY-MM-DD or a full ISO timestamp. With sort "newest" paging stops at the first older review, so this is cheap.

## `untilDate` (type: `string`):

Only reviews written on or before this date, UTC. A plain date includes the whole day.

## `onlyWithDeveloperReply` (type: `boolean`):

Keep only reviews carrying a public developer reply. Expect a minority of rows for most apps (measured on 200 newest: Robinhood 87.5%, Spotify 15.5%, WhatsApp 0%).

## `onlyNewReviews` (type: `boolean`):

For scheduled runs: each app x language x country returns only reviews newer than the newest one your previous run delivered, so you never pay twice for the same review. Always reads newest-first. The bookmark lives in your account's named key-value store "google-play-reviews-monitor" and only advances when a walk reaches it, so a capped run never skips a gap.

## `maxReviewsPerApp` (type: `integer`):

Cap per app per language per country — with the app list, your cost ceiling: 200 = one page. A review already delivered for another country/language counts toward this cap without being billed again, so a repeat country stops after the same number of list positions. 0 = no per-app cap (walk to the end of the corpus or until Max reviews total).

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

Hard cap on reviews delivered across the whole run. 0 = no total cap.

## `dedupeAcrossCountries` (type: `boolean`):

A review is keyed on app + reviewId. On (default), a review already delivered in this run for another country or language is not delivered or billed again — this matters: English newest-first lists overlap 87-100% across countries (measured). Off, each job's list is delivered whole (repeats within one job's walk are always dropped).

## `includeAppDetails` (type: `boolean`):

Reads each app's store page once to add appName, appScore and appRatingsCount to every row and to tell a non-existent package (skipped, $0) apart from an app with no reviews. Costs one ~1.3 MB page per app; turn off for huge app lists where you only need the reviews.

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

How many app x language x country walks run in parallel (pages within one walk are sequential — that is how continuation tokens work). Max 5.

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

Off by default: Google Play answered every request direct from Apify's network in testing. Retries after two failures switch to an Apify RESIDENTIAL session automatically. Set a proxy here only if you see repeated rate-limit retries in the log.

## `saveRawResponses` (type: `boolean`):

Stores up to 40 raw Google responses in this run's key-value store (RAW\_ keys) so a parsing issue can be reproduced. Leave off.

## Actor input object example

```json
{
  "apps": [
    "com.whatsapp"
  ],
  "languages": [
    "en"
  ],
  "countries": [
    "us"
  ],
  "sort": "newest",
  "stars": [],
  "onlyWithDeveloperReply": false,
  "onlyNewReviews": false,
  "maxReviewsPerApp": 200,
  "maxItems": 10000,
  "dedupeAcrossCountries": true,
  "includeAppDetails": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "saveRawResponses": false
}
```

# Actor output Schema

## `items` (type: `string`):

One row per review: rating, text, author, date, thumbsUp, app version, developer reply and criteria.

## `runSummary` (type: `string`):

Per app x country outcome, what was not delivered and why, measured field fill, transport and billing reconciliation.

# 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 = {
    "apps": [
        "com.whatsapp"
    ],
    "languages": [
        "en"
    ],
    "countries": [
        "us"
    ],
    "stars": [],
    "maxReviewsPerApp": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/google-play-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 = {
    "apps": ["com.whatsapp"],
    "languages": ["en"],
    "countries": ["us"],
    "stars": [],
    "maxReviewsPerApp": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/google-play-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 '{
  "apps": [
    "com.whatsapp"
  ],
  "languages": [
    "en"
  ],
  "countries": [
    "us"
  ],
  "stars": [],
  "maxReviewsPerApp": 200
}' |
apify call scrapersdelight/google-play-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/google-play-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/6EHIdFnMJeNz0gWGt/builds/C91JfMciCwVew5Cp0/openapi.json
