# Google Play Reviews Scraper & Release Health (`steadywren/google-play-reviews-scraper`) Actor

Google Play reviews scraper: Play Store reviews of any Android app (rating, text, app version, developer reply) at $0.10 per 1,000, plus an optional app report ($0.002 each): rating by version with bad-release alerts, reply rate, complaint topics and spikes, installs per day, listing changes.

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

## Pricing

from $0.10 / 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.

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 & Release Health

Google Play reviews scraper for your app and your competitors: export the **Play Store reviews** of any Android app (rating, text, app version, developer reply) **plus an app report** per app - rating by app version with **bad-release alerts**, **how fast the developer answers** and which angry reviews are still unanswered, **complaint topics and spikes**, **installs per day**, **listing and price changes** between runs, and a **comparison with similar apps**. Android app reviews cost **$0.10 per 1,000**, the same as plain review scrapers; each app report costs **$0.002** and can be switched off.

![Google Play Reviews Scraper & Release Health - example output](https://steadywren.com/assets/screens/google-play-reviews-scraper.png)

### Why this Actor

Other Google Play scrapers give you raw reviews and leave the analysis to you. This one does it for you: reviews cost the same as theirs ($0.10 per 1,000), and the analysis comes in one app report per app ($0.002 each):

- **Release health**: which app version made users unhappy, and whether the newest version fixed the complaints of the previous one.
- **Developer reply analytics**: reply rate, median reply time and the most liked 1-2 star reviews still waiting for an answer.
- **Change tracking**: installs per day, new ratings, rating change, listing changes (title, descriptions, screenshots, icon) and price changes since your last run, with alerts.
- **Every extra can be switched off**: turn the analytics off and you get a plain, fast review scraper - and no app report charge.

### What you get

- **Reviews**: rating, text, date, app version, thumbs up, the developer's reply with its date, and Google's per-feature ratings (`criteria`). No limit of 500 per app - up to 15,000 reviews per app and run. Reviewer names are never collected.
- **Filters**: star ratings, date range, keywords, answered / unanswered by the developer, minimum thumbs up, sort by newest, relevance or rating.
- **App report** (one per app, in its own **App reports** table in the Output tab): store rating and star counts, exact installs, price and in-app price range, content rating, last update and "What's new", plus the analytics below.
- **Release health** (`releaseHealth`): rating and top complaints for each app version with at least 3 reviews, the change against the previous version, `badRelease: true` when a version drops the rating by 0.5 stars or more, release cadence, and `fixCheck`: complaint topics that went down (`improved`) or up (`worsened`) in the newest version.
- **Developer replies** (`developerReplies`): `replyRate`, `negativeReplyRate` (1-2 stars), `medianReplyHours`, and `unansweredNegative`: the 5 most liked 1-2 star reviews of the last 90 days without a reply.
- **Complaint topics and trends** (`complaintTopics`): every review tagged with `crash`, `bugs`, `login`, `billing`, `ads`, `performance`, `ui` or `feature_request` (English, German, French, Spanish, Ukrainian); top complaints with their share; rating per week; `complaintSpikes` when a topic jumps in the last 7 days.
- **Changes between runs** (`trackChanges`): installs per day, new ratings, rating change, listing changes and price changes since your previous run, and `alerts` such as `bad_release:v2.1`, `complaint_spike:crash`, `rating_drop`, `listing_changed:screenshots`, `price_changed`.
- **Similar apps** (`compareSimilarApps`, off by default): an app report for the apps Google lists as "Similar apps", so you see your real competitors without looking them up.
- **Competitor comparison**: all apps of a run side by side in the `COMPARISON` record (Output tab) when the run has 2 or more apps.

The analytics read the newest 1,000 reviews of each app (`analysisDepth`). They are not output and not charged.

### Example: app report

```json
{
    "type": "app",
    "appId": "com.todoist",
    "appName": "Todoist: To Do List & Calendar",
    "developer": "Todoist Inc.",
    "genre": "Productivity",
    "price": 0,
    "inAppPriceRange": "$0.99 - $149.99 per item",
    "installs": "10,000,000+",
    "installsExact": 49910274,
    "storeRating": 4.6078777,
    "ratingCount": 307104,
    "ratingHistogram": { "1": 13401, "2": 5118, "3": 11875, "4": 27677, "5": 249014 },
    "updatedAt": "2026-11-02T00:38:21.000Z",
    "similarApps": ["todolist.scheduleplanner.dailyplanner.todo.reminders", "com.google.android.apps.tasks", "com.ticktick.task"],
    "reviewsAnalyzed": 1000,
    "recentRating": 3.92,
    "versions": [
        { "version": "v12322", "releasedAt": "2026-10-24T19:54:08.000Z", "notes": null, "reviews": 6, "avgRating": 5, "ratingChange": null, "topComplaints": [] },
        { "version": "v12318", "releasedAt": "2026-10-21T09:24:10.000Z", "notes": null, "reviews": 4, "avgRating": 3.75, "ratingChange": null, "topComplaints": [] }
    ],
    "badRelease": false,
    "releasesLast90Days": 23,
    "avgDaysBetweenReleases": 4,
    "fixCheck": { "version": "v12282", "comparedTo": "v12250", "improved": [], "worsened": [] },
    "replies": {
        "replyRate": 0.9,
        "negativeReplyRate": 0.88,
        "medianReplyHours": 24.9,
        "unansweredNegative": [
            { "reviewId": "…", "rating": 1, "text": "Reminders stopped working after the update.", "date": "2026-09-19T15:57:37.000Z", "version": "v12282", "thumbsUp": 4 }
        ]
    },
    "topComplaints": [{ "topic": "billing", "share": 0.03 }, { "topic": "bugs", "share": 0.03 }, { "topic": "login", "share": 0.02 }],
    "weeklyRating": [{ "weekStart": "2026-10-26T11:36:36.011Z", "reviews": 9, "avgRating": 3.44 }],
    "complaintSpikes": [],
    "changes": { "daysSincePrevious": 1, "installsGrowthPerDay": 6100, "newRatings": 42, "storeRatingChange": 0, "listingChanged": [], "priceChange": null, "inAppPriceRangeChange": null },
    "alerts": []
}
```

Reading it: Todoist answers 90% of reviews (88% of the angry ones) within about a day, ships a build every 4 days, and its newest reviews average 3.92 stars against 4.61 in the store. (Real run, shortened; the review text and the `changes` numbers are illustrative - `changes` is filled from the second run on.)

### Example: review

```json
{
    "type": "review",
    "reviewId": "3e1e45fa-54fa-4cf8-9383-ff0147e7c237",
    "appId": "com.todoist",
    "appName": "Todoist: To Do List & Calendar",
    "language": "en",
    "country": "us",
    "url": "https://play.google.com/store/apps/details?id=com.todoist&hl=en&gl=US",
    "rating": 5,
    "text": "It is the best app I have ever used for doing my tasks.",
    "date": "2026-10-31T12:14:45.000Z",
    "version": "v12326",
    "thumbsUp": 0,
    "replyText": "That means so much to us! Thank you for sharing your experience with us!",
    "replyDate": "2026-11-02T03:04:35.000Z",
    "criteria": [],
    "topics": [],
    "isNew": true,
    "scrapedAt": "2026-11-02T11:36:36.011Z"
}
```

### How much does it cost?

**$0.10 per 1,000 reviews** (the same as plain review scrapers) and **$2 per 1,000 app reports** ($0.002 each; one report per app, none when every analytics option is off), plus a small Actor start fee charged by Apify. Platform compute is included. Example: your app + 3 competitors with 100 reviews each costs about $0.05 per run.

### Use cases

- **Release monitoring**: schedule daily with your app and *Only new reviews*; act on `alerts` with `bad_release` or `complaint_spike`.
- **Support quality**: compare your reply rate and reply time with competitors; work through `unansweredNegative` first.
- **Competitor research and ASO**: add competitors (or turn on *Compare similar apps*) and follow their installs per day, rating, listing changes and prices.
- **Product feedback**: filter reviews by keyword, stars, version or topic (`feature_request`, `crash`, `billing`).

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `apps` | array | Todoist | Google Play URLs or package names (e.g. `com.todoist`). |
| `language` | string | `en` | Language of the reviews (en, de, fr, es, uk...). |
| `country` | string | `us` | Store country for prices and app data. |
| `maxReviewsPerApp` | integer | 100 | Reviews to output per app (0 = reports only), up to 15,000. |
| `sort` | string | `newest` | `newest`, `relevant` or `rating`. |
| `stars` | array | all | Only these star ratings. |
| `dateFrom`, `dateTo` | date | - | Only reviews written in this range (inclusive). |
| `keywords` | array | - | Only reviews mentioning any of these words. |
| `replyFilter` | string | `any` | `withReply` or `withoutReply`. |
| `minThumbsUp` | integer | 0 | Only reviews at least this many users found helpful. |
| `includeReviews` | boolean | `true` | Output one result per review. |
| `releaseHealth` | boolean | `true` | Rating per version, bad release, cadence, fix check. |
| `developerReplies` | boolean | `true` | Reply rate, reply time, unanswered negative reviews. |
| `complaintTopics` | boolean | `true` | Topics on reviews, top complaints, weekly rating, spikes. |
| `trackChanges` | boolean | `true` | Remember each app between runs (key-value store `google-play-review-history` in your account) for changes and alerts. |
| `onlyNew` | boolean | `false` | Output only reviews earlier runs have not returned. |
| `compareSimilarApps` | boolean | `false` | Add reports for Google's "Similar apps" (charged per report). |
| `similarAppsCount` | integer | 3 | Similar apps per app. |
| `analysisDepth` | integer | 1000 | Newest reviews read per app for the analytics (not charged). |
| `proxyConfiguration` | object | off | Not needed usually. |

When every analytics option is off, the Actor is a plain review scraper: no app reports, no extra requests.

### Monitor daily

1. Console -> **Schedules** -> create a schedule for this Actor (or for a saved task with your apps) and let it run daily.
2. Turn on *Only new reviews*: each run outputs only reviews earlier runs did not return (`isNew: true`).
3. Keep *Track changes* on: the app reports then show installs per day, rating and listing changes since the last run and `alerts` such as `bad_release:<version>`, `complaint_spike:<topic>`, `rating_drop`, `listing_changed:<fields>` and `price_changed`.
4. Actor -> **Integrations**: send every finished run to Slack, email, Google Sheets or your own webhook.

### FAQ

**Where are the app reports?** In their own table, so reviews and reports both have clean columns: run page -> Output tab -> **App reports** (or Storage -> Dataset -> `reports`). Reviews stay in the main dataset, which the Export button and the default API endpoint return. Via API: `GET /v2/actor-runs/<runId>` -> `storageIds.datasets.reports` gives the dataset id, then `/v2/datasets/<id>/items`.

**Why is `complaintSpikes` empty (`null`) or `weeklyRating` short?** A spike compares the last 7 days with the 4 weeks before, so the analyzed reviews must reach back 5 weeks; `weeklyRating` lists only weeks the reviews fully cover. For very popular apps 1,000 reviews can cover just a few days - raise `analysisDepth` (up to 5,000, not charged) or run on a schedule.

**Why do the newest versions in `versions` have so few reviews?** Many apps publish a new build every few days, and only a few users review each one. Versions with fewer than 3 reviews are left out, and `ratingChange` and `badRelease` need at least 10 reviews per version. With *Track changes*, daily runs keep counting, so busy versions fill up.

**How is `releasedAt` found?** Google Play does not publish a version history, so it is the date of the first review that mentions the version - close to the release date for apps with many reviews. Versions already out before the oldest analyzed review get no date.

**Why is `recentRating` lower than `storeRating`?** The store rating includes years of in-app rating prompts (mostly 5 stars); written reviews are left more often by unhappy users. The gap and its trend per version are the signal.

**What is `installsExact`?** Google shows installs in buckets ("10,000,000+") but the page also carries a more exact number. Installs per day are computed from it between your runs.

**Is the history shared between my runs?** Yes - all runs and tasks of your account use the key-value store `google-play-review-history`, one record per app, language and country. A manual run marks reviews as seen for a scheduled *Only new reviews* task too. Turn *Track changes* off for one-off runs, or delete the store to start over.

**Why are some reviews without `version`?** Google does not send the version for every review (about 10% in our checks).

**What are `criteria`?** Google's own per-feature ratings attached to some reviews (for example `vaf_app_quality_ads_frequency`). They are passed through as Google sends them.

**How are topics found?** By keywords and phrases in English, German, French, Spanish and Ukrainian. Problem topics count only in reviews of 3 stars or less; `feature_request` counts at any rating.

**Is it legal?** The Actor reads only public Google Play pages - no login. Reviewer names and avatars are not collected. Check Google's terms for your use case.

**Something broke?** Open an issue on the Actor page - we answer within 12 hours.

### More from Steadywren

- [App Store Reviews Scraper](https://apify.com/steadywren/apple-app-store-reviews-scraper) - the same release health and competitor analytics for iOS apps, in any country.
- [Shopify App Store Scraper](https://apify.com/steadywren/shopify-app-store-scraper) - Shopify app reviews with review trends, reply rate, category ranks and change alerts.

**Who builds this?** [Steadywren](https://steadywren.com) - small tools, steady results. More products and custom builds on [steadywren.com](https://steadywren.com).

### Changes

- **2026-11-02:** app reports moved from the main dataset to their own **App reports** table (run dataset `reports`), so both tables have clean columns. If you read reports through the API, use `storageIds.datasets.reports` of the run (see FAQ). Reviews did not move.

### Technical details

- Sources: the public app page (embedded JSON: details, star counts, listing, similar apps) and Google Play's review data (150 reviews per request). Plain HTTP, no browser, no proxy by default.
- Retries: network errors, 5xx, 403 and 429 are retried with backoff; an app that does not exist is skipped with a warning.
- Every run stores a `RUN_SUMMARY` record and fails when no app is found, when requests failed and nothing was delivered, or when the key report fields (`appName`, `storeRating`, `ratingHistogram`) are empty in most results. No new reviews, or no reviews matching the filters, is a successful run.

# Actor input Schema

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

Google Play app URLs or package names (e.g. com.todoist). Add your competitors to get a side-by-side comparison.

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

Two-letter language code (en, de, fr, es, uk...). Google Play returns reviews written in this language.

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

Two-letter country code (us, gb, de...). Sets the store country for prices and app data.

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

Reviews to output per app (you pay per review). 0 = reports only.

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

Order in which Google returns reviews.

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

Only reviews with these ratings. Leave empty for all.

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

Only reviews written on or after this day (YYYY-MM-DD).

## `dateTo` (type: `string`):

Only reviews written on or before this day (YYYY-MM-DD).

## `keywords` (type: `array`):

Only reviews that mention any of these words (case-insensitive).

## `replyFilter` (type: `string`):

Keep reviews by whether the developer answered.

## `minThumbsUp` (type: `integer`):

Only reviews that at least this many users found helpful.

## `includeReviews` (type: `boolean`):

One result per review: rating, text, date, app version, thumbs up, developer reply and Google's feature ratings. Turn off to get only the app reports.

## `releaseHealth` (type: `boolean`):

Rating per app version, bad-release flag (a version rated 0.5+ stars lower than the previous one), release cadence, and "did the fix work": which complaints went down or up in the newest version.

## `developerReplies` (type: `boolean`):

Share of reviews the developer answers (also for 1-2 star reviews), median reply time, and the most liked negative reviews still without a reply.

## `complaintTopics` (type: `boolean`):

Complaint topics (crashes, bugs, login, billing, ads, performance, design, feature requests) with their share, rating per week, and complaint spikes in the last 7 days.

## `trackChanges` (type: `boolean`):

Remember each app in a key-value store "google-play-review-history" in your account: installs per day, new ratings, rating change, listing changes (title, descriptions, screenshots, icon), price changes and alerts. Run on a schedule.

## `onlyNew` (type: `boolean`):

Output only reviews that earlier runs did not return (turns on change tracking). Good for daily schedules.

## `compareSimilarApps` (type: `boolean`):

Also make a report for the apps Google lists as "Similar apps" for each of your apps (no reviews are output for them; each report is charged).

## `similarAppsCount` (type: `integer`):

How many similar apps to add for each app.

## `analysisDepth` (type: `integer`):

Newest reviews read per app for the analytics. They are not output and not charged; more gives better trends but takes longer.

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

Not needed usually. Use Apify Proxy if Google starts blocking requests.

## Actor input object example

```json
{
  "apps": [
    "https://play.google.com/store/apps/details?id=com.todoist"
  ],
  "language": "en",
  "country": "us",
  "maxReviewsPerApp": 100,
  "sort": "newest",
  "replyFilter": "any",
  "minThumbsUp": 0,
  "includeReviews": true,
  "releaseHealth": true,
  "developerReplies": true,
  "complaintTopics": true,
  "trackChanges": true,
  "onlyNew": false,
  "compareSimilarApps": false,
  "similarAppsCount": 3,
  "analysisDepth": 1000,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One item per review (type "review") as JSON. Add ?format=csv or ?format=xlsx for other formats.

## `reports` (type: `string`):

One item per app report (type "app") with the analytics, in its own dataset. Add ?format=csv or ?format=xlsx for other formats.

## `comparison` (type: `string`):

All apps of the run side by side: store vs recent rating, installs per day, latest version, bad release, reply rate and time, top complaint, alerts. Made when the run has 2+ apps.

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

Results, retries and failed requests per error category, and why the run failed if it did.

# 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.todoist"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadywren/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": ["https://play.google.com/store/apps/details?id=com.todoist"],
    "proxyConfiguration": { "useApifyProxy": False },
}

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

```

## MCP server setup

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