Google Play Reviews – App Ratings, Replies & Countries
Pricing
from $0.80 / 1,000 reviews
Google Play Reviews – App Ratings, Replies & Countries
Collect Google Play reviews and ratings for any app across country storefronts. Search by app name or use a Google Play URL. Returns one row per review with rating, text, author, date, app version, thumbs-up count, developer reply, and storefront country.
Pricing
from $0.80 / 1,000 reviews
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
Google Play Reviews Scraper
Collect Google Play Store reviews and ratings for any app, across country storefronts. Give it an app name or a Google Play link and it returns a clean, one-row-per-review dataset: the star rating, review body, author, date, the app version reviewed, thumbs-up count, any developer reply, and the storefront country. Reviews are storefront-specific, so you can sweep many countries to gather the full picture for a single app.
Why this scraper
- Reviews are the primary output: rating, body, author, date, app version, thumbs-up, developer reply, country, and language on every row.
- Two ways in: search by app name, or paste one or more Google Play app links (a bare package id like
com.spotify.musicworks too). - Multi-country sweep: pass a list of countries, or use "all" for a broad built-in set of major markets.
- Sort by newest, most helpful, or by rating.
- Filter by minimum and maximum star rating.
- Choose the review language / locale.
- Optional app-metadata enrichment: developer, average score, ratings count, installs, category, icon, price, and description attached to each review.
- 20+ output fields, more than typical alternatives, at a predictable per-result price.
Data you get
Sample shape, values are illustrative placeholders, not from a live review.
| Field | Example |
|---|---|
| reviewId | 00000000-0000-0000-0000-000000000000 |
| appId | com.example.app |
| appName | Sample App |
| country | us |
| language | en |
| rating | 5 |
| body | Full review text appears here. |
| author | Reviewer Name |
| authorId | 100000000000000000000 |
| authorImage | https://play-lh.googleusercontent.com/… |
| thumbsUp | 12 |
| appVersion | 1.0.0 |
| reviewDate | 2026-01-01T00:00:00+00:00 |
| reviewTimestamp | 1780000000 |
| reviewUrl | https://play.google.com/store/apps/details?id=com.example.app&reviewId=… |
| developerReply | Thanks for the feedback! |
| developerReplyDate | 2026-01-02T00:00:00+00:00 |
With enrichment enabled, each review also carries: appDeveloper, appDeveloperEmail, appDeveloperWebsite, appScore, appRatingsCount, appInstalls, appCategory, appContentRating, appPrice, appCurrency, appIconUrl, appUpdated, appDescription, appStoreUrl.
How to use
Search by app name:
{"mode": "search","queries": ["Instagram", "Spotify"],"appsPerQuery": 1,"countries": ["us"],"sortBy": "newest","maxItems": 100}
Sweep several countries for one app via its link:
{"mode": "url","urls": ["https://play.google.com/store/apps/details?id=com.instagram.android"],"countries": ["us", "gb", "de", "jp"],"maxItems": 500}
Only high-rated reviews, with app details attached:
{"mode": "url","urls": ["https://play.google.com/store/apps/details?id=com.instagram.android"],"countries": ["us"],"minRating": 4,"fetchDetails": true,"maxItems": 200}
Multiple apps at once (bare package ids work too):
{"mode": "url","urls": ["com.instagram.android","com.spotify.music"],"countries": ["us"],"maxItems": 200}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | search | "search" (by app name) or "url" (paste app links). |
| queries | array | ["Instagram"] | App names or keywords (search mode). |
| appsPerQuery | integer | 1 | Top matching apps to take per search term. |
| urls | array | (example) | Google Play app links or package ids (url mode). |
| countries | array | ["us"] | Country codes to collect from. Empty uses the link's country or us. "all" sweeps major markets. |
| language | string | en | Review language / locale code. |
| sortBy | string | newest | "newest", "mostHelpful", or "rating". |
| minRating | integer | (none) | Keep reviews at or above this star rating. |
| maxRating | integer | (none) | Keep reviews at or below this star rating. |
| fetchDetails | boolean | false | Attach app metadata to each review. |
| maxItems | integer | 20 | Total review cap. 0 means no limit. |
| maxPages | integer | (none) | Optional safety bound on review pages read per country (about 40 reviews per page). Leave empty to walk every page Google Play serves — the run still stops at Max reviews. |
| resumeFromRunId | string | (none) | Run id (or dataset id) of a previous run of this Actor. Reviews it already collected are skipped, so this run only fetches new ones. |
| incrementalMode | boolean | false | Recurring monitoring: remembers what a previous run of the SAME search saw and marks each review NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED. |
| stateKey | string | (none, auto) | Name this monitoring campaign explicitly. Leave empty to derive one automatically from mode, queries/urls, countries, language, sortBy, minRating/maxRating, and fetchDetails (maxItems/maxPages and delivery options like mcpConnectors do NOT affect it). |
| emitUnchanged | boolean | false | Also return (and bill for) reviews unchanged since the last run. |
| emitExpired | boolean | false | Also return (and bill for) a tombstone row for reviews the previous run saw that this run no longer finds. Only reported after a run that fully re-walked every tracked app/country stream — never after a capped or resumed run. |
| proxy | object | Apify proxy | Connection settings. |
Incremental mode (recurring monitoring)
Turn on incrementalMode and schedule the Actor to run on the same app/country/filter set (or set stateKey yourself for an explicit campaign name). Each run compares against what the previous run of the SAME campaign saw and adds changeType (NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED), changedFields, firstSeenAt, and lastSeenAt to every row. By default only NEW/UPDATED/REAPPEARED rows are returned — turn on emitUnchanged/emitExpired to also see (and pay for) the rest.
What counts as a change: rating, review text, author, thumbsUp, app version, and developer replies are all compared — every field a review actually carries is real data a monitoring run exists to report. One thing is deliberately excluded from change detection (though still shown on every row):
- App-metadata fields attached when
fetchDetailsis on (appScore,appRatingsCount,appInstalls,appDeveloper, ...) — these describe the APP, not the individual review, and change on their own as other users interact with the app. Excluding them stops one unrelated review's helpful-vote or the app's aggregate rating from flipping every other review toUPDATEDin lockstep.
thumbsUp was suspected of ticking up independently of the review (like a vote counter) and was excluded in an earlier draft on that guess. It was measured directly: two live fetches of the same popular app's top-40 most-helpful reviews (Gmail, com.google.android.gm), 1810s (30.2 minutes) apart, diffed field-by-field. Result: zero drift — every one of the 40 thumbsUp values (ranging 2–3318, including reviews as recent as days old) was byte-identical across both passes, as was every other field. The guess wasn't supported by data, so thumbsUp is now treated as ordinary review data and included in change detection. This was tested at a 30-minute window, not the actor's real incremental cadence (typically daily/weekly) — if a future run surfaces thumbsUp-only UPDATED noise at that longer cadence, revisit _VOLATILE_FIELDS in src/incremental.py.
Combining resumeFromRunId with incrementalMode is only for bootstrapping a brand-new campaign from an earlier non-incremental run's dataset; once a campaign has its own tracked state, combine them again and the run fails fast (remove resumeFromRunId or use a different stateKey). emitExpired reviews are only ever reported after a complete, uncapped, non-resumed scan — a partial run can't tell "deleted" apart from "not reached yet".
Output example
Sample shape, values are illustrative placeholders.
{"reviewId": "00000000-0000-0000-0000-000000000000","appId": "com.example.app","appName": "Sample App","country": "us","language": "en","rating": 5,"body": "Full review text appears here.","author": "Reviewer Name","authorId": "100000000000000000000","authorImage": "https://play-lh.googleusercontent.com/…","thumbsUp": 12,"appVersion": "1.0.0","reviewDate": "2026-01-01T00:00:00+00:00","reviewTimestamp": 1780000000,"reviewUrl": "https://play.google.com/store/apps/details?id=com.example.app&reviewId=…","developerReply": null,"developerReplyDate": null}
Send results into your apps (MCP connectors)
You can optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector under Apify, Settings, API & Integrations, then select it in the input. For Notion, set a parent page URL and each review is written as a page. Other connectors receive a best-effort write.
The connector receives a condensed, human-readable summary of each review (a heading plus the key fields and body text), not the full JSON. The complete record always stays in the Apify dataset. Leave the connector field empty to skip this step; it never changes the dataset output.
Plan requirement
Runs on any Apify plan. For very large multi-country sweeps, a proxy with more exit rotation can help.