# Google Play Reviews Scraper (`rastriq/google-play-reviews-scraper`) Actor

Reviews of any Google Play app by country and language, with developer replies: rating, text, version, date, helpful votes. Author data hashed, emails and phones redacted.

- **URL**: https://apify.com/rastriq/google-play-reviews-scraper.md
- **Developed by:** [Rastriq — Structured data from the world](https://apify.com/rastriq) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.08 / 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/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

**Google Play Reviews Scraper** extracts user reviews from any Google Play app by country and language: star rating, review text, app version, publication date, helpful votes and the **developer reply** when there is one. Give it package names or Play Store URLs and get clean, deduplicated JSON, CSV or Excel. It is a fast Google Play reviews API alternative for sentiment analysis, customer support analytics, competitor tracking and ASO research, with no Google account and no login.

Author names are included and can be hidden with one switch for GDPR (`hideAuthorNames`). A keyed `author_hash` is always output; avatars, profile URLs and raw user ids never are. Developer replies are the developer's own text, as written. Emails and phone numbers typed into a review are redacted.

### What is Google Play Reviews Scraper?

Google Play Reviews Scraper reads the same public review feed the Play Store web page uses and turns it into a flat, consistent dataset. Run it once for a snapshot, or schedule it daily with `sort = recent` and `dateFrom` to collect only new reviews. Pagination is handled for you, 40 reviews per request.

It shares one output contract with [App Store Reviews Scraper](https://apify.com/rastriq/app-store-reviews-scraper), so you can ingest both stores with a single integration.

### What data does Google Play Reviews Scraper extract?

| Field | What it is |
|---|---|
| ⭐ `rating` | Stars, 1 to 5 |
| 📝 `text` | Review body (emails and phones redacted). Google Play reviews have no title, so `title` is `null` |
| 🕒 `published_at` | Publication time, ISO 8601, UTC |
| 💬 `developer_reply`, `developer_reply_at` | The developer's answer, exactly as written, and when it was posted, or `null` |
| 📱 `app_version` | App version the review refers to |
| 👍 `helpful_count` | Helpful votes |
| 🌍 `country`, `lang` | Storefront country (`gl`) and review language (`hl`) you requested |
| 🏷️ `app_id`, `app_name` | Package name and app name |
| 🔑 `review_id` | Durable review id, used to deduplicate |
| 👤 `author_name` | Author display name. `null` if you enable *Hide author names* |
| 🔒 `author_hash` | Keyed HMAC-SHA256 pseudonym of the user id. Stable across runs while the salt is unchanged |
| 🔗 `source_url`, `scraped_at` | Public store page for that country and language, and extraction time (UTC) |
| 🚩 `_quality_*` | Flags for missing text, rating or date. Flagged, never filtered |

Fields the source does not provide are `null`, never invented.

### How to scrape Google Play reviews with Google Play Reviews Scraper

1. Open **Google Play Reviews Scraper** on Apify and click **Try for free**.
2. In **App IDs or URLs**, add package names such as `com.whatsapp` or full Play Store URLs.
3. In **Countries** and **Languages**, choose where and in which language you want the reviews, for example `es` and `es`. Each app x country x language is scraped as its own group.
4. Set **Max reviews** and **Sort**: `recent` for newest first, `helpful` for the most helpful first.
5. Optionally set **Reviews since**. With `recent`, the run stops as soon as it reaches older reviews.
6. Click **Start** and download the results as JSON, CSV, Excel or XML, or read them through the API.

#### Input parameters

| Parameter | Type | Description |
|---|---|---|
| `appIds` | array, required | Package names or Play Store URLs |
| `countries` | array | Country codes (`gl`). Empty: the URL's, else `us` |
| `languages` | array | Review language filter (`hl`). Empty: the URL's, else `en` |
| `maxReviews` | integer | Max per app x country x language. If empty, 100 |
| `sort` | `recent` or `helpful` | If empty, `recent` |
| `dateFrom` | date `YYYY-MM-DD` | Only reviews published on or after this date (UTC) |
| `hideAuthorNames` | boolean | If on, `author_name` is `null` in every row (GDPR). Default off |

#### Example input

```json
{
  "appIds": ["com.whatsapp"],
  "countries": ["es"],
  "languages": ["es"],
  "maxReviews": 200,
  "sort": "recent"
}
```

### Output example

```json
{
  "review_id": "00000000-0000-4000-8000-00000000a001",
  "store": "google_play",
  "app_id": "com.example.app",
  "app_name": "Example App",
  "country": "es",
  "lang": "es",
  "rating": 1,
  "title": null,
  "text": "The app crashes when I open the chat.",
  "author_hash": "3f1c0c5a0a6d6b7e9d2b8f4c1a7e5d3b9c0f2a6e8d4b1c7a5e3f9d0b2c4a6e81",
  "author_name": "Jane Example",
  "app_version": "2.26.43.76",
  "published_at": "2026-11-08T11:20:26Z",
  "developer_reply": "Thanks for letting us know, please contact support so we can help.",
  "developer_reply_at": "2026-11-09T04:53:20Z",
  "helpful_count": 3,
  "source_url": "https://play.google.com/store/apps/details?id=com.example.app&hl=es&gl=ES",
  "scraped_at": "2026-11-09T10:00:00Z",
  "ext_pii_redactions": 0,
  "ext_sort": "recent",
  "ext_author_hash_weak": false,
  "_quality_missing_text": false,
  "_quality_missing_rating": false,
  "_quality_missing_published_at": false,
  "_quality_missing_app_name": false,
  "_quality_bad_number": false,
  "_quality_pii_redacted": false
}
```

Every run also writes a `SUMMARY` record with, for each app, country and language: reviews scanned, emitted and dropped, pages read and the reason it stopped.

### How much does it cost to use Google Play Reviews Scraper?

Google Play Reviews Scraper uses pay-per-event pricing: you pay per review delivered, plus a negligible amount of compute. Start with 10 reviews to see the exact bill, and set a maximum charge per run in the Apify Console to cap spending. Because every app x country x language is its own group, the cost of a run is simply the number of reviews you ask for.

### Privacy & GDPR

- **Author name.** `author_name` is the display name published with the review. If you want to minimise personal data, switch on **Hide author names** (`hideAuthorNames`): every row then has `author_name = null`.
- **Author hash.** `author_hash` is a keyed pseudonym: HMAC-SHA256 of the author id, computed with the secret `AUTHOR_HASH_SALT` of the Actor. It is stable across runs (as long as the salt does not change), so you can count repeat reviewers, but it is pseudonymisation, not anonymisation: whoever holds the salt can recompute it, and if no salt is set the Actor flags every row with `ext_author_hash_weak = true`.
- **Never output.** Avatars, profile URLs and raw author ids are never output, in either mode. Emails and phone numbers written inside the review text are redacted (`[email]`, `[phone]`). Developer replies (`developer_reply`) are the developer's own text, exactly as written.
- **Your responsibility.** Review text is free text and may contain personal information. You remain responsible for your lawful basis, retention and use of the data under GDPR and the store's terms.

Google Play Reviews Scraper only collects review data that is publicly visible on Google Play.

### FAQ

**Does Google Play Reviews Scraper return developer replies?**
Yes, in `developer_reply` and `developer_reply_at`, when the developer answered. Most reviews have no reply.

**Why is `title` always null?**
Google Play reviews do not have a title.

**What does the language filter do?**
`hl` filters the reviews by their language and `gl` selects the country. Checked live on 2026-11-09 for `com.whatsapp` with `gl=ES`: `hl=es` and `hl=en` returned 40 reviews each and shared none of them, the first set in Spanish and the second in English and other languages. Reviews that still match several groups are deduplicated by `review_id`, and a group that keeps returning only already-seen reviews stops after 3 pages.

**What happens if Google blocks a request?**
The Actor retries with backoff and then switches to an Apify datacenter proxy. If one app, country or language keeps failing, the others still run. The run always ends cleanly with a `SUMMARY` record: `completed`, `no_results`, `partial` (some groups failed) or `failed` (all of them), with a `stopped_reason` per group.

**How do I get only new reviews each day?**
Schedule the Actor with `sort = recent` and `dateFrom` set to yesterday.

### Related Actors

- [App Store Reviews Scraper](https://apify.com/rastriq/app-store-reviews-scraper): same output contract for iOS apps. Limited to 500 reviews per country by Apple.

# Changelog

This Actor's version history is a separate document: https://apify.com/rastriq/google-play-reviews-scraper/changelog.md

# Actor input Schema

## `appIds` (type: `array`):

Package names (<code>com.whatsapp</code>) or Play Store URLs (<code>https://play.google.com/store/apps/details?id=com.whatsapp</code>). One per line.

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

Storefront country codes (ISO 3166 alpha-2), e.g. <code>es</code>, <code>us</code>. Empty = country in the URL, else <code>us</code>.

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

Review language filter (<code>hl</code>), e.g. <code>es</code>, <code>en</code>, <code>pt-br</code>. Empty = language in the URL, else <code>en</code>. Each app x country x language is scraped separately.

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

Max reviews per app x country x language. If empty, 100.

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

Order of the reviews. If empty, <code>recent</code>. <code>dateFrom</code> stops early only with <i>recent</i>.

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

Only reviews published on or after this date (UTC), YYYY-MM-DD. With <i>recent</i> order the run stops as soon as older reviews appear.

## `hideAuthorNames` (type: `boolean`):

Replace author names with null (author_hash is kept) to minimise personal data under GDPR.

## Actor input object example

```json
{
  "appIds": [
    "com.whatsapp"
  ],
  "countries": [
    "es"
  ],
  "languages": [
    "es"
  ],
  "maxReviews": 10
}
```

# Actor output Schema

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

No description

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

No description

# 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 = {
    "appIds": [
        "com.whatsapp"
    ],
    "countries": [
        "es"
    ],
    "languages": [
        "es"
    ],
    "maxReviews": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("rastriq/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 = {
    "appIds": ["com.whatsapp"],
    "countries": ["es"],
    "languages": ["es"],
    "maxReviews": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("rastriq/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 '{
  "appIds": [
    "com.whatsapp"
  ],
  "countries": [
    "es"
  ],
  "languages": [
    "es"
  ],
  "maxReviews": 10
}' |
apify call rastriq/google-play-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rastriq/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/Yx6UXWetv6A7IpKqL/builds/yPg0hWMNJILEQFaaW/openapi.json
