App Store & Google Play Reviews Scraper
Pricing
$0.40 / 1,000 review scrapeds
App Store & Google Play Reviews Scraper
Collect public reviews from Google Play and the Apple App Store: rating, text, author, date. Apple may return only ~10 public-page reviews per app per country. Repeat monitoring: each run saves a Next run input that skips reviews you already have, plus a per-app coverage CSV. Pay per new review.
Pricing
$0.40 / 1,000 review scrapeds
Rating
0.0
(0)
Developer
Datamule
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
Scrape public customer reviews from the Apple App Store and Google Play: star rating, title, review text, author and date, per app and country storefront. Pay only per review saved.
What you actually get: on Google Play, paginated reviews (newest or most relevant), with app version and thumbs-up count. On the App Store, Apple's review feed is often empty right now, so many apps return only the ~10 reviews Apple shows on the public app page per country (not date-sorted, no app version or votes). Every row says which source it came from, and a free per-app coverage file tells you what each app actually returned. This is not a full review history and there is no freshness guarantee.
Useful for app developers and PMs tracking sentiment after releases, ASO/marketing agencies watching client and competitor apps, and researchers mining feature requests.
Quick start: first run, then only new reviews
-
First run (about $0.01). The prefilled input is the tested example: Spotify and Duolingo, US App Store,
maxReviews10. Click Start. In our own cloud test of exactly this input, each app returned 10 rows fromapp_store_web_page(20 rows total).{"apps": ["https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580", "570060128"],"store": "app_store","country": "us","sort": "recent","maxReviews": 10}For Google Play, set Store to Google Play and use a package name such as
com.spotify.music. -
Check coverage. In the run's Output tab, open Per-app coverage (CSV). One row per app:
status,reason,sourceUsed,deliveredRows.app_store_web_pagemeans you got the ~10-review page sample;..._retry_latermeans Apple throttled that app, so try it again later. BlankdeliveredRowsmeans unknown, not 0. -
Download Next run input. In the same Output tab, download Next run input. It is this run's settings plus
excludeReviewKeys, the keys of every review you just saved. -
Run again yourself. Start a new run, switch the Input tab to JSON, paste the file and click Start. Reviews you already have are skipped: not stored, not charged, not counted toward
maxReviews. Nothing is scheduled or started for you. In our own test (Google Play, Spotify,maxReviews3), the second run skipped the 3 known reviews and saved 3 new ones. On the App Store page sample, a repeat run can return 0 new reviews if Apple shows the same 10 again; that costs nothing.
Finding an app ID: on apps.apple.com the digits after id in the URL are the ID (.../id324684580). You can also paste the whole URL.
Coverage and limits (read this)
- Google Play: paginated, sorted by newest or most relevant; thousands of reviews per app are possible. Includes app version and thumbs-up count.
- App Store: the Actor first uses Apple's public customer-reviews feed (up to ~500 per app/country, date-sorted, with app version and votes). In September 2026 that feed has been returning empty results for many apps. When it is empty or errors, the Actor falls back to the reviews Apple shows on the public app page: about 10 per app per country, not date-sorted, and without app version or vote counts. Every row carries a
sourcefield (itunes_rss,app_store_web_page,google_play) so you always know which you got. - Want more App Store coverage? Run several countries (
us,gb,ca,au, …); each storefront has its own reviews. - You are only charged for review rows actually returned. A run that finds nothing costs nothing in review events.
- App Store reviews are public store reviews, not proof of a verified purchase.
Check what each app and country actually returned
After a run, open the Output tab and click Per-app coverage (CSV) (the COVERAGE record in the run's key-value store). It has one row per app you asked for, in input order:
| Column | Meaning |
|---|---|
status | success, partial (spending limit hit mid-app, or Apple stopped answering after some rows were saved), empty (source answered with no reviews), unavailable (source errored, e.g. HTTP 404), invalid_input, error (run failed on that app; rows unknown), or not_attempted |
reason | Why: max_reviews_reached, fallback_page_sample_exhausted, source_exhausted, all_already_seen, charge_limit, rate_limited_retry_later / transient_error_retry_later (Apple throttled or failed; run that app again later), the HTTP error, or run_ended_before_app |
sourceUsed | Where the delivered rows came from: itunes_rss, app_store_web_page, google_play, none, or unknown (not fetched) |
deliveredRows | Review rows actually stored in the dataset for that app. Blank means unknown (never reached), which is not the same as 0. |
If sourceUsed is app_store_web_page, you have the public page sample (about 10 reviews), not the app's full review history. It is not date-ordered and should not be treated as representative for sentiment. It only tells you what was delivered. It does not report how many reviews the app has in total. The CSV is free: no extra rows or charges, and no extra requests to Apple or Google. Run storage is private to your account, so open the link from the Console or add your API token.
When Apple is slow or rate-limits
Apple's review sources sometimes answer with HTTP 429 (too many requests) or a temporary 502/503/504. The Actor retries each Apple request at most 3 times. It waits exactly as long as Apple's Retry-After header asks and never retries a 429 immediately. Retry waiting is capped at 20 s per wait, 30 s per app and 60 s per run, and it never runs into the Actor timeout. If Apple asks for a longer wait, the Actor stops that app instead of hammering and marks it ..._retry_later in COVERAGE. Rows already saved are kept and billed once; a later-page failure shows partial, not "exhausted". After a 429 the Actor does not switch to another Apple page or IP to get around it, and it skips further requests to that same Apple host (feed or page) for the rest of the run. Other errors (404, 403, 500, …) are not retried; on a later feed page they still mark the app partial. Recovery is not guaranteed: a persistent rate limit can still give you 0 rows, and then you pay nothing for review events. If a retry did recover, the note column says so.
Repeat monitoring: skip reviews you already have
Running the same apps on a schedule? Pass the reviews you already collected in Skip already-seen reviews (excludeReviewKeys) and they are not stored and not charged, and they don't count toward Max reviews.
Each key is store:appId:country:reviewId, built from the matching columns of a previous run's dataset. Example from a real Spotify US run:
{"apps": ["324684580", "570060128"],"store": "app_store","country": "us","maxReviews": 10,"excludeReviewKeys": ["app_store:324684580:us:11994640656","app_store:324684580:us:9447841001","app_store:570060128:us:14158523706"]}
You don't have to build the list yourself. Every run saves a ready-made list in the Already-seen review keys output (key-value store record SEEN_REVIEW_KEYS). It is a JSON array you can paste straight into Skip already-seen reviews on the next run:
- Run the Actor. Open the Output tab and download Already-seen review keys.
- Next run, paste that array into
excludeReviewKeys. Only new reviews are stored and charged. - That run's list has its new keys first, followed by the keys you passed in. Keep pasting the latest list and it builds up over time. (With the API: fetch
/key-value-stores/{defaultKeyValueStoreId}/records/SEEN_REVIEW_KEYSfrom the previous run and pass it asexcludeReviewKeys.)
The list only contains keys of rows that were actually saved to the dataset. Rows cut off by your spending limit are not in it. Rows with no review ID can't be listed; the companion record SEEN_REVIEW_KEYS_INFO counts them (unkeyedRowsNotExported). The limit is 5,000 keys. If adding this run's keys would go past it, the oldest keys you passed in are dropped from the end. droppedOverLimit shows how many and complete becomes false, so you know the list is no longer your full history. The list holds keys only: no review text and no author names.
Or skip the pasting step entirely: download the whole next input. Runs also save Next run input in the Output tab (record NEXT_RUN_INPUT). It is this run's exact settings (apps, store, country, language, sort, maxReviews, with defaults written out) plus excludeReviewKeys set to the same key list as above:
- Open the finished run's Output tab and download Next run input.
- Start a new run, switch the Input tab to JSON and paste it (or send it as the run input via the API).
- Start the run yourself. Nothing is scheduled or launched for you. You are charged only for reviews actually saved in that run, at the normal per-review price.
It never raises your caps and carries nothing else: no proxy, tokens, cookies or account/run details. The same limits apply as for the key list: at most 5,000 keys (check complete and droppedOverLimit in SEEN_REVIEW_KEYS_INFO), rows without a review ID are not tracked, and apps that were partial or unavailable in COVERAGE stay partial. It does not guarantee you will see every new review. If a run is stopped or times out, the file (when it could be written) holds only the keys of rows that were really saved. If the run's own settings could not be reused as-is, the file is skipped and the log says why; SEEN_REVIEW_KEYS is still there.
To build the list by hand instead, export the previous dataset (JSON or CSV) and join store, appId, country and reviewId with : for each row. Up to 5,000 keys per run. Keys include the store, app and country, so the same review ID in another app or storefront is never skipped by mistake.
What it does and doesn't do:
- Exact ID match only. No text or fuzzy matching. An edited review keeps its ID, so it stays skipped. This is new-review monitoring, not change detection.
- Rows with no
reviewIdare never skipped (there is nothing reliable to match on). - It does not dig deeper to find new reviews. The same source limits apply: on the App Store page sample (~10 reviews) a run can return 0 new rows if Apple shows the same reviews again. For Google Play and the RSS feed the Actor asks for at most one extra row per key for that app, then stops.
- The
COVERAGECSV gains askippedAlreadySeencolumn (distinct matched keys per app). If every fetched review was already seen, the app showsstatus=success,reason=all_already_seen,deliveredRows=0. That is a successful empty run, not an error; source failures still showunavailable. - The key list is a record of what this Actor saved, not a guarantee of full or continuous history. Apple only exposes a limited number of pages (RSS up to ~500, page sample ~10), so reviews that fall outside those pages between your runs are never seen or listed.
- Keys are public store IDs, not personal data, but keep your exported datasets private as usual.
Input
| Field | Description |
|---|---|
apps | List of app IDs or store URLs. App Store: 324684580 or https://apps.apple.com/us/app/spotify/id324684580. Google Play: com.spotify.music or its Play URL. |
store | app_store or google_play. |
country | Two-letter storefront code (us, gb, sg, de…). Reviews are country-specific. |
language | Two-letter language (Google Play only). |
sort | recent or helpful. |
maxReviews | Max reviews per app. See Coverage and limits above. |
excludeReviewKeys | Optional. Up to 5,000 store:appId:country:reviewId keys to skip (not stored, not charged). See Repeat monitoring above. |
Output
One record per review:
{"store": "app_store","appId": "324684580","country": "us","reviewId": "...","author": "jane_doe","rating": 5,"title": "Love it","text": "Works great, but…","appVersion": "9.1.60","voteSum": "3","updated": "2026-07-04T12:00:00-07:00","source": "itunes_rss"}
Data sources
- Apple: the public iTunes RSS customer-reviews feed, with a fallback to the reviews embedded in the public apps.apple.com page when the feed is empty. No login.
- Google Play: the maintained
google-play-scraperlibrary, which tracks Google's review endpoint so results stay reliable.
Pricing
Pay-per-event: you're charged per review returned. No subscription — you only pay for what you pull: $0.0004 per review (about $0.40 per 1,000), with volume discounts on higher Apify plans.
Built with the Apify SDK for Python. Runs serverless on the Apify platform.
Rebuild and verify (maintainer)
apify push from this folder, then run the prefilled input on the cloud and check the dataset has rows with a source field and that the COVERAGE CSV deliveredRows sum equals the dataset row count. Tests: PYTHONPATH=. python -m unittest tests/test_coverage.py tests/test_exclude.py tests/test_seen_keys.py tests/test_retry.py. Rollback: re-tag build 0.1.6 (PbigN5OUTh04Vxt4Z) as latest.