# Google Play Reviews Scraper · All Languages · Dev Replies (`thequietstack/google-play-reviews`) Actor

Google Play reviews scraper. Google shows each language its own reviews, so this merges many (or all 49) languages in one run, deduplicated. Developer replies included. Input by URL, package name or search term. Filter by stars, date, version. No login.

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

## Pricing

from $0.50 / 1,000 scraped reviews

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 · All Languages · Dev Replies

Scrape Google Play Store reviews for any Android app, in **one, several or all 49 review languages in a single run**. Every review becomes one clean, flat row with stars, text, app version, date, thumbs-up count and the **developer's reply**, deduplicated by review ID. No login, no API key.

Looking for iPhone/iPad reviews? Use the twin Actor [App Store Reviews Scraper](https://apify.com/thequietstack/app-store-reviews). Both return one flat row per review with rating, text, app version, ISO date and a review ID, so the two stores fit into one sheet.

### Why this scraper

- **Google shows each language its own reviews.** A scraper set to English only ever sees the English review set. Measured on 23 Sep 2026: WhatsApp's 150 newest reviews in English, German, Spanish, Portuguese and Japanese share **zero** review IDs. The first page (150 newest) of **all 49 languages** returned **7,350 reviews, all 7,350 different**. This Actor merges the languages you pick (or all of them) into one dataset. Every row has a `language` field, and duplicates are removed.
- **Developer replies included.** `developerReply` and `developerReplyDate` are fields on every row (empty when there is no reply). There is also a filter for reviews the developer answered, which is useful for studying how a competitor handles support.
- **Input the way you have it.** A Play Store URL, a package name (`com.whatsapp`), or just a search term (`"notion"`).
- **Filters that save money.** Star rating is filtered **on Google's side**, so a 1-2★ run never pages through thousands of 5★ reviews. There are also filters for date range, app version, "has developer reply" and "has text". Filtered-out reviews are **never charged**. With `sortBy: newest`, paging stops as soon as reviews are older than `sinceDate`.
- **Deep history.** Paging goes as far back as Google serves. In our test we stopped Notion (English) after 8,400+ reviews reaching back to October 2024, without hitting the end.
- **A hard limit you can trust.** `maxReviews` stops the run cleanly. You are never charged for more reviews than that, and never for duplicates.
- **No silent empty results.** Google Play's review endpoint is undocumented and can change. Every response is checked against the known format. If Google answers in a shape the Actor does not recognise, the run summary says `FORMAT_WARNING` with samples, and a run that writes nothing because of it **fails visibly**. You never get an empty "success".

### Input example

```json
{
    "apps": ["https://play.google.com/store/apps/details?id=com.whatsapp", "com.instagram.android"],
    "searchTerms": ["notion"],
    "languages": ["en", "de", "es"],
    "ratings": [1, 2],
    "sinceDate": "2026-08-01",
    "maxReviews": 5000
}
```

Set `"allLanguages": true` to scrape all 49 languages. Languages where the app has no reviews cost nothing. With a limit, the limit is **shared fairly across languages** page by page: WhatsApp with all 49 languages and a 5,000 limit returns 102–103 reviews from every one of the 49 languages, instead of 5,000 from the first few. Languages with fewer reviews hand their unused share to the others.

### Output example

```json
{
    "reviewId": "1492883b-928a-467b-8777-e8a2504ee2fb",
    "appId": "com.spotify.music",
    "appName": "Spotify: Music and Podcasts",
    "language": "en",
    "country": "gb",
    "rating": 1,
    "text": "too many ads",
    "version": "9.1.84.2231",
    "date": "2026-09-22T21:47:34.301Z",
    "thumbsUp": 0,
    "author": "SHAWN",
    "developerReply": "Hey. We hear you and we'll pass your feedback along to the Ads team. For an ad-free experience, we'd recommend checking out our Premium plans at spotify.com/premium. If you've never had Premium before, you should be eligible for our trial.",
    "developerReplyDate": "2026-09-22T22:04:45.642Z",
    "aspectRatings": [
        { "aspect": "app_quality_ads_frequency", "rating": 1 },
        { "aspect": "phase1_learning_piano", "rating": 3 }
    ],
    "url": "https://play.google.com/store/apps/details?id=com.spotify.music&reviewId=1492883b-928a-467b-8777-e8a2504ee2fb"
}
```

| Field | Meaning |
|---|---|
| `rating` | Stars, 1–5 |
| `text` | Review body (Google Play reviews have no title) |
| `version` | App version the reviewer was using (empty if Google does not report it) |
| `date` | Review date, ISO 8601 UTC |
| `language` / `country` | The language/country view the review was found in |
| `thumbsUp` | "Helpful" votes |
| `developerReply`, `developerReplyDate` | The developer's public answer, if any |
| `aspectRatings` | Google's optional per-aspect ratings (ads, usability, performance ...), where given |

A run summary (`SUMMARY` in the key-value store) lists reviews per language (with `cutAtLimit` = this language had more reviews when the limit was reached), duplicates removed, how many reviews each filter dropped, languages without reviews, failed streams, and `dataSourceCheck` (`OK` or `FORMAT_WARNING`).

### Honest limits

- **Country matters much less than language.** In our test, English reviews in the US and the UK overlapped by 87 of 150, and German reviews in Germany and the US overlapped by 150 of 150. Add languages to get more reviews. Extra countries mostly return duplicates, which are removed and not charged.
- Google only lists written reviews. The app's rating count is far larger than what any scraper can list (Instagram on 23 Sep 2026: 169,380,459 ratings, 4,549,231 reviews).
- The source is the public Play Store web page's own review endpoint (the same one the page uses when you scroll). It is undocumented, which is why every response is validated (see above).
- Google Play only. Apple App Store is the separate [App Store Reviews Scraper](https://apify.com/thequietstack/app-store-reviews).

### Pricing (pay per event)

- Actor start: small flat fee per run
- Per scraped review: charged only for reviews written to the dataset. No charge for duplicates, filtered-out reviews or languages without reviews.

# Actor input Schema

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

Google Play URLs (play.google.com/store/apps/details?id=com.whatsapp) or bare package names (com.whatsapp).

## `searchTerms` (type: `array`):

App names or keywords, resolved with the Google Play search (first language and country below).

## `appsPerSearchTerm` (type: `integer`):

How many top search results to scrape for each search term.

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

Google Play shows each language its OWN set of reviews (en, de, es, pt, fr, ja ...). More languages = more reviews, merged and deduplicated. Codes: en, es, pt, de, fr, it, ru, tr, ar, ja, ko, zh-TW, zh-CN, id, vi, th, hi, pl, nl, uk ...

## `allLanguages` (type: `boolean`):

Ignore the list above and scrape all 49 Play Store review languages. Languages without reviews cost nothing. With a review limit, the limit is shared fairly so every language with reviews is represented.

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

Two-letter country codes. The country changes the review set much less than the language (English: US and UK overlap by about 60%). One country is usually enough.

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

Newest is required for an efficient date filter.

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

e.g. \[1, 2] for complaints only. Filtered on Google's side, so a 1-star-only run does not page through 5-star reviews. Empty = all ratings.

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

With sort Newest, paging stops as soon as reviews get older than this date.

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

Optional upper bound for the review date.

## `versions` (type: `array`):

Exact version ("2.26.36.74") or a prefix ("2.26" matches 2.26.x). Empty = all versions.

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

Keep only reviews that have a developer reply. Filtered-out reviews are not charged.

## `onlyWithText` (type: `boolean`):

Drop reviews with an empty text body.

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

Stop an app after this many reviews. Empty = no per-app limit.

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

The run stops cleanly at this number. You are never charged for more reviews than this.

## `concurrency` (type: `integer`):

How many language/country streams are fetched at the same time.

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

Requests go out directly first. If Google answers 429 or 5xx, the retry goes through this proxy with a fresh IP.

## Actor input object example

```json
{
  "apps": [
    "https://play.google.com/store/apps/details?id=com.whatsapp",
    "com.instagram.android"
  ],
  "searchTerms": [
    "notion",
    "duolingo"
  ],
  "appsPerSearchTerm": 1,
  "languages": [
    "en",
    "es",
    "de"
  ],
  "allLanguages": false,
  "countries": [
    "us"
  ],
  "sortBy": "newest",
  "ratings": [
    1,
    2
  ],
  "versions": [
    "2.26"
  ],
  "onlyWithDeveloperReply": false,
  "onlyWithText": false,
  "maxReviews": 5000,
  "concurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One flat row per review: stars, text, app version, ISO date, language, thumbs-up, developer reply.

## `summary` (type: `string`):

Reviews per language, duplicates removed, filtered-out counts, languages without reviews, and dataSourceCheck (OK or FORMAT\_WARNING).

# 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": [
        "https://play.google.com/store/apps/details?id=com.whatsapp"
    ],
    "languages": [
        "en",
        "es",
        "de"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("thequietstack/google-play-reviews").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": ["https://play.google.com/store/apps/details?id=com.whatsapp"],
    "languages": [
        "en",
        "es",
        "de",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("thequietstack/google-play-reviews").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": [
    "https://play.google.com/store/apps/details?id=com.whatsapp"
  ],
  "languages": [
    "en",
    "es",
    "de"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call thequietstack/google-play-reviews --silent --output-dataset

```

## MCP server setup

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

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/LEStva9APJhymq0kM/builds/Wnv1tWZPXN9WDhNnG/openapi.json
