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

Scrape Google Play app reviews in bulk: many apps per run, any country & language, star and date filters, developer replies, app version and thumbs-up counts, plus optional app rating histogram & installs. Fast, no login, $0.09 per 1,000 reviews.

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

## Pricing

Pay per event

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

**Get thousands of Google Play app reviews in seconds. Scrape many apps in one run, choose the country and language, filter by star rating and date, and get developer replies, app versions and helpful-vote counts.**

Paste package IDs or Play Store links and get clean, flat JSON, CSV or Excel. You don't need a login, a Google account or a proxy.

### What can you use it for?

- **App review monitoring.** Track new 1★ and 2★ reviews after each release with `reviewsNewerThan: "7 days"` on a schedule.
- **Competitor research.** Pull reviews for your app and 5 competitors in one run and compare complaints and feature requests.
- **Release QA.** Group reviews by `appVersion` to see whether a release caused a wave of crashes or complaints.
- **Customer support analytics.** Measure developer reply rate and reply time (`hasDeveloperReply`, `developerRepliedAt`).
- **Sentiment analysis and LLM pipelines.** Feed reviews to an LLM for topic clustering, summaries or sentiment. AI agents can call the Actor through the [Apify MCP server](https://mcp.apify.com) and get structured reviews back.
- **Market research datasets.** Collect localized reviews (e.g. `country: "de"`, `language: "de"`) for many apps.

### What data can you get?

Each review is one record:

| Field | Description |
|---|---|
| `appId`, `appTitle` | Package ID and app name |
| `reviewId`, `reviewUrl` | Unique review ID and a link to the review |
| `userName` | Reviewer's public display name |
| `rating` | Stars, from 1 to 5 |
| `text` | Review text |
| `reviewedAt` | Review date (ISO 8601, UTC) |
| `thumbsUpCount` | How many users marked the review as helpful |
| `appVersion` | App version the review was written for |
| `hasDeveloperReply`, `developerReplyAuthor`, `developerReplyText`, `developerRepliedAt` | The developer's public reply, if there is one |
| `country`, `language`, `sort`, `appUrl`, `scrapedAt` | Context of the scrape |

If you turn on **Include app details record**, you also get one `recordType: "app"` record per app with the title, developer, genre, **average rating, ratings count, review count, star histogram (1–5)**, installs, price, content rating, current version and last update date. App records are free.

### How to use it

1. Add one or more apps: package IDs like `com.spotify.music`, or Play URLs like `https://play.google.com/store/apps/details?id=com.duolingo`.
2. Optionally set the country, language, sort, star filter, date cutoff and limits.
3. Click **Start** and download the results as JSON, CSV, Excel or HTML, or read them through the API.

### Input example

```json
{
  "apps": ["com.spotify.music", "https://play.google.com/store/apps/details?id=com.duolingo"],
  "maxReviewsPerApp": 2000,
  "maxItems": 10000,
  "sort": "newest",
  "stars": ["1", "2"],
  "reviewsNewerThan": "30 days",
  "country": "us",
  "language": "en",
  "includeAppDetails": true
}
```

- **sort**: `newest` (default), `most_relevant` or `rating` (highest first).
- **stars**: any combination of `"1"` to `"5"`. Leave it empty to get all ratings.
- **reviewsNewerThan**: a date (`2026-01-31`) or a relative value (`7 days`, `2 weeks`, `6 months`). With `newest`, the scraper stops as soon as it reaches older reviews, so you only pay for what you need.
- **maxReviewsPerApp** / **maxItems**: the per-app limit and the total limit for the run.

### Output example

This is a real record from a test run:

```json
{
  "recordType": "review",
  "appId": "com.spotify.music",
  "appTitle": "Spotify: Music and Podcasts",
  "reviewId": "a9d7c1d4-5dce-48a7-8ba4-ac87cc97702c",
  "userName": "Wisdom Eshiet",
  "rating": 4,
  "text": "i love Spotify but please increase the daily search from 3 to 5 or more",
  "reviewedAt": "2026-10-08T13:43:12Z",
  "thumbsUpCount": 0,
  "appVersion": "9.1.84.2231",
  "hasDeveloperReply": true,
  "developerReplyAuthor": "Spotify AB",
  "developerReplyText": "Hi. We appreciate your feedback. If you'd like to play music on demand, 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.",
  "developerRepliedAt": "2026-10-08T23:47:45Z",
  "reviewUrl": "https://play.google.com/store/apps/details?id=com.spotify.music&reviewId=a9d7c1d4-5dce-48a7-8ba4-ac87cc97702c",
  "appUrl": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us",
  "country": "us",
  "language": "en",
  "sort": "newest",
  "scrapedAt": "2026-10-09T13:48:34.582622Z"
}
```

App details record (with `includeAppDetails: true`):

```json
{
  "recordType": "app",
  "appId": "com.duolingo",
  "appTitle": "Duolingo: Learn Languages",
  "developer": "Duolingo",
  "genre": "Education",
  "rating": 4.735219,
  "ratingsCount": 50368482,
  "reviewsCount": 962871,
  "histogram": { "1": 1020609, "2": 370446, "3": 1158155, "4": 5826449, "5": 41992773 },
  "installs": "500,000,000+",
  "minInstalls": 500000000,
  "realInstalls": 981438421,
  "price": 0.0,
  "currency": "USD",
  "free": true,
  "containsAds": true,
  "contentRating": "Everyone",
  "released": "May 29, 2013",
  "lastUpdatedAt": "2026-10-06T18:53:36Z",
  "version": "Varies with device",
  "summary": "Make language learning fun with Spanish, French, English, chess, math & music.",
  "appUrl": "https://play.google.com/store/apps/details?id=com.duolingo&hl=en&gl=us",
  "country": "us",
  "language": "en",
  "scrapedAt": "2026-10-09T13:48:34.447933Z"
}
```

The run also saves a `RUN_SUMMARY` record in the key-value store. It lists the review count and any error for each app, such as an invalid ID or an app that doesn't exist.

### Pricing

**$0.09 per 1,000 reviews.** You pay only for reviews that are saved, and app details records are free. Use `maxItems` or the run's maximum cost setting to cap your spend. The scraper stops cleanly when it reaches either limit.

### Performance

In tests, 4,321 Spotify reviews took about 15 seconds. Each request returns up to 200 reviews, and the scraper follows Google's pagination tokens until it reaches your limit, the date cutoff or the last review.

### FAQ

**Is it legal to scrape Google Play reviews?**
The Actor collects only publicly visible data that anyone can see on play.google.com without logging in: review text, star rating, date, the reviewer's public display name and the developer's reply. It doesn't collect emails, phone numbers or private data. Your use of the data must still comply with the laws that apply to you (e.g. GDPR) and Google's terms. If you're unsure, ask a lawyer.

**How many reviews can I get per app?**
As many as Google Play shows. Pagination works to the end of the list; one test downloaded every review of an app back to 2019. Google Play lists only reviews that contain text, so star-only ratings are not included. The `histogram` in the app record covers all ratings.

**Why are the reviews in a different language than I expected?**
Google Play mostly returns reviews written in the selected `language` for the selected `country` storefront. Change both to get localized reviews.

**Can I filter by date with "Most relevant" sorting?**
Yes, but it's slower. Relevance order isn't chronological, so the scraper has to scan many reviews and stops after scanning 2,000 reviews or 20× your per-app limit, whichever is larger. Use `newest` for fast and complete date filtering.

**What happens with an invalid or removed app?**
The scraper logs it, records it in `RUN_SUMMARY` and continues with the other apps. One bad ID never breaks the run.

**Do I need a proxy?**
Usually not. The Actor uses Google Play's public web endpoints and retries automatically with backoff on rate limits and server errors. If you scrape very large volumes and see repeated 429 errors, turn on Apify Proxy in the input.

### Limitations

- Only reviews that contain text are available. This is a Google Play limitation.
- The star filter with several values fetches each rating in turn, and the ratings share the per-app limit.
- `appVersion` is empty for some reviews when Google doesn't show it, for example older reviews.
- The Actor uses Google Play's internal web API, the same one the Play website uses. If Google changes it, the Actor needs an update.

# Actor input Schema

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

One or more apps. Use the package ID (e.g. com.spotify.music) or the full Google Play URL (https://play.google.com/store/apps/details?id=com.spotify.music).

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

Maximum number of reviews to save for each app. Thousands per app are supported (the scraper paginates automatically).

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

Hard cap on the total number of reviews saved in this run across all apps. Protects your budget.

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

Order in which Google Play returns reviews. 'Newest' is required for efficient date filtering.

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

Only return reviews with these star ratings. Leave empty for all ratings. With several values, ratings are fetched one after another and share the per-app limit.

## `reviewsNewerThan` (type: `string`):

Only save reviews posted on or after this date. Absolute (2026-01-31) or relative (e.g. '30 days', '2 weeks', '6 months'). With sort 'Newest' the scraper stops as soon as it reaches older reviews.

## `country` (type: `string`):

Two-letter country code of the Google Play storefront (e.g. us, gb, de, in, br). Affects which reviews and app details are shown.

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

Language code (e.g. en, de, es, pt-BR, ja). Google Play mainly returns reviews written in this language.

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

Also save one record per app (recordType = 'app') with title, developer, average rating, rating count, star histogram, installs, price, version and last update. Not charged as a review.

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

Optional. Usually not needed - Google Play's public endpoints work without a proxy. Enable if you see repeated 429 errors.

## Actor input object example

```json
{
  "apps": [
    "com.spotify.music",
    "https://play.google.com/store/apps/details?id=com.duolingo"
  ],
  "maxReviewsPerApp": 50,
  "maxItems": 1000,
  "sort": "newest",
  "stars": [],
  "country": "us",
  "language": "en",
  "includeAppDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `results` (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 = {
    "apps": [
        "com.spotify.music",
        "https://play.google.com/store/apps/details?id=com.duolingo"
    ],
    "maxReviewsPerApp": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("exciting_pawpaw/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.spotify.music",
        "https://play.google.com/store/apps/details?id=com.duolingo",
    ],
    "maxReviewsPerApp": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("exciting_pawpaw/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.spotify.music",
    "https://play.google.com/store/apps/details?id=com.duolingo"
  ],
  "maxReviewsPerApp": 50
}' |
apify call exciting_pawpaw/google-play-reviews-scraper --silent --output-dataset

```

## MCP server setup

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