Google Play Reviews Scraper | Low-Star & Replies
Pricing
from $0.05 / 1,000 reviews
Google Play Reviews Scraper | Low-Star & Replies
Google Play reviews API for Android app feedback. Export review text, ratings, dates, versions and developer replies to JSON/CSV. Filter low-star reviews, dates and keywords across apps and country/language locales. Actor-run resources are included in the review price.
Pricing
from $0.05 / 1,000 reviews
Rating
0.0
(0)
Developer
tingyou333 zhuang
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
6 days ago
Last modified
Categories
Share
Google Play reviews API for Android app feedback. Export review text, ratings, dates, versions and developer replies to JSON/CSV. Filter low-star reviews, dates and keywords across apps and country/language locales. Actor-run resources are included in the review price.
Try the prefilled example · Inspect sample JSON before signing in · Download sample CSV
Choose your first workflow
| Goal | Start here |
|---|---|
| Inspect low-star Android app feedback | Open the prefilled example, inspect the input and price, then Start |
| Integrate CSV/JSON into your own script | Step-by-step guide |
| Call this named tool from an AI assistant | Direct MCP setup |
What this adds: Batch apps and locales with rating/date/text filters, duplicate suppression and documented migration formats. Actor-run resources are included, with no separate start fee.
Replace appIds with package IDs, then choose country, language and ratingFilter. The sample requests only scores 1 and 2, with a total limit of five.
{"appIds": ["com.whatsapp"],"country": "us","language": "en","ratingFilter": [1,2],"maxReviews": 5}
The September 27, 2026 (UTC+8) owner check returned 5 non-error data records. The linked preview selects up to three records and a subset of fields. It omits full descriptions and reviewer identities; textExcerpt, hasDeveloperReply, hasCompanyReply, counts and presence flags in previews are derived summaries, not additional Actor fields. Live results can differ. This is sample execution evidence, not proof of complete coverage or customer adoption.
Cost at a glance
| Free plan | Starter / Bronze | Scale / Silver | Business / Gold+ |
|---|---|---|---|
| $0.08 | $0.07 | $0.06 | $0.05 |
Rates per 1,000 delivered reviews. Actor-run resources are included. No separate Actor-start fee or monthly rental. Later storage/export and external services can have account-level charges.
Five delivered reviews cost $0.00040 at the Free-plan rate, including Actor-run resources and with no separate start fee.
The Console example has a $0.03 Actor-event cap, 256 MB memory and a 240-second timeout. Actor-run resources are included; downstream services can charge separately. “Try for free” uses available account credits. Check the live Pricing tab for your account rate.
Coverage to know: Country and language select query locales; they do not translate or classify each review. Reply/version fields may be absent. Low-star exports are not representative of all customers; filtering may require extra source requests.
Full workflow guide · Python starter ZIP · Compare all ten workflows
First run from the Input form
The Input form now starts with the small configuration below. Review the target and Pricing tab before Start, then inspect the dataset and coverage diagnostics. Increase the limits after checking the sample. Saved tasks and explicitly supplied API inputs keep their own settings.
{"ratingFilter": [1,2],"maxReviews": 5,"appIds": ["com.whatsapp"],"country": "US","language": "en"}
Guides and full reference
Workflows · Pricing details · Inputs · API · FAQ
Form prefills, schema defaults and empty API input can differ. Use explicit targets and limits; see the technical reference for source and default behavior.
Locale selection and detailed ratings
The Input form offers 52 country and 54 language suggestions, with separate multi-country and multi-language fields. Custom values remain available; the source determines which combinations return data. Country and language select request locales; they do not classify or translate the language of each returned review.
criterias preserves Google's available category ratings as { "criteria": "vaf_app_quality_ads_presence", "rating": 1 } objects. These category-specific ratings are separate from the overall 1–5 review score. Missing ratings are not fabricated; an empty list means no parsed category ratings were supplied. Malformed entries generate warnings while valid siblings are retained.
Common workflows
Compare two Android apps
{"appIds": ["com.whatsapp","org.telegram.messenger"],"maxReviews": 40}
Collect English and German locale results
{"appIds": ["com.whatsapp"],"languages": ["en","de"],"maxReviews": 40}
Keep reviews with developer replies
{"appIds": ["com.whatsapp"],"includeRepliesOnly": true,"maxReviews": 20}
Output at a glance
Illustrative field subset below; these are example values, not a captured customer review or a claim about source coverage. Native and compatibility output profiles can differ.
{"type": "review","appId": "com.whatsapp","reviewId": "example-review-id","content": "Example feedback used to illustrate the output format.","score": 4,"country": "us","language": "en","replyContent": null,"coverage": "complete","warnings": []}
Google Play review totals are not a promise of retrievable written reviews. Locale queries do not classify the actual language of each review. Pages, source access and your global cap can limit results. Replies and version fields may be null.
Pricing
Pay per delivered event, with automatic discounts based on your Apify subscription plan. These are result fees in USD, not separate subscriptions sold by this Actor. All tiers have the same Actor features. Platform resource usage during this Actor run is included.
| Billable event (1,000 events) | Free | Starter | Scale | Business |
|---|---|---|---|---|
| Review delivered | $0.08 | $0.07 | $0.06 | $0.05 |
Platinum and Diamond currently use the Business rate. The Pricing tab is the source of truth for the active schedule and your applicable plan.
- Review delivered: One delivered review after filtering and output mapping. Error rows have no result fee. Actor-run platform usage is included.
Example on the Free plan: 10 / 1,000 / 10,000 events cost $0.0008 / $0.08 / $0.8 in total Actor-run charges, including platform resources.
There is no Actor start fee, setup fee or monthly rental. Runs with no delivered reviews have no Actor charge. External integrations and separately initiated downstream services can charge independently. Requested counts are ceilings, not guaranteed deliveries.
Input reference
Fields below are grouped like the Input form. Optional fields need not be supplied. Compatibility input envelopes and transformations are explained in the technical reference.
Targets and collection
| Field | Type | Default | Meaning |
|---|---|---|---|
appIdOrUrl | string | Not set | Single-app compatibility input, e.g. com.whatsapp or a Play Store app URL. |
appIds | array | Not set | Multiple Google Play package IDs in one run. |
startUrls | array | Not set | Compatibility input containing Google Play app detail URLs. |
country | string | "US" | Google Play country code used by the review RPC, e.g. US, GB, KR. Select a suggested locale or enter a custom code. Locale selection does not detect the language of each review. |
countries | array | Not set | Optional multi-country extension. When supplied, each app is queried for each country and review IDs are deduplicated. |
language | string | "en" | Google Play query locale, e.g. en or de. all sweeps the documented fixed locale list in round-robin pages; maxReviews is a global cap, not per language. This does not classify review text language. Select a suggested locale or enter a custom code. Locale selection does not detect the language of each review. |
languages | array | Not set | Explicit query locales, or ["all"] for the fixed locale sweep. Queried round-robin; unvisited sources are reported when the global limit is reached. |
deviceType | string | "mobile" | Google Play device review context. |
keywords | array | Not set | Return reviews containing at least one keyword, case-insensitive. |
appVersion | array | Not set | Optional exact app-version allow-list. |
since | string | Not set | ISO date/timestamp for scheduled incremental monitoring. |
recentDays | integer | 0 | Return reviews from the most recent N days; 0 disables this filter. |
startPage | integer | 1 | Compatibility page offset. Earlier pages are fetched only to obtain Google's continuation token, then discarded. |
pagesToScrape | integer | -1 | Maximum RPC pages per app/country after startPage. -1 means continue until maxReviews/maxItems or source exhaustion. |
reviewsPerPage | integer | 100 | Requested reviews per Google Play RPC call. |
requestDelayMillis | integer | 0 | Optional delay before each RPC attempt. |
until | string | Not set | theagents-compatible LOWER date bound: returns reviews newer than this date. Combined with since using the later bound. Use endDate for an upper bound. |
neatratInput | object | Not set | Explicit Neatrat migration: paste the original input object here. Do not combine with native fields (unchanged platform defaults are ignored). outputSchema remains top-level and independent. Preserves language arrays and defaults mostRelevant / 5 pages / 10000 reviews. Missing language uses en query locale; text-language filter equivalence is unproven. |
wolvesInput | object | Not set | Explicit thewolves migration: paste the original input object here. Do not combine with native fields (unchanged platform defaults are ignored). outputSchema remains top-level and independent. Requires explicit positive maxItems: competitor has UI prefill only, no documented API default. No explicit page limit; native safety bounds apply. |
theagentsInput | object | Not set | Explicit theagents migration: paste the original input object here. Do not combine with native fields (unchanged platform defaults are ignored). outputSchema remains top-level and independent. Requires explicit positive maxItems: competitor has UI prefill only, no documented API default. No explicit page limit; native safety bounds apply. |
Filters and ordering
| Field | Type | Default | Meaning |
|---|---|---|---|
sort | string | "NEWEST" | Compatibility sort: NEWEST, RATING or HELPFULNESS/MOST_RELEVANT. |
sortBy | string | Not set | Alternative compatibility sort used by another major Actor. |
rating | integer | Not set | Return reviews with exactly one star rating from 1 to 5. |
ratingFilter | array | Not set | Return only reviews whose score is in this 1-5 allow-list. Numeric arrays such as [1,2] are supported for migration compatibility. |
endDate | string | Not set | Compatibility upper date bound in YYYY-MM-DD or ISO format. |
includeRepliesOnly | boolean | false | Return only reviews that have a developer reply. |
uniqueOnly | boolean | true | Deduplicate by reviewId across pages/apps/countries. |
ratings | array | Not set | Additional allowed ratings, merged with ratingFilter. |
Result limits and cost
| Field | Type | Default | Meaning |
|---|---|---|---|
maxReviews | integer | Not set | Compatibility maximum number of saved reviews across the run. -1 uses maxItems or the safety ceiling. Defaults to 1000 only when neither limit is supplied. |
maxItems | integer | Not set | Alternative compatibility maximum. When supplied with maxReviews, the lower positive limit wins. |
maxRequestRetries | integer | 2 | Retries transient HTTP/rate-limit/network failures. |
Compatibility and transformations
| Field | Type | Default | Meaning |
|---|---|---|---|
customMapFunction | string | Not set | JavaScript function applied after output formatting to each review. Must return one JSON object. Isolated runtime with no network, file system or Python access; 50ms CPU and 16MB per row, 10s total. Not a filter. |
outputSchema | string | "extended" | Explicit migration format. Missing source values stay null; extended preserves diagnostics. |
Connection and advanced settings
| Field | Type | Default | Meaning |
|---|---|---|---|
proxyConfiguration | object | Not set | Accepted for migration compatibility. The validated public RPC path does not require or use a proxy. |
Output reference
The table describes native fields; fields can be absent or null when the source does not provide them. Error rows and selected compatibility profiles have different shapes. Nested objects remain structured in JSON; CSV exports may serialize them.
| Field | Type | Meaning |
|---|---|---|
type | string | Type |
appId | string | App ID |
reviewId | string | Review ID |
id | ['string', 'null'] | Compatibility review ID |
userName | ['string', 'null'] | User |
userImage | ['string', 'null'] | User image |
content | ['string', 'null'] | Review |
text | ['string', 'null'] | Compatibility review text |
score | ['integer', 'null'] | Score |
scoreText | ['string', 'null'] | Compatibility score text |
thumbsUpCount | ['integer', 'null'] | Helpful votes |
thumbsUp | ['integer', 'null'] | Compatibility helpful votes |
reviewCreatedVersion | ['string', 'null'] | Review app version |
at | ['string', 'null'] | Review date |
date | ['string', 'null'] | Compatibility review date |
replyContent | ['string', 'null'] | Developer reply |
replyText | ['string', 'null'] | Compatibility developer reply |
repliedAt | ['string', 'null'] | Reply date |
replyDate | ['string', 'null'] | Compatibility reply date |
appVersion | ['string', 'null'] | App version |
version | ['string', 'null'] | Compatibility app version |
url | ['string', 'null'] | Review URL |
inputSource | ['string', 'null'] | Compatibility input source |
country | string | Country |
language | string | Language |
sort | string | Sort |
deviceType | string | Device |
sourceUrl | string | Source URL |
coverage | string | Coverage |
retrievalMethod | string | Retrieval method |
warnings | array | Warnings |
scrapedAt | string | Scraped at |
errorCode | string | Error code |
message | string | Message |
API and automation
The API tab provides snippets for this Actor. For scheduled or larger collections, start a run asynchronously and poll its status instead of holding a synchronous request open. Keep your API token in an environment variable.
import os, time, requestsbase = "https://api.apify.com/v2"headers = {"Authorization": "Bearer " + os.environ["APIFY_TOKEN"]}actor_input = {'appIds': ['com.whatsapp'], 'maxReviews': 20}response = requests.post(base + "/acts/YaQpO5GGTRCoNPtD7/runs",headers=headers, json=actor_input, timeout=30,)response.raise_for_status()run = response.json()["data"]for _ in range(720):if run["status"] not in ("READY", "RUNNING", "TIMING-OUT", "ABORTING"):breaktime.sleep(5)response = requests.get(base + "/actor-runs/" + run["id"], headers=headers, timeout=30)response.raise_for_status()run = response.json()["data"]else:raise TimeoutError("Polling ended; inspect the existing run before starting another.")if run["status"] != "SUCCEEDED":raise RuntimeError(run.get("statusMessage", run["status"]))response = requests.get(base + "/datasets/" + run["defaultDatasetId"] + "/items",headers=headers, params={"format": "json", "limit": 1000, "offset": 0}, timeout=30,)response.raise_for_status()rows = response.json()print(rows) # Paginate with offset for larger datasets; inspect per-row coverage.
Scheduled monitoring and integrations
- Save a working input as an Apify Task.
- Attach a Schedule in your timezone; keep runs sharing an incremental state key sequential.
- Add a successful-run webhook or connect your downstream workflow to the dataset export/API.
- Inspect missing/partial data before sending alerts or treating absence as removal.
Use the platform Integrations/API options to connect external workflows such as Make, n8n or a data warehouse. An external sentiment or summarization step is separate from this Actor and may have its own charges. The platform also supports Actor tools through Apify MCP; availability and client setup depend on your integration.
FAQ
Where is the package name?
Copy the id parameter from the Google Play URL; for example, id=com.whatsapp.
Why are fewer reviews returned than the store rating count?
A rating count can include ratings without written reviews, and source pagination, locales and filters change the retrievable subset.
Can I reuse an existing integration?
Select the matching input envelope and outputSchema. Compatibility covers the documented fields; it does not promise identical source ordering or availability.
Can I export without writing code?
Yes. Run from the Input form, open the dataset and use the export controls for JSON or CSV. Select your preferred output profile before running when migrating an integration.
Does a successful run guarantee every field?
No. Inspect coverage, warnings and source-specific status fields. Optional enrichment may be missing even when usable rows were delivered.
Troubleshooting
| Symptom | What to check |
|---|---|
| Empty dataset | Validate the target, source availability and filters; try the small quick-start input. |
| Fewer rows than requested | Check source limits, pagination and filtering. Increasing a cap cannot create unavailable source records. |
| Partial fields | Inspect coverage/warnings and the relevant source or enrichment status. |
| Access or throttling errors | Check the run log and documented proxy configuration; retry at a lower request volume. |
| Migration mismatch | Check the explicit input/output profile and technical field mapping below. |
| Unexpected bill | Check the delivered review count and your plan rate in the Pricing tab; Actor-run resources are included. |
Technical reference
Migration compatibility
The Actor accepts the common input families used by leading Google Play review Actors:
appIdOrUrl,deviceType,sortBy,rating,startPage,pagesToScrape,reviewsPerPage,maxReviews,ratingFilter,keywords,endDate,recentDays,uniqueOnly,appVersionappIds,country,language,sort,startUrls,maxItems,customMapFunction
customMapFunction executes an isolated JavaScript function on each output row.
One schema-level migration difference is explicit: one tracked competitor defines language as an array while another defines the same key as a string. Apify validates a field as one type, so this Actor preserves the string-shaped language contract and adds languages for array-shaped multi-locale workflows. For native workflows, rename language to languages. For competitor defaults as well as original array keys, use the explicit envelope below; numeric ratingFilter arrays are preserved.
Extensions
- Multiple app IDs and countries in one run
- Multiple languages through
languages sincefor scheduled incremental review monitoring- Developer-reply-only filtering
- Explicit RPC request/retry/source diagnostics
- Stable structured output with source locale and coverage metadata
Output
Review rows include review ID, user name/image, text, score, helpful votes, app version, timestamp, developer reply/reply timestamp, app/country/language and source telemetry.
For drop-in migration from the major appIds/startUrls competitor family, rows also expose compatibility aliases such as id, text, date, replyText, replyDate, version, thumbsUp, scoreText, url, inputSource and criterias alongside the canonical fields.
Source boundary
The validated path uses Google Play's public oCPfdb review RPC. It requires no account or private endpoint. Source behavior can change, so the Actor reports source failures and retry counts explicitly.
Date and output compatibility
theagents until is a LOWER date bound (reviews newer than that date), combined with since using the later bound. endDate remains the upper bound. recent/top alias newest/mostRelevant; ratings merges with ratingFilter. Neatrat output date is date-only and has different rating/reviewer/body/position fields: select outputSchema=neatrat for its field layout. Use languages for Neatrat language-array migration through the input form; language remains a string in the schema. language=all now expands to the fixed query-locale list documented below.
Output profiles and custom JavaScript
The default outputSchema=extended preserves the existing output. Google Play supports wolves, theagents and neatrat. These are explicit field projections, not a guarantee of identical source pagination or data availability. Missing source fields remain null.
customMapFunction runs after output projection and before delivery. Example: (row) => ({...row, exported: true}). It must synchronously return one JSON object per row. Async functions, filtering and non-object results fail the run before delivery. Each row has 50 ms CPU, 16 MB memory and 256 KB stack limits; total mapping budget is 10 seconds. The interpreter has no network, filesystem or host callbacks.
Multiple locales and bounded coverage
Use language: "all" or languages: ["all"] to query these fixed locales: en de fr es it pt-BR pt-PT ja ko zh-CN zh-TW zh-HK af am bg ca hr cs da el en-GB es-419 et fi fil fr-CA he hi hu is id lt lv ms nl no pl ro ru sk sl sr sv sw th tr uk zu vi. This sweeps query locales, not all review text languages or historical reviews. Explicit languages: ["en", "de"] remains supported. Sources are scheduled one page at a time in round-robin order; output is source-page order, not a globally sorted merge. maxReviews remains global. A small cap can stop before later sources are visited. SOURCE_DIAGNOSTICS records all sources including unvisited ones, pages, accepted rows and stop reason. Repeated cursors terminate with limited coverage. Source locale does not classify actual text language.
The fixed locale list is based on Google's published locale table (https://support.google.com/googleplay/android-developer/table/4419860?hl=en-GB); this table does not prove that each review endpoint returns distinct data for every locale. Refer to the run diagnostics for actual coverage.
Explicit input migration
Keep existing native calls unchanged. Native defaults remain NEWEST, pagesToScrape=-1, maxReviews=1000 (when neither quantity limit is supplied). Input profiles are independent of outputSchema, which remains extended unless selected explicitly.
For Neatrat, replace the entire input JSON with one wrapper around the original object. No language key rename or manual default copying is needed:
{"neatratInput":{"appIdOrUrl":"com.whatsapp","language":["en","de"]}}
In the form, paste the original object into Neatrat original input and clear unrelated native fields, including any prefilled appIds. Using the JSON tab and replacing the whole document is the shortest reliable migration. Do not submit the old language array at the top level: that field deliberately remains a string.
| Entry | Sort when omitted | Pages when omitted | Quantity when omitted |
|---|---|---|---|
| Native (no envelope) | NEWEST | -1 | 1000 unless maxItems supplied |
| neatratInput | mostRelevant / HELPFULNESS | 5 | 10000 |
| wolvesInput | NEWEST | no explicit page limit, native ceiling applies | Must provide positive maxItems |
| theagentsInput | NEWEST | no explicit page limit, native ceiling applies | Must provide positive maxItems |
The last two declared competitor schemas supply only prefill:1000, not a maxItems default. Their omitted API quantity behavior is unproven. Add maxItems only if the original input omitted it, then wrap:
{"wolvesInput":{"appIds":["com.whatsapp"],"maxItems":1000},"outputSchema":"wolves"}
{"theagentsInput":{"appIds":["com.whatsapp"],"maxItems":1000,"until":"2026-09-01"},"outputSchema":"theagents"}
Only one envelope is allowed. Inside it, use that competitor's fields, types and enum values; unknown or cross-profile fields fail as INVALID_INPUT before fetching. Explicit nested settings win over that profile's defaults. Native extension workflows should continue using the native entry. customMapFunction inside wolvesInput/theagentsInput still executes after the explicitly selected output projection.
Top-level native fields matching the existing Schema defaults are ignored in envelope mode because Apify injects them automatically; this is also reported in OUTPUT.warnings. Other top-level native fields fail rather than merge. Even an explicitly supplied top-level value identical to a default cannot override an envelope: put settings inside the envelope. outputSchema is the sole independent top-level control. OUTPUT.inputProfile and OUTPUT.resolvedInput show the selected profile and resolved sort/page/quantity controls for inspection.
Limits remain explicit: -1 is bounded by 100000 reviews and 10000 pages per query source; maxReviews/maxItems is global. Neatrat language arrays route query locales, not a proven equivalent of its described text-language filter. Empty/omitted Neatrat language uses en as this implementation's query fallback, not a verified competitor default. Page offsets and page limits are per source; raw page sizes, locale coverage, position semantics and cross-source global ordering are not guaranteed equal to competitors. The other actors' omitted page behavior is not proven by their schemas; this entry uses the documented native bounded traversal.
Support
Open an issue from this Actor’s Issues tab with the run ID, expected result and a redacted input. Do not include tokens, cookies or private credentials. Include the output profile and affected field when reporting a migration mismatch.
Presentation update
The current listing adds workflow examples, grouped input documentation, output-field explanations and plan-based result discounts. Source-specific limitations above still apply. This is an independent tool and is not affiliated with the source platform.
How to export low-star Google Play reviews for release feedback
Reading every app review manually is difficult. A small filtered export can help a product team inspect recent complaints before deciding whether a larger analysis is useful.
Disclosure: I maintain the paid Apify Actor in this tutorial. This is a documented workflow for my own product. Available account credits may cover a trial, but collection is metered.
Configure one app and one locale
Open the Actor, go to Input and choose JSON. This example requests up to five one- or two-star reviews from WhatsApp's US/English feed:
{"appIds": ["com.whatsapp"],"country": "us","language": "en","ratingFilter": [1,2],"maxReviews": 5}
The package name is the id value in a Google Play app URL. Replace com.whatsapp with your target. Country selects the source locale; language is a collection setting, not automatic translation. Keep these explicit for a reproducible comparison.
Inspect the result before drawing conclusions
After the run finishes, open the dataset and confirm that returned scores are one or two. Export CSV for manual triage or JSON for an analysis pipeline. Retain review IDs, timestamps, app version where available, text and developer replies rather than reducing the output to an average score.
A useful manual worksheet separates the review's actual statement, your proposed issue category, and your confidence. A complaint is not proof of a confirmed bug; missing app versions and replies should remain unknown. Don't classify sentiment or assign root causes as if the scraper had verified them.
Verification and limitations
A September 11, 2026 owner cloud sample returned five reviews for this configuration. It is a small functional check, not proof of comprehensive coverage or customer adoption. Source data changes, and filtering can require more requests than the number of results ultimately delivered.
The verified Free-plan result fee is $0.08 per 1,000 reviews: five delivered results cost $0.0004 including Actor-run platform resources. Refer to the live Pricing tab for your applicable plan. A zero-result run has no Actor charge.
Low-star feedback is deliberately biased. It is useful for finding possible problems, but cannot establish the percentage of users experiencing them. For broader research, compare it with an unfiltered sample using the same date and locale settings. For recurring exports, use explicit date boundaries and deduplicate review identities downstream.
Try it
Open the Google Play review exporter. Start with five rows, inspect the original text and only then expand the scope. Report reproducible issues through the Actor's Issues tab without including credentials.
Predictable run costs and scan limits
Before fetching, the Actor reduces the requested review count to the remaining event budget. Memory is bounded to 128–1024 MB. Collection has a 15-minute wall-clock limit, in addition to the existing row and page limits; a pending request may need a short time to close. On reaching it, accepted reviews are saved and OUTPUT.status reports limited coverage, with time_limit in source diagnostics. Split large or selective scans by app, locale or date. A limited scan never establishes that no other reviews exist.