App Store Reviews Scraper avatar

App Store Reviews Scraper

Pricing

from $0.84 / 1,000 results

Go to Apify Store
App Store Reviews Scraper

App Store Reviews Scraper

Apple App Store customer reviews across as many storefronts as you name. Apple caps every app at 500 reviews per storefront and sort, but each storefront holds a completely different set - so widening the country list is the only way past it, and the actor reports which pairs hit the ceiling.

Pricing

from $0.84 / 1,000 results

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Customer reviews from Apple's App Store — rating, title, body, app version, author and vote counts — across as many storefronts as you name. HTTP-only, no API key, no login, no browser.

The one thing to understand before you run it

Apple serves a hard maximum of 500 reviews per (app × storefront × sort). Page 10 is the last page that exists; page 11 answers HTTP 400. No parameter lifts it. An app with three million reviews will hand back five hundred.

But every storefront holds a completely different set of reviews. Measured on WhatsApp, page 1, same minute:

storefrontreviewsoverlap with US
us50
gb500
de500
jp500
id500
br500

…each in that storefront's own language. So widening countries is the only way past 500, and reach is roughly 500 × countries × sorts. The summary publishes theoreticalMaxForThisGrid so you can see what your grid can reach before you run it, and ceilingsHit names every pair that ran all ten pages full — meaning there are more reviews upstream that the endpoint will not serve at any page number.

Three more upstream quirks it corrects

1. Only two sorts work, and the broken ones return HTTP 500

sortByResult
mostRecent200, 50 reviews
mostHelpful200, 50 reviews
mostFavorableHTTP 500
mostCriticalHTTP 500
nosuchsortHTTP 500

mostFavorable and mostCritical look like supported values, and they fail with the same 500 a genuine outage produces. A client that retried would burn its budget on something that can never work; one that reported "upstream is down" would be wrong. Both are refused locally, by name, with an explanation.

The two working sorts return near-disjoint sets — their first pages shared nothing at all, though a full walk of one storefront turned up a single review under both. Deduped by (country, reviewId) and counted, not assumed away.

2. An unknown app id returns HTTP 200 with an empty feed

Exactly what a real app with no reviews in that storefront returns. There is no way to tell them apart from the feed alone — so the actor resolves the app through Apple's lookup endpoint first and reports appResolved. A run that comes back empty with appResolved: false almost certainly has a wrong id.

3. Every value is wrapped

im:rating is {"label": "5"} — a string inside an object. author.name is {"label": "..."} while author.label is an empty string that looks like it should hold the name. Nothing is read directly; every field is unwrapped and coerced, and a changed wrapper costs one field rather than the run.

Output

One SEARCH_SUMMARY per run, one REVIEW per review, one ERROR per storefront/sort pair that failed.

REVIEW: appId, appName, country, sortUsed, reviewId, title, review, rating, appVersion, authorName, authorUrl, updatedAt, voteSum, voteCount, pageFetched, resultRank.

SEARCH_SUMMARY adds appResolved, reviewsPerCountry, ceilingsHit, emptyStorefronts, theoreticalMaxForThisGrid, duplicateReviewsDropped and a ratingHistogram.

Limits

  • 500 per app × storefront × sort, structurally. Widen countries to reach more.
  • Reviews are per-storefront and in that storefront's language — a multi-country run is deliberately multilingual.
  • Apple ships a vote sum and a vote count, not a helpful/unhelpful split.
  • No WAF on this host; a proxy is offered but was not needed for any of the reconnaissance.