App Store & Google Play Reviews Scraper
Pricing
from $1.00 / 1,000 results
App Store & Google Play Reviews Scraper
Scrape Apple App Store and Google Play reviews for iOS/Android app and competitor analysis. Export ratings, text, dates, available versions, developer replies, full app metadata and raw data. Bulk JSON/CSV export, filters and AI agent/MCP support.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Anas Nadeem
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Scrape public Apple App Store and Google Play reviews for app research, competitor analysis, app store optimization (ASO) and product feedback. Export iOS and Android reviews together, with ratings, original text, dates, available review versions, helpful votes and developer responses. Full available app metadata, original source payloads and a collection report are included by default.
Use the actor in Apify Console, through the API, or as a tool for an AI agent through Apify MCP. Supply app URLs or IDs; no Apple or Google developer-account credentials are needed.
Quick start
This example requests up to 40 reviews from each store, with an 80-review total cap:
{"apps": ["https://apps.apple.com/us/app/whatsapp-messenger/id310633997","https://play.google.com/store/apps/details?id=com.whatsapp"],"countries": ["us"],"languages": ["en"],"maxReviewsPerAppCountry": 40,"maxReviews": 80,"includeAppMetadata": true,"includeRawData": true}
Open Output for review rows, or use the run's result links for full JSON, core-field CSV, a short preview, the collection report and app profiles. Set a maximum run charge in Console or maxTotalChargeUsd in API run options.
The actor accepts mixed Apple numeric IDs such as 310633997, Android package names such as com.whatsapp, and HTTPS app URLs. Explicit countries/languages override URL hints. Each app/country combination is a separate context; Google additionally creates one context per requested language. Apple uses its storefront and returns language: null.
What you can do with the data
- Compare your app with competitors using original reviews and star ratings.
- Find complaints or feature requests with date, keyword and rating filters.
- Inspect feedback on a specific version where the source exposes that version.
- Analyze developer responses and unresolved feedback.
- Feed review JSON into your own AI analysis, data warehouse or reporting workflow.
The actor exports evidence for analysis. Sentiment labels, translations and inferred reviewer demographics are not generated.
Bulk export and filtered research
Request up to 5,000 reviews for each of four app/storefront contexts:
{"apps": ["310633997", "com.whatsapp"],"countries": ["us", "in"],"languages": ["en"],"sort": "newest","maxReviewsPerAppCountry": 5000,"maxReviews": 20000,"includeAppMetadata": true,"includeRawData": true}
For low-rating reviews mentioning a problem, use:
{"apps": ["310633997", "com.whatsapp"],"ratings": [1, 2],"keywords": ["crash", "login", "notification"],"dateFrom": "2026-01-01","replyFilter": "all","maxReviewsPerAppCountry": 500,"maxReviews": 1000,"maxReviewsScannedPerAppCountry": 10000,"maxRequestsPerAppCountry": 1000}
All filter groups combine with AND; any listed keyword matches within the keyword group. Keywords match title/body case-insensitively. Version filters require an exact source version. Filters examine retrieved candidates within the work limits; a batch with no matches does not end collection.
For all reachable reviews, set both review caps to 0. The candidate/request ceilings still apply. Removing those ceilings also requires setting their inputs to 0. Keep a maximum run charge and inspect SUMMARY: public endpoints do not guarantee access to every historical review.
Review output contract
The default dataset has one row per unique exported review. Every field below is present except sourceData, which is omitted when includeRawData is false. Unavailable scalar values are null; source zeros and empty strings retain their meaning. Full JSON preserves nested data. The CSV/table view selects core review fields.
The run API's output object provides these result URLs:
| Output link | Result |
|---|---|
reviews | Full review dataset as JSON; supports pagination. |
reviewsPreview | First 20 rows projected to core fields for quick inspection. |
reviewsCsv | Core review table exported as CSV. |
collectionReport | The SUMMARY collection and quality report. |
appProfiles | The APPS metadata index. |
appProfileRecords | List of full profile keys in the key-value store. |
| Fields | Type and meaning |
|---|---|
schemaVersion | Integer 1, the review contract version. |
store, appId, appUrl | Store is app_store or google_play; IDs are strings; app store URL. |
appName, developerName | Nullable current app/publisher names from optional app metadata. |
appRating, appRatingCount | Nullable current app-level rating and rating count, including ratings without written text. |
reviewId, reviewKey | Source ID and stable namespaced key for joins and deduplication. |
rating, title, text | Integer 1–5, nullable original title, original body string. Google titles are usually null. |
sourceDate, sourceDateType | ISO UTC source date; published, updated or unspecified. An update date is not an inferred original publication time. |
scrapedAt | ISO UTC observation time. |
country, language | Requested country/storefront and nullable requested Google language. Not reviewer residence or detected text language. |
appVersion | Nullable version attached to this review. Current app version is stored separately in the profile. |
reviewerName, reviewerUrl, reviewerImage | Nullable public reviewer display name, profile URL and image URL. |
helpfulCount, voteCount, voteMetric | Nullable source vote values. Metric is net_votes for Apple, thumbs_up for Google, or null. Apple net votes can be negative. |
developerReplyStatus | present, none or unavailable. Unavailable does not mean no reply. |
replyId, replyText, replyDate, replyDateType | Nullable source response ID, original text, ISO UTC timestamp and modified/unspecified date meaning. |
isEdited, reviewUrl | Nullable Apple edit flag and review link. Apple's app-level review links are not represented as unique permalinks. |
reviewTags | Array of {criteria, rating} source criteria, where available; empty otherwise. |
source, sources, fieldSources | Primary adapter, contributing adapter array and per-field provenance map. Adapters: apple_catalog, apple_rss, google_play_rpc. |
sourceData | Optional original payloads keyed by adapter. Included by default; Google retains the full source row array, including unmapped positions. |
Illustrative review below uses a fictional app and reviewer, with includeRawData: false. Real rows contain the source's original text and values:
{"schemaVersion": 1,"store": "google_play","appId": "com.example.notes","appName": "Example Notes","appUrl": "https://play.google.com/store/apps/details?id=com.example.notes","developerName": "Example Developer","appRating": 4.2,"appRatingCount": 12500,"reviewId": "demo-review-001","reviewKey": "google_play:com.example.notes:demo-review-001","rating": 2,"title": null,"text": "Sync stopped working after the latest update.","sourceDate": "2026-10-12T09:00:00.000Z","sourceDateType": "unspecified","scrapedAt": "2026-10-14T09:00:00.000Z","country": "us","language": "en","appVersion": "3.2.1","reviewerName": "Example Reviewer","reviewerUrl": null,"reviewerImage": null,"helpfulCount": 7,"voteCount": null,"voteMetric": "thumbs_up","developerReplyStatus": "present","replyId": null,"replyText": "Please contact support so we can investigate.","replyDate": "2026-10-13T10:00:00.000Z","replyDateType": "unspecified","isEdited": null,"reviewUrl": "https://play.google.com/store/apps/details?id=com.example.notes&reviewId=demo-review-001","reviewTags": [],"source": "google_play_rpc","sources": ["google_play_rpc"],"fieldSources": {"reviewId": "google_play_rpc","rating": "google_play_rpc","text": "google_play_rpc","sourceDate": "google_play_rpc","reviewerName": "google_play_rpc","appVersion": "google_play_rpc","helpfulCount": "google_play_rpc","replyText": "google_play_rpc","replyDate": "google_play_rpc"}}
Google deduplicates by app and source review ID across requested locales; the first matching observation is retained. Apple keys also include the storefront. Resume within the same run reconciles existing rows before continuing. A separate new run can export the same reviews again; cross-run monitoring is not included.
App metadata and collection report
The run's key-value store contains three types of result records:
| Record | Contents |
|---|---|
SUMMARY | Run totals and one report per app/country/language: examined candidates, matches, unique output, duplicates, requests, field availability counts, source, date bounds, warnings, errors and stop reason. |
APPS | { "apps": [...] } index. Each entry contains store, appId, country, language and the key of its full profile. Empty if metadata is disabled or unavailable. |
APP_* | Profile identified by the index key: current title, developer, ratings/histogram, capture time, complete available store-specific metadata in details, and optional original metadata sections in sourceData. |
Profiles retain available descriptions, price/currency, publisher/contact fields, categories, versions, screenshots and platform requirements. Google additionally exposes available install ranges and release/update fields. Exact keys vary by store. App profiles and reports are separate from review rows.
Read a profile at https://api.apify.com/v2/key-value-stores/{defaultKeyValueStoreId}/records/{key}, authenticating with your Apify token. Internal STATE_*/ENRICH_* records support recovery and are not analysis results.
SUMMARY.failedPartitions can be positive even when some reviews were successfully exported. All-source failure fails the run; a valid collection with no matching reviews succeeds with a report. A metadata warning does not discard reviews.
Per-context stop reasons distinguish source_exhausted, source_limit, per_context_limit, global_limit, scan_limit, request_limit, spending_limit, source_error and interrupted. Overall partitions_finished means each context stopped; inspect those individual reasons. exhaustedReachableSource: true describes the selected endpoint, while historicalCompleteness remains not_guaranteed.
Inputs
| Input | Default | Behavior |
|---|---|---|
apps | Required | Array of mixed app IDs/package names or HTTPS store URLs. |
countries | URL country, then us | Two-letter storefront/country codes. Explicit array overrides URL hints. |
languages | Play URL language, then en | Array of Google language codes; each creates a context. Apple language remains null. |
sort | newest | newest or mostHelpful within each context. The combined dataset is not globally sorted. |
maxReviews | 10000 | Total unique output cap. 0 removes this ceiling. |
maxReviewsPerAppCountry | 1000 | Unique output cap for each app/country/language context. 0 removes this ceiling. |
ratings | [1,2,3,4,5] | Keep any listed star rating. One Google rating uses a source-side filter. |
dateFrom, dateTo | Unset | Inclusive source-date window. YYYY-MM-DD uses UTC and includes the entire ending day. ISO timestamps require a timezone. |
keywords | Unset | Array of case-insensitive title/body matches; any listed keyword matches. |
appVersions | Unset | Exact source review versions. Missing versions cannot match. |
replyFilter | all | all, withReply or withoutReply. Unavailable status does not match either reply-specific filter. |
appleSource | auto | Catalog pagination with disclosed RSS fallback; catalog requires catalog availability; rss selects the limited feed. |
enrichAppleReviews | true | Supplement Apple catalog rows with available RSS versions/votes from up to ten feed pages. |
includeAppMetadata | true | Collect full available app profiles in the key-value store and app context on review rows. |
includeRawData | true | Preserve original review/metadata payloads, including unmapped source fields. |
maxReviewsScannedPerAppCountry | 100000 | Examined candidate cap per context, including duplicates and filter rejects. 0 removes it. A positive ceiling must be at least a positive per-context review cap. |
maxRequestsPerAppCountry | 10000 | HTTP-attempt cap per context, including metadata, enrichment and retries. 0 removes it. |
maxConcurrency | 3 | Simultaneous contexts, from 1 to 10. Pages within a context remain sequential. |
requestIntervalMillis | 350 | Minimum shared spacing per source host; Apple lookups have additional spacing. |
requestTimeoutSecs | 30 | Timeout for each HTTP attempt. |
maxRetries | 3 | Bounded retries with backoff for transient failures. |
proxyConfiguration | Direct | Optional standard Apify/custom proxy configuration, applied to review and metadata requests. |
At most 1,000 expanded contexts are accepted per run. Split larger jobs across runs. Contexts receive pages in rounds; a low global cap can leave some unfinished. Inspect the report before comparing context counts.
Apple and Google field availability
Apple catalog pagination reaches beyond the finite RSS review feed and exposes available developer responses and edit flags. Review versions and votes are not consistently present in the catalog. RSS enrichment supplements its recent/helpful window, generally up to 500 reviews per storefront/sort order. Older catalog rows can therefore have null versions or votes.
Apple RSS alone cannot determine developer replies. A reply-specific filter with RSS, or with an unavailable catalog, produces a visible source error. Automatic fallback is disclosed; reaching the ten-page feed ceiling is reported as source_limit.
Google timestamps can reflect edits without exposing the original publication date. Requested countries and languages do not prove reviewer residence or actual text language. Rating counts include ratings without written text and do not establish export completeness.
The actor preserves all fields available from its selected public sources, including original payloads by default. Deleted/private reviews, unavailable historical fields, reviewer email addresses and a complete review edit history are not publicly exposed by these sources.
Use with AI agents and MCP
Actor identifier: whoareyouanas/app-store-google-play-review-scraper.
Connect a remote MCP client using OAuth with this configuration, or add an Authorization: Bearer <APIFY_TOKEN> header if your client uses token authentication:
{"mcpServers": {"appReviews": {"url": "https://mcp.apify.com?tools=actors,whoareyouanas/app-store-google-play-review-scraper,get-dataset-schema"}}}
After publication, agents can discover the actor with search-actors and inspect its contract with fetch-actor-details. Calls return run/storage IDs. Read results with get-dataset-items and get-key-value-store-record, obtain review field types with get-dataset-schema, and poll longer runs with get-actor-run. See Apify MCP documentation.
An agent's first inspection can use this bounded input. Turning off raw payloads here reduces response size; keep them enabled for a full archival export:
{"apps": ["310633997", "com.whatsapp"],"countries": ["us"],"languages": ["en"],"maxReviewsPerAppCountry": 25,"maxReviews": 50,"maxReviewsScannedPerAppCountry": 500,"maxRequestsPerAppCountry": 50,"includeAppMetadata": true,"includeRawData": false}
Agent workflow:
- Read
fetch-actor-detailswith the actor identifier andoutput: { inputSchema: true, readme: true, outputSchema: true }. Resolve app IDs/URLs and choose storefronts, filters and finite caps. Usecall-actorwithcallOptionsfor memory, timeout ormaxTotalChargeUsd; those controls are outside actor input. - Wait for a terminal run status, then read
SUMMARYand inspect failed contexts, stop reasons and field coverage. - Read the preview or page the dataset with
limit/offset,clean: falseand selectedfields. Useget-dataset-schemafor the collected field types. ReadSUMMARY/APPSwithget-key-value-store-recordusingkeyValueStoreIdandrecordKey; follow profile keys for full app context. - Join on
reviewKey. Treat null values as unavailable, preserve date/vote semantics, and base conclusions on the exported sample and reported coverage.
Example prompt: “Compare one- and two-star feedback for these iOS and Android apps in the US. Start with 50 reviews per app. Identify recurring problems using quoted source text and review IDs, and report any collection limits.”
API example
Install the official apify-client package and set APIFY_TOKEN in your environment. Run limits are separate from actor input:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('whoareyouanas/app-store-google-play-review-scraper').call({apps: ['310633997', 'com.whatsapp'],countries: ['us'],languages: ['en'],maxReviewsPerAppCountry: 50,maxReviews: 100,includeRawData: true}, { memory: 512, timeout: 600, maxTotalChargeUsd: 1 });const report = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('SUMMARY');if (run.status !== 'SUCCEEDED' || report?.value?.failedPartitions > 0) {throw new Error('Inspect the run log and SUMMARY before using partial results.');}const page = await client.dataset(run.defaultDatasetId).listItems({ limit: 100, offset: 0 });console.log(page.items);const appIndex = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('APPS');console.log(appIndex?.value);
For larger exports, keep increasing offset until an empty page is returned. Retrieve the full APP_* records named in the index. The equivalent REST workflow starts with POST /v2/acts/whoareyouanas~app-store-google-play-review-scraper/runs, polls GET /v2/actor-runs/{runId}, then reads the default dataset/key-value store. See the official JavaScript client and run API.
Pricing
Launch pricing is $0.50 per 1,000 exported reviews ($0.0005 per unique dataset row), plus $0.00005 per run start. For example, 10,000 exported reviews cost $5.00005 before tax. No rental subscription is required. App profiles and collection reports are included; duplicate candidates and filter rejects do not create review charges.
Apify's maximum run charge can stop collection before your review caps are reached. The report records this as spending_limit. Interrupted/resurrected runs retain delivered rows and reconcile them before continuing.
Reliability and support
The actor has been validated with 5,000 distinct reviews from each store, multiple country/language contexts, public developer replies, filtered exports, Apify Proxy and interrupted-run recovery. These checks establish working collection paths, while available fields and reachable history remain source-dependent.
For a collection problem, share the run ID and SUMMARY errors/warnings through the actor's Issues tab. Keep app IDs, requested storefronts and filter settings in the report so the workload can be reproduced.
Metadata parsing uses pinned helpers from the MIT-licensed google-play-scraper; all network requests pass through this actor's timeout, proxy and retry controls.