# Google Play Scraper $0.02/1K | Reviews, Replies & App Search (`apivault_labs/google-play-reviews-scraper`) Actor

Collect Google Play review text, star ratings, dates, versions and developer replies. Paginate large review exports, filter dates and ratings, look up app details or search Android apps by keyword.

- **URL**: https://apify.com/apivault_labs/google-play-reviews-scraper.md
- **Developed by:** [Apivault Labs](https://apify.com/apivault_labs) (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.02 / 1,000 useful google play row delivereds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 — API Vault](https://raw.githubusercontent.com/apivault-labs/apivault-labs/5f1007a5432eaf647502e565545573ccd5619193/assets/google-play-reviews-scraper/readme-cover-generated-v1.png)

## Google Play Reviews Scraper — reviews, replies & app insights

Turn Android app feedback into a useful research dataset. Export public **review text, star ratings, dates, app versions, helpful votes and developer replies**. Investigate low-star feedback, find unanswered complaints, compare apps or prepare your own review analysis.

**$0.02 per 1,000 useful delivered rows**, on every Apify plan, plus platform usage. No Actor-start event. App context and delivered-sample analytics add no result events.

No Google login, Play Console access or external data API key is required. An Apify account/token is needed to call the Apify API. Each review is a separate row. Apple App Store collection and official category charts are outside this product.

### Quick start: export 100 reviews

```json
{"mode":"reviews","appInputs":["com.whatsapp"],"country":"us","language":"en","maxReviews":100}
```

Each delivered review is a separate row, rather than an app summary containing an empty reviews array. Set a small limit first to check whether the chosen locale gives you the feedback you need.

### What you can collect

| Mode | Useful output | Typical use |
|---|---|---|
| `reviews` | Review text, stars, dates, votes, app versions and developer replies | Product feedback, issue discovery, review exports |
| `apps` | App title, developer, description, rating counts, installs labels, category, pricing and public developer links | Competitor research and app catalog enrichment |
| `search` | Keyword listings with observed search positions | Android app discovery and ASO research |

Search positions describe the returned keyword page. They are not official category rankings. Google decides how many listings it exposes; the search limit is an upper bound, not guaranteed coverage.

### Choose a useful workflow

| Your goal | Suggested input | What to inspect |
|---|---|---|
| Build a review research dataset | `reviews`, explicit locale, larger `maxReviews` | Dataset, counts and source limitations |
| Find unanswered negative feedback | `ratings: [1, 2]`, `replyFilter: "without_reply"` | Delivered text and reply statistics |
| Investigate an app release | `appVersions`, optional dates and keywords | Exact source-reported version and feedback |
| Study developer responses | `replyFilter: "with_reply"` | Review/reply text and timestamps |
| Research competing Android apps | `apps` or `search` | Descriptions, pricing, categories and publisher links |
| Continue a large export | Copy `CHECKPOINT.input` after a controlled stop | Retained page and remaining work |

### Collect thousands of reviews

```json
{"mode":"reviews","appInputs":["com.whatsapp","com.spotify.music"],"maxReviews":10000,"maxResults":20000,"country":"us","language":"en","sort":"newest","maxRunSeconds":3600}
```

The reviews collector follows Google's continuation tokens in source requests of up to 1,000 records and Dataset delivery batches of up to 200 rows, removes repeated review IDs per app, and saves useful rows incrementally. You can request up to 100,000 delivered reviews per app, 1,000 input apps or keywords, and 100,000 total results per run. These are configured ceilings, not a promise that Google exposes every review or that one run reaches the ceiling. Requests are processed sequentially to keep pagination and budgets predictable.

#### Verified collection capacity

The private runtime verification on October 22, 2026 delivered **100,000 unique useful reviews and 100,000 matching result events**. CSV export and the official Python SDK returned the same ordered review IDs. The run took about **8 minutes 13 seconds** at 512 MB; peak memory was approximately 377 MB. One unusable source row was skipped without a result event and reported in the summary.

A separate 5,000-review verification took about **11 seconds**. These are observed runs, not speed guarantees or complete-history claims. Source conditions, locale, app availability, filtering and platform conditions affect future collections. The 100,000-row capacity was demonstrated for one input, not guaranteed for every app.

### Filter low-star, unanswered and version-specific feedback

```json
{"appInputs":["com.spotify.music"],"ratings":[1,2],"replyFilter":"without_reply","keywords":["login","crash"],"minThumbsUp":1,"maxReviews":100}
```

`ratings` accepts several star values. `rating` remains available for one exact star; do not supply conflicting filters. `keywords` uses case-insensitive literal substring matching and accepts a match to any keyword. `appVersions` matches an exact reported version. `replyFilter` accepts `any`, `with_reply`, or `without_reply`; an empty reply counts as no observed reply. Filtered reviews have no result event. Local filters can scan more source pages and consume platform usage even if no reviews match.

### Filter feedback by date and stars

```json
{"mode":"reviews","appInputs":["com.spotify.music"],"rating":1,"dateFrom":"2026-01-01T00:00:00Z","dateTo":"2026-12-31T23:59:59Z","maxReviews":5000,"country":"us","language":"en"}
```

Date boundaries are inclusive. Dates without a timezone use UTC; a date without a time means midnight, so specify the day's ending time if you want the whole day. The date filter is applied locally to returned reviews. A narrow filter can require scanning many pages and may reach the time budget before enough matching rows appear. Review timestamps are Google-provided; this Actor does not infer a missing date.

### App details and app keyword search

```json
{"mode":"apps","appInputs":["https://play.google.com/store/apps/details?id=com.whatsapp","com.spotify.music"],"country":"gb","language":"en"}
```

```json
{"mode":"search","searchTerms":["budget planner","habit tracker"],"maxSearchResults":20,"country":"us","language":"en"}
```

App detail fields include public developer email and website where Google supplies them. Missing fields remain null. Detail mode also preserves source screenshots, header image, video links, developer address and ads flag when supplied. Install labels are public thresholds, and any source-provided install counters are not audited download measurements. This Actor does not estimate revenue.

### Output fields

| Field | Meaning |
|---|---|
| `recordType`, `appId`, `url` | Result type and Android package identity |
| `reviewId`, `content`, `score`, `at` | Public review ID, text, 1–5 stars and review timestamp |
| `userName`, `userImage`, `thumbsUpCount` | Public display name, avatar URL and helpful votes |
| `appTitle`, `developer` | App context on review rows when enabled and available |
| `reviewCreatedVersion`, `appVersion` | App versions reported by the source, if available |
| `replyContent`, `repliedAt` | Developer response and response timestamp, if present |
| `title`, `developer`, `description`, `genre` | App detail metadata; detail mode only |
| `ratings`, `reviews`, `score`, `histogram` | App aggregates in detail mode; not a count of rows available to scrape |
| `searchTerm`, `searchRank` | Query and observed listing position in search mode |
| `country`, `language`, `scrapedAt` | Requested storefront/locale and collection time |

`country` is the requested storefront, not the author's location. `language` selects the source locale and does not translate text or guarantee every review's language. Fields vary by mode; absent source values are not filled with invented values.

#### Illustrative review row

This is a schema illustration, not captured customer feedback. Missing reply/version fields remain null.

```javascript
{
  recordType: "review",
  appId: "com.example.app",
  reviewId: "illustrative-review-id",
  content: "Illustrative review text.",
  score: 2,
  at: "2026-10-01T12:00:00Z",
  appVersion: null,
  replyContent: null,
  country: "us",
  language: "en"
}
```

### App context and sample insights — no extra result events

In reviews mode, `includeAppDetails` defaults to true. App title and developer are attached to delivered reviews when lookup succeeds, and `APPS` stores the source-provided app context and aggregate ratings. Context lookup adds a source request and platform usage, but no additional result event. Its failure records a warning and review collection continues. Disable it for a lighter export.

`INSIGHTS` contains, per app, the delivered sample's star histogram, average rating, developer-reply percentage, observed low-star reviews without replies, helpful-vote total and timestamp range. It describes only delivered reviews that passed your filters, across the continuation chain. It does not infer text sentiment or represent all users. INSIGHTS, APPS, SUMMARY and CHECKPOINT are key-value records without Dataset result charges.

Checkpoint state is compressed to reduce transfer and storage costs. Checkpoints from the previous candidate format cannot be resumed with this build; use the original build for those runs or start a new collection. Controlled-stop continuation remains supported. A hard crash can happen between Dataset delivery and checkpoint persistence; automatic crash recovery and exactly-once delivery are not promised.

### Continue a large or budget-limited run

`SUMMARY` stores delivered counts, fetched review pages, filtered/invalid/duplicate counts, target errors and the final collection status. `CHECKPOINT` stores progress and an `input` object for continuing. After the run has stopped, copy `CHECKPOINT.input` into a new run. It includes `resumeCheckpointStoreId`; retain the same app list, mode, locale, filters and per-app target. You may adjust the per-run `maxResults` and time budget.

The prior checkpoint must belong to this Actor and be accessible to your account. Select its key-value store; only read permission for that selected storage is requested. The Actor reads its own stored checkpoint; inline, user-written row payloads are not accepted. Continuation keeps known delivered IDs and a partially delivered page in a compressed checkpoint, preventing repeats during a normal, controlled limit or budget stop. Do not start multiple continuations from the same checkpoint. Google reviews can change between requests; this is not a frozen snapshot. Only controlled stops produce a resumable checkpoint. Sudden process termination leaves the checkpoint marked running and cannot be resumed automatically; check IDs before retrying and combining interrupted exports. Errors skip the affected target and are recorded unpaid; retry those targets separately.

### Pricing and complete run costs

**$0.02 per 1,000 useful delivered rows** for reviews, app details and search listings, on all plans. **Apify compute, storage and transfer usage is additional and paid by the user.** There is no Actor-start event. Errors, diagnostics, filtered/invalid rows and removed duplicates have no result event. APPS, INSIGHTS, SUMMARY and CHECKPOINT are separate key-value records without result events.

| Useful delivered rows | Result-event cost |
|---:|---:|
| 100 | $0.002 |
| 1,000 | $0.02 |
| 10,000 | $0.20 |
| 100,000 | $2.00 |

The verified 100,000-review export had $2.00 in result fees and about $0.565 in reported platform usage: approximately **$2.565 total, or $0.02565/1,000 rows**. A 5,000-review run was about $0.128 including events and reported usage. These are measured examples and event arithmetic, not an invoice, fixed package price or guarantee. Small or narrowly filtered runs can have higher platform cost per delivered row. Later exports/storage reads and external integrations can add account-level charges.

Check the Pricing tab and set a spending limit before a large export. Apify's automatic Dataset billing controls the result-event budget; do not treat it as a guarantee that every possible platform charge is included in that cap. No blanket claim of cheapest service or superiority over every scraper is made.

### Limits and diagnostics

| Setting | Default | Maximum |
|---|---:|---:|
| `maxReviews` per app | 1,000 | 100,000 |
| `maxResults` per run | 100,000 | 100,000 |
| Input apps / search terms | 1 | 1,000 |
| `maxSearchResults` per keyword | 50 | 250 |
| `maxRunSeconds` | 3,600 | 7,200 |

Set the Apify run timeout at least 60 seconds higher than the collection budget. A source request has a bounded network timeout; the time budget is checked between requests and deliveries. `PARTIAL_LIMIT`, `PARTIAL_TIME` and `PARTIAL_BUDGET` mean rows were preserved but the requested work is unfinished. `PARTIAL_ERRORS` identifies failed targets or skipped unusable source rows; inspect the counts and error list. A platform-level SUCCEEDED status alone does not prove complete source coverage. An empty valid search or a review feed with no matching reviews can finish with zero rows. Invalid input or all targets failing produces a failed run with no fabricated Dataset row.

Google can restrict or change its public endpoints, return fewer records, reorder feedback, or make an app unavailable in a storefront. Review pagination stops on exhaustion, a repeated token, a configured ceiling or a time/spending limit. An endpoint or parser failure is not represented as a successful complete review history. No proxy is required by this candidate; source availability from your selected region may vary.

### API, Python and workflow integrations

Use exact Actor ID **`OfCoojvD9eGIdwxuz`** with the [Apify API](https://docs.apify.com/api/v2/), [official Python client](https://docs.apify.com/api/client/python/) or [official JavaScript client](https://docs.apify.com/api/client/js/).

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("OfCoojvD9eGIdwxuz").call(
    run_input={
        "mode": "reviews",
        "appInputs": ["com.whatsapp"],
        "country": "us",
        "language": "en",
        "maxReviews": 100,
    },
    build="latest",
    memory_mbytes=512,
    timeout_secs=3660,
    max_total_charge_usd=0.01,
)
if run is None:
    raise RuntimeError("The run did not return metadata")
for review in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(review["reviewId"], review["score"], review["content"])
```

Keep your token in an environment variable. The example selects the current production build. Use your Apify account token and review the run spending limit before starting.

The Dataset supports JSON, CSV and Excel exports through the console/API. n8n, Make or your own workflow can call the standard Apify API. No dedicated API Vault Google Play n8n node or Python package is advertised: the historical App Store integration points to a different product. No dedicated marketplace package is required to use the standard Apify API.

### FAQ

**Does it return every review counted on the app page?** No. Star ratings include ratings without text, and Google's public review feed has its own locale, relevance and availability limits. A configured ceiling is not a completeness guarantee.

**Can it collect hundreds or thousands at once?** Yes, it follows review pagination and writes individual records. Start with a small sample and raise both the review limit and run budget for a larger export. A 100,000-row export has been verified on this runtime; source coverage and timing can differ for another app or locale.

**Can I collect developer replies?** Yes, when Google includes reply text and timestamps for that review. Missing replies stay null.

**Does search paginate through all Android apps?** No. Search reads the public keyword results exposed by Google, up to your listing limit. Only review collection promises continuation-token pagination.

**Are diagnostics billed?** No. Only useful Dataset rows trigger the single automatic result event. The key-value summary, errors and checkpoint do not produce result events.

**Can I resume a stopped export?** Yes, after a controlled collection limit, time or spending stop. Use CHECKPOINT.input after the earlier run stops. Keep the same collection inputs; do not resume one checkpoint concurrently. Sudden termination has the checkpoint caveat described above.

**Can I schedule daily monitoring?** You can schedule runs through Apify and use dates/IDs in your workflow. A new independent run does not automatically deduplicate against every prior run. Controlled continuation is a separate feature. This Actor does not send external alerts.

**Is this an official Google product?** No. API Vault collects public Google Play data independently and is not affiliated with Google. The generated cover/avatar are illustrative artwork, not platform logos or screenshots of captured customer data.

### Python client and n8n workflow

Use the thin [Python client](https://github.com/apivault-labs/apivault-labs/tree/main/packages/apivault-google-play-reviews-scraper) or install it from [PyPI](https://pypi.org/project/apivault-google-play-reviews-scraper/):

```bash
pip install apivault-google-play-reviews-scraper==0.1.0
```

The client starts this hosted Actor through the Apify API and reads its dataset. An Apify account and your own API token are required. Actor result charges and infrastructure usage follow the current pricing. The client package has no subscription of its own. Set both Actor collection limits and run charge caps; the dataset download limit does not limit paid collection.

[n8n node source and manual workflow](https://github.com/apivault-labs/apivault-labs/tree/main/community-nodes/n8n-nodes-apivault-google-play-reviews-scraper) are available on GitHub. The workflow is inactive and has no embedded credentials. Its Run operation starts a paid Actor run; Read Existing Run reads a previous run without starting another. npm version0.1.0 currently awaits npm staged-release approval; do not install the placeholder0.0.0-stage as an operational node. npm publication, when approved, does not establish n8n verification or availability in n8n Cloud.

# Changelog

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

# Actor input Schema

## `mode` (type: `string`):

Reviews are separate rows. Apps returns full metadata. Search returns keyword listings, not chart ranks.

## `appInputs` (type: `array`):

Package IDs or exact HTTPS Google Play details URLs. Up to 1000 inputs; duplicate inputs are removed.

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

Used only in search mode, up to 1000 terms.

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

Lowercase storefront code, not the reviewer location.

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

Requested Google Play locale; does not guarantee the language of every review.

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

Source order. Newest is recommended for review monitoring.

## `rating` (type: `integer`):

Optional exact star filter, 1 to 5.

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

Optional ISO 8601, for example 2026-01-01T00:00:00Z. Date-only values mean midnight UTC.

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

Optional ISO 8601. To include a whole day, specify its ending time.

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

Overall per-app delivery ceiling across a continuation chain; source availability may be lower.

## `maxSearchResults` (type: `integer`):

Upper limit from the public search page. Google may return fewer; no search pagination is promised.

## `maxResults` (type: `integer`):

Stop this run after this many useful rows; resume remaining work from CHECKPOINT.

## `maxRunSeconds` (type: `integer`):

Soft time budget checked between requests/results. Set Apify Timeout at least 60 seconds higher.

## `resumeCheckpointStoreId` (type: `string`):

Optional checkpoint store of a controlled stopped run of this Actor. Copy CHECKPOINT.input; keep filters unchanged. No concurrent resume.

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

Optional multiple stars, e.g. \[1,2]. Do not conflict with the single rating field.

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

Keep all reviews, only reviews with a developer reply, or only reviews without one.

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

Optional case-insensitive literal matches; any keyword may match. Up to 30.

## `appVersions` (type: `array`):

Optional exact app version allow-list; missing versions do not match.

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

Only deliver reviews with this many helpful votes or more.

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

In reviews mode, fetch app title/developer plus app aggregates for APPS. No result event for context. Extra source/platform usage applies; context failure does not discard reviews.

## Actor input object example

```json
{
  "mode": "reviews",
  "appInputs": [
    "com.whatsapp"
  ],
  "searchTerms": [
    "budget planner"
  ],
  "country": "us",
  "language": "en",
  "sort": "newest",
  "maxReviews": 1000,
  "maxSearchResults": 50,
  "maxResults": 100000,
  "maxRunSeconds": 3600,
  "replyFilter": "any",
  "minThumbsUp": 0,
  "includeAppDetails": true
}
```

# Actor output Schema

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

No description

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

No description

## `checkpoint` (type: `string`):

No description

## `insights` (type: `string`):

No description

## `apps` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("apivault_labs/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("apivault_labs/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 '{}' |
apify call apivault_labs/google-play-reviews-scraper --silent --output-dataset

```

## MCP server setup

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