Google Play Reviews Scraper | Low-Star & Replies avatar

Google Play Reviews Scraper | Low-Star & Replies

Pricing

from $0.05 / 1,000 reviews

Go to Apify Store
Google Play Reviews Scraper | Low-Star & Replies

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

tingyou333 zhuang

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

6 days ago

Last modified

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

GoalStart here
Inspect low-star Android app feedbackOpen the prefilled example, inspect the input and price, then Start
Integrate CSV/JSON into your own scriptStep-by-step guide
Call this named tool from an AI assistantDirect 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 planStarter / BronzeScale / SilverBusiness / 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)FreeStarterScaleBusiness
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

FieldTypeDefaultMeaning
appIdOrUrlstringNot setSingle-app compatibility input, e.g. com.whatsapp or a Play Store app URL.
appIdsarrayNot setMultiple Google Play package IDs in one run.
startUrlsarrayNot setCompatibility input containing Google Play app detail URLs.
countrystring"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.
countriesarrayNot setOptional multi-country extension. When supplied, each app is queried for each country and review IDs are deduplicated.
languagestring"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.
languagesarrayNot setExplicit query locales, or ["all"] for the fixed locale sweep. Queried round-robin; unvisited sources are reported when the global limit is reached.
deviceTypestring"mobile"Google Play device review context.
keywordsarrayNot setReturn reviews containing at least one keyword, case-insensitive.
appVersionarrayNot setOptional exact app-version allow-list.
sincestringNot setISO date/timestamp for scheduled incremental monitoring.
recentDaysinteger0Return reviews from the most recent N days; 0 disables this filter.
startPageinteger1Compatibility page offset. Earlier pages are fetched only to obtain Google's continuation token, then discarded.
pagesToScrapeinteger-1Maximum RPC pages per app/country after startPage. -1 means continue until maxReviews/maxItems or source exhaustion.
reviewsPerPageinteger100Requested reviews per Google Play RPC call.
requestDelayMillisinteger0Optional delay before each RPC attempt.
untilstringNot settheagents-compatible LOWER date bound: returns reviews newer than this date. Combined with since using the later bound. Use endDate for an upper bound.
neatratInputobjectNot setExplicit 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.
wolvesInputobjectNot setExplicit 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.
theagentsInputobjectNot setExplicit 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

FieldTypeDefaultMeaning
sortstring"NEWEST"Compatibility sort: NEWEST, RATING or HELPFULNESS/MOST_RELEVANT.
sortBystringNot setAlternative compatibility sort used by another major Actor.
ratingintegerNot setReturn reviews with exactly one star rating from 1 to 5.
ratingFilterarrayNot setReturn only reviews whose score is in this 1-5 allow-list. Numeric arrays such as [1,2] are supported for migration compatibility.
endDatestringNot setCompatibility upper date bound in YYYY-MM-DD or ISO format.
includeRepliesOnlybooleanfalseReturn only reviews that have a developer reply.
uniqueOnlybooleantrueDeduplicate by reviewId across pages/apps/countries.
ratingsarrayNot setAdditional allowed ratings, merged with ratingFilter.

Result limits and cost

FieldTypeDefaultMeaning
maxReviewsintegerNot setCompatibility maximum number of saved reviews across the run. -1 uses maxItems or the safety ceiling. Defaults to 1000 only when neither limit is supplied.
maxItemsintegerNot setAlternative compatibility maximum. When supplied with maxReviews, the lower positive limit wins.
maxRequestRetriesinteger2Retries transient HTTP/rate-limit/network failures.

Compatibility and transformations

FieldTypeDefaultMeaning
customMapFunctionstringNot setJavaScript 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.
outputSchemastring"extended"Explicit migration format. Missing source values stay null; extended preserves diagnostics.

Connection and advanced settings

FieldTypeDefaultMeaning
proxyConfigurationobjectNot setAccepted 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.

FieldTypeMeaning
typestringType
appIdstringApp ID
reviewIdstringReview 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
countrystringCountry
languagestringLanguage
sortstringSort
deviceTypestringDevice
sourceUrlstringSource URL
coveragestringCoverage
retrievalMethodstringRetrieval method
warningsarrayWarnings
scrapedAtstringScraped at
errorCodestringError code
messagestringMessage

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, requests
base = "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"):
break
time.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

  1. Save a working input as an Apify Task.
  2. Attach a Schedule in your timezone; keep runs sharing an incremental state key sequential.
  3. Add a successful-run webhook or connect your downstream workflow to the dataset export/API.
  4. 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

SymptomWhat to check
Empty datasetValidate the target, source availability and filters; try the small quick-start input.
Fewer rows than requestedCheck source limits, pagination and filtering. Increasing a cap cannot create unavailable source records.
Partial fieldsInspect coverage/warnings and the relevant source or enrichment status.
Access or throttling errorsCheck the run log and documented proxy configuration; retry at a lower request volume.
Migration mismatchCheck the explicit input/output profile and technical field mapping below.
Unexpected billCheck 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, appVersion
  • appIds, 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
  • since for 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.

EntrySort when omittedPages when omittedQuantity when omitted
Native (no envelope)NEWEST-11000 unless maxItems supplied
neatratInputmostRelevant / HELPFULNESS510000
wolvesInputNEWESTno explicit page limit, native ceiling appliesMust provide positive maxItems
theagentsInputNEWESTno explicit page limit, native ceiling appliesMust 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.