App Store Review History Scraper - All Storefronts
Pricing
from $0.06 / 1,000 reviews
App Store Review History Scraper - All Storefronts
Apple caps App Store reviews at 500 per app per country. This Actor sweeps up to 175 storefronts, de-duplicates by review ID, normalizes timestamps to UTC and reaches far older reviews.
Pricing
from $0.06 / 1,000 reviews
Rating
0.0
(0)
Developer
HEESEOK HONG
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
2 days ago
Last modified
Categories
Share
App Store Review History Scraper — All Storefronts
Apple stops at 500 reviews per app per country. Ten pages of fifty. Page eleven does not exist, no matter which scraper you use or how much you pay for it.
For a popular app that means the US storefront holds only the last few days.
This Actor gets past that by sweeping up to 175 storefronts, de-duplicating by review ID, and giving you back one clean, chronological dataset.
The measurement that explains the whole product
WhatsApp Messenger (310633997), collected 2026-08-11:
| Storefront | Reviews available | Distinct app versions in them |
|---|---|---|
| United States | 500 (Apple's cap) | 3 |
| Mongolia | 46 (all of them) | 37 |
Large storefronts are a firehose with a short memory. Small storefronts are a trickle that remembers everything.
And the sweep compounds. One run across 44 storefronts of the same app returned 16,427 reviews covering 508 distinct app versions. The US storefront, on its own, offers three.
If you want reviews from the version you shipped last spring, they are not in the US feed. They are scattered across the small storefronts, and the only way to reach them is to sweep.
What you get per review
| Field | Notes |
|---|---|
reviewId | unique across the whole run; duplicates are dropped |
rating, title, body | rating is a number, not Apple's string |
appVersion | the version the reviewer was actually running |
isCurrentVersion | joined against live app metadata; null when unknown |
updatedAt | normalized to UTC — 175 storefronts otherwise means 175 offsets |
updatedAtLocal | Apple's original string, kept so you can check |
country, countryName, storefrontId | countryName in English |
authorName, authorId, authorUrl | read from the right field (see below) |
voteSum, voteCount, contentType, reviewUrl | |
raw | Apple's untouched record, so you can verify every field above |
An appProfile record per app carries name, seller, bundle ID, genres, current version and its release date, price, content rating, and the storefront-level rating average and count. It lands in the run's app-profiles dataset, separate from the reviews, so neither table has empty columns in it.
Coverage is measured, not promised
Every run produces a RUN_SUMMARY, and it is free — you are not charged for it. You will find it in the run's run-summary dataset and in the key-value store, and its headline numbers are printed in the log. It is kept out of the main dataset so your review table stays a clean table of reviews:
{"itemType": "RUN_SUMMARY","reviewsCollected": 16427,"countriesRequested": 175,"countriesWithReviews": 44,"skippedCountries": [{ "country": "bt", "reason": "noReviews" }],"partialCountries": [],"reviewsByCountry": { "us": 500, "gb": 500, "mn": 46 },"distinctAppVersions": 508,"duplicatesRemoved": 0,"apiCalls": 340,"rateLimitSignals": 0,"stoppedBy": null}
No Actor can promise 175 responding storefronts, because it depends on where the app is sold, and because Apple throttles hard sweeps. So this one reports exactly which storefronts answered, which returned nothing, and which were cut short — on every run.
stoppedBy is null unless one of your own limits ended the run early. There is no second, hidden cap — a short result set always has a stated reason.
Input
| Field | Default | |
|---|---|---|
appIds | — | Numeric IDs (310633997) or App Store URLs. The ID is extracted for you. |
countries | ALL | Storefront codes, or ALL for the full sweep. |
sortBy | mostrecent | mostrecent or mosthelpful. |
dateFrom | — | Drop older reviews. With mostrecent the Actor also stops paging a storefront as soon as a whole page predates your cutoff, which lowers your bill. |
maxReviews, maxReviewsPerCountry, maxApiCalls, concurrency | Every one is reported back in RUN_SUMMARY. |
Pricing
Pay per result. $0.12 per 1,000 reviews. App profiles are $0.002 each. There is no start fee, so a small test run costs you cents.
Notes on the source
Apple's public RSS feed needs no API key and no account — yours or ours. It is also inconsistent in ways that quietly corrupt naive scrapers, and each one is handled here and covered by a test:
- an unknown app ID returns HTTP 200 with a feed whose
entrykey is absent, not empty - the
nextlink over-reports and walks past the end of the data forever; onlylastis honest - every pagination link points at an XML endpoint, so following one returns XML, not JSON
- a storefront with exactly one review returns an object where every other storefront returns an array
author.labelis always an empty string; the real name is one level down
Apple throttles with HTTP 403, not only 429 — measured at roughly 14 requests per second, after 340 requests. So requests are paced across all workers, the pacing widens automatically whenever Apple pushes back and narrows again once responses are clean, and a throttled storefront is retried on a second, slower pass. If it still will not answer, it is reported in skippedCountries and the rest of the sweep continues.
Reviews are not shared between storefronts, so measured cross-storefront duplication is zero. De-duplication is a guarantee here, not a feature — it means a reviewId never appears twice in your dataset even when you re-run or overlap storefronts.
Questions or a field you need added: open an issue on the Actor's Issues tab.