App Store Reviews Scraper — Deep, Multi-Country, Dev Replies avatar

App Store Reviews Scraper — Deep, Multi-Country, Dev Replies

Pricing

$0.10 / 1,000 per review returneds

Go to Apify Store
App Store Reviews Scraper — Deep, Multi-Country, Dev Replies

App Store Reviews Scraper — Deep, Multi-Country, Dev Replies

Apple App Store reviews from Apple's own review API: rating, title, body, author, date and developer reply, one row per review. Goes past the 500-review RSS cap — verified 150,000 reviews deep on one app — and sweeps many countries in one run. $0.10 per 1,000 reviews. No login, no token.

Pricing

$0.10 / 1,000 per review returneds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

App Store Reviews Scraper — Deep, Multi-Country, With Developer Replies

Turn any app's Apple App Store reviews into clean rows, straight from Apple's own review API. One row per review: rating, title, body, userName, date, country, appId, appName, isEdited, developerResponseBody, developerResponseDate, position — plus appVersion, voteCount, voteSum and authorUrl in recent mode. Filter by star rating or developer-reply presence, sweep as many storefront countries as you want in one run. No login. No API token. No browser.

Scope: this Actor paginates the whole review corpus, not the first feed page — verified live on 2026-08-15 by walking one app (WhatsApp, US storefront) to offset 150,000 (page 7,500) and still getting rows back. Apple's public RSS feed — which is what many review scrapers actually read — hard-caps at 500 reviews per app per country (page 11 returns zero entries, measured). If the reviews you need are older or deeper than the newest 500, the cap is the difference between a sample and the corpus.

{
"apps": ["https://apps.apple.com/us/app/whatsapp-messenger/id310633997"],
"countries": ["us", "gb", "au"],
"mode": "deep",
"maxItems": 600,
"maxReviewsPerAppCountry": 200
}

Click Try for free and hit Start — that block is literally the input the Actor ships with. A run on those shipped defaults returned 600 reviews (exactly 200 per country) in 30 requests with 0 duplicates and 0 failures, rating/title/body/author/date all 100% filled, for $0.06.


The wedge: the corpus, not the sample — in every country at once

Three things this Actor does that the RSS-cap scrapers cannot:

  • Deep pagination. Apple's review API serves the full written-review corpus, most helpful first. Measured: 150,000 reviews deep on one app x country and still going; a 2,000-review contiguous walk of Slack US came back 2,000 unique, 0 duplicates, in 1m15s. The 500-review feed cap does not apply here.
  • Multi-country in one run. Reviews are storefront-specific — WhatsApp's US reviews and its German reviews are two disjoint corpora. countries takes any list of storefront codes and every app is crossed with every country, each pair walked, counted and capped separately. Verified live on nine storefronts (us, gb, de, jp, fr, br, in, au, kr).
  • Developer replies. Deep mode carries the publisher's public reply where one exists (developerResponseBody + developerResponseDate) — measured 31.75% of 2,000 Slack US reviews, 2.2% on WhatsApp, 0% on Duolingo's first 100. The onlyWithDeveloperResponse filter turns any competitor's support behaviour into a dataset: what they answer, what they ignore, how fast.

As of 2026-08-15 the Apify Store has 12+ actors on "app store reviews" — this lane has real demand and real competition. Judge this page on its measured numbers: the depth, the 0.00% duplicate rate, the per-mode field-fill tables below, and a price at the floor of the lane ($0.10 per 1,000).


Read this before you buy rows

Six things that would otherwise turn into a refund request.

  1. Deep mode is most-helpful order, not newest-first. That is the order Apple's API serves, and its sort parameter is silently ignored (measured: identical pages with and without it). If you need newest-first, that is mode: "recent" — Apple's date-sorted feed — which caps at 500 per app x country. Deep = complete, helpfulness-ranked; recent = fresh, capped. Pick per job.
  2. appVersion, voteCount, voteSum and authorUrl are null in deep mode — always. Apple's review API simply does not return them; only the RSS route (recent mode) carries them. Measured fill: 0.0% in deep mode, 100% in recent mode. If you need "which version was this complaint written against", use recent mode.
  3. Reviews are not ratings. WhatsApp shows 18.4M US ratings (star taps); its written-review corpus in the US storefront ended between offset 150,000 and 200,000 when measured. Expect written reviews to be a low single-digit percentage of the rating count Apple advertises on the store page.
  4. No reviewer contact data exists — at all. userName is a public nickname ("Can't Share Album"), never a real name, and Apple publishes no email, no phone, no location for reviewers. If a lead list is what you need, this is the wrong source.
  5. recent mode runs out at 500. That is Apple's feed cap, not a bug and not this Actor's limit — the run logs "feed exhausted" and moves on rather than pretending there is more.
  6. A country with no reviews is a warning, not an error. Apps are not sold in every storefront and small storefronts often have zero written reviews. The run reports "no reviews in this storefront" per app x country and keeps going; you are never billed for an empty pair.

What you get

One record shape in both modes — fields a mode cannot know are null, so your CSV columns never move. Dates are ISO-8601 UTC. rating is an integer 1–5.

GroupFieldsExample
IdentityreviewId, appId, appName, country11781634604 · 618783545 · Slack · us
Reviewrating, title, body, date, isEdited3 · "New Users Say it is difficult" · 2024-09-30T14:31:24.000Z
AuthoruserName, authorUrl (recent mode)Can't Share Album · https://itunes.apple.com/us/reviews/id…
Developer reply (deep mode)developerResponseBody, developerResponseDate"Hi there, We'd be interested in hearing more…"
Version & votes (recent mode)appVersion, voteCount, voteSum26.08.10 · 4 · 3
Provenanceposition, order, source, appUrl, scrapedAt354 · mostHelpful · app-store-api

position is the review's 1-based rank within its app x country walk — in deep mode that is Apple's helpfulness rank, a signal in its own right.


Field fill — measured, per mode

Deep mode, 2,000-review contiguous walk of Slack US (2026-08-15):

FieldFillNotes
reviewId / appId / appName / country100%
rating / title / body / userName / date100%
isEdited100%true on 3.0% of rows
position / order / source / appUrl / scrapedAt100%
developerResponseBody / developerResponseDate31.75%publisher-dependent: 2.2% on WhatsApp, 0% on Duolingo's first 100
appVersion / voteCount / voteSum / authorUrl0%Apple's API omits them — recent mode only

Recent mode, 300 reviews (Slack, US + DE, 2026-08-15):

FieldFillNotes
reviewIddate (all core fields)100%
appVersion100%the version the review was written against
voteCount / voteSum100%helpful votes; 0 is a real zero
authorUrl100%the reviewer's public iTunes profile URL
isEdited / developerResponseBody / developerResponseDate0%the feed omits them — deep mode only

The ratings in a deep walk are the real distribution, not a happy-path sample — the 2,000 Slack rows split 1★ 319 · 2★ 263 · 3★ 312 · 4★ 294 · 5★ 812. Every run prints its own measured fill in the log.


How to run it

1. The default — one app, three countries

The shipped input above. 600 reviews across us/gb/au for $0.06.

2. A competitor's whole review corpus

{
"apps": ["https://apps.apple.com/us/app/slack/id618783545"],
"countries": ["us"],
"mode": "deep",
"maxItems": 100000,
"maxReviewsPerAppCountry": 0
}

Walks until Apple's corpus ends (the log says "corpus exhausted" with the true count) or maxItems is hit, whichever comes first. maxItems is your hard cost cap: 100,000 = $10.

3. Complaint mining — 1–2★ only

{
"apps": ["310633997"],
"countries": ["us", "gb", "ca", "au"],
"mode": "deep",
"minRating": 1,
"maxRating": 2,
"maxItems": 5000
}

Filtered-out reviews are fetched but never billed — you pay for the 1–2★ rows you receive, not the 5★ rows discarded on the way.

4. Support-behaviour audit — only reviews the developer answered

{
"apps": ["618783545"],
"countries": ["us"],
"mode": "deep",
"onlyWithDeveloperResponse": true,
"maxItems": 2000
}

5. Version-tagged fresh reviews, on a schedule

{
"apps": ["310633997"],
"countries": ["us", "gb", "de", "fr", "jp", "br", "in"],
"mode": "recent",
"maxItems": 3500
}

Newest-first with appVersion and vote counts on every row — the release-quality monitor. Save it as a Task (Console → Save as Task), attach a Schedule (0 7 * * * for a daily pull), and diff on reviewId downstream. The dataset is available over the REST API and the standard integrations (Zapier, Make, n8n, webhooks, MCP). From the API:

curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~appstore-reviews-scraper/runs?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"apps":["310633997"],"countries":["us"],"mode":"recent","maxItems":500}'

Countries

Any 2-letter storefront code Apple runs (~175 of them):

us gb ca au de fr it es nl jp kr cn hk tw sg in br mx ar cl co pe ru tr sa ae il za ng eg pl cz se no dk fi pt gr…
— nine of them verified live in testing (us, gb, de, jp, fr, br, in, au, kr). An unknown code is reported per app x country ("Unknown storefront 'zz'") and costs you nothing.


Sample row

A real row from an actual run, captured 2026-08-15 (deep mode, Slack US):

{
"reviewId": "11781634604",
"appId": "618783545",
"appName": "Slack",
"country": "us",
"rating": 3,
"title": "New Users Say it is difficult",
"body": "I have used many business communication tools. What I hear often from new users and trying to get people to integrate into and use slack as opposed to calling or Texting on a phone, is how difficult it is to use and it is not intuitive. Since it is under the control of an administrator, there is little ability for people to organize in a way that they can get the information they need quickly.",
"userName": "Can't Share Album",
"authorUrl": null,
"date": "2024-09-30T14:31:24.000Z",
"isEdited": false,
"appVersion": null,
"voteCount": null,
"voteSum": null,
"developerResponseBody": "Hi there, \nWe'd be interested in hearing more about any frictions new users are having when using Slack. When you have a moment, please navigate to your app's \"You\" tab - \"Preferences\" - \"Send Feedback\" to flag this with our support team and provide some logs we'll need to investigate. We'll be happy to help!",
"developerResponseDate": "2024-10-02T09:28:51.000Z",
"position": 354,
"order": "mostHelpful",
"source": "app-store-api",
"appUrl": "https://apps.apple.com/us/app/id618783545",
"scrapedAt": "2026-08-15T04:19:21.260Z"
}

Fields people misread:

  • position: 354 — Apple's helpfulness rank, not a date rank. In recent mode it is the recency rank instead, and order says which one you got.
  • voteCount/voteSum are null here because this is a deep-mode row, not because nobody voted. In recent mode they are filled, and 0 there is a real zero.
  • isEdited: false means the reviewer never revised the review; null (recent mode) means Apple's feed doesn't say.

Input

Fields in the order the Console shows them.

FieldTypeDefaultWhat it does
🎯 What to scrape
appsstring listWhatsApp URLApp Store URLs or bare numeric ids. A wrong id is reported and skipped before anything is billed. Left empty, the WhatsApp sample runs.
countriesstring list["us","gb","au"]Storefront codes, one per entry. Every app is crossed with every country.
modeselectdeepdeep = whole corpus, most-helpful order, developer replies. recent = newest 500 per pair, appVersion + votes.
🎚️ Filters (applied before billing)
minRating / maxRatinginteger0 (off)Star-rating window, 1–5. minRating: 1, maxRating: 2 = complaints only.
onlyWithDeveloperResponsebooleanfalseDeep mode only — recent mode has no replies and the run says so rather than returning nothing.
📊 Output & cost
maxItemsinteger600Your hard cost cap. 600 = $0.06, 10,000 = $1, 100,000 = $10. Counts unique delivered reviews only.
maxReviewsPerAppCountryinteger200 shipped / 0 = offPer-corpus cap so one deep storefront cannot eat the whole budget before the others get a turn.
⚙️ Advanced
maxConcurrencyinteger3App x country pairs walked in parallel, max 5. Pages within a pair are sequential by nature.
proxyConfigurationproxyApify datacenterOn by default — see the measured ladder below. Residential is not needed.

Pricing

$0.0001 per review returned — $0.10 per 1,000. Charged on the review-scraped event. No actor-start fee, no monthly fee from this Actor. That is the floor of this lane, deliberately: reviews are high-volume rows and are priced like it.

RunReviewsCost
The shipped default (WhatsApp, 3 countries)600$0.06
A full recent-mode sweep, 7 countries3,500$0.35
A mid-size app's whole US corpus20,000$2.00
A whale's whole US corpus100,000$10.00
  • You are charged for rows delivered. Duplicates are dropped before billing (measured duplicate rate: 0.00% — and the run verifies it, see below). Reviews removed by your rating/reply filters are fetched but never charged.
  • Rows are charged as they are pushed, so a budget cap gives you whole rows and a clean stop, never a half-billed dataset.
  • Every run ends with a billing integrity check: the dataset row count must equal the charged-review count exactly, or the run errors instead of over- or under-billing.

Honest limits

  • No reviewer emails, phones, or real names — ever. Apple publishes nicknames only. This is a voice-of-customer source, not a lead-gen source.
  • Deep mode cannot give you appVersion or helpful votes (0.0% measured — Apple's API omits them), and recent mode cannot go past 500 per app x country or carry developer replies (Apple's feed, Apple's rules). The two modes exist because neither Apple route carries everything; the record shape is identical in both so you can union the datasets downstream.
  • Deep order is Apple's helpfulness ranking and cannot be changed — the API ignores its own sort parameter (measured). There is no "oldest first" on any public Apple route.
  • No date-range filter. Deep mode is not date-ordered, so a server-side date slice does not exist; filter on date downstream. In recent mode, newest-first plus maxItems is the practical date window.
  • Written reviews are a small fraction of the advertised rating count (see gotcha 3). An app showing "50K ratings" may have only a few thousand written reviews. The log prints each app's worldwide rating count at start so you can calibrate expectations.
  • Rate limits are real. Apple 429-throttles busy IPs. The Actor absorbs this (measured 100% page success through the default proxy with fresh-session retries), but a 100k-review corpus still takes on the order of an hour, not minutes: measured throughput ~27 rows/s single pair, 45.7 rows/s across pairs.

How it works, and what it cost to make reliable

Deep mode reads Apple's own review API (amp-api) through the same-origin route the App Store web front-end itself uses — the route that needs no token (the dedicated API hosts demand a bearer JWT that Apple no longer embeds in the page; this Actor needs no JWT at all). Recent mode reads Apple's public customer-reviews feed. App ids are validated against Apple's lookup API before anything is walked, so a typo is caught in second one with a clear message, not after a paid crawl.

Transport ladder, measured 2026-08-15, retries off:

RungResult
Direct, one IP, conc 3 @ 16.5 req/s13/20 = 65% (7x HTTP 429 — rate limit, no bot wall)
Apify datacenter, one pinned session18/20 = 90%
Apify datacenter, fresh session per request24/30 = 80%
Apify RESIDENTIAL18/20 = 90%

There is no Cloudflare, no CAPTCHA, no challenge page — only a per-IP token-bucket rate limit. So the shipped transport is the cheap datacenter rung plus the thing the measurements actually justify: a per-worker pinned session for rate-budget locality, and every retry on a fresh exit IP with exponential backoff. Sustained load, as shipped:

TestResult
50 contiguous pages, conc 3, through Apify datacenter50/50 = 100%, 1,000 rows, 45.7 rows/s
2,000-review contiguous walk (100 pages), in-actor100/100 pages, 0 failures, 1m15s
Shipped-default run (30 requests, 3 countries)30/30, 0 failures

Concurrency is capped at 5 on purpose: Apple rate-limits per IP, and past ~3 workers more concurrency mostly buys more 429-retries, not more rows.


Duplicates — measured, then verified every run

WalkRowsDuplicates
20 contiguous pages, direct (x2 runs)8000
50 contiguous pages through Apify proxy1,0000
2,000-review in-actor walk, Slack US2,0000
Shipped default, 3 countries6000

Apple's offset pagination is stable — 0.00% overlap on every contiguous walk measured. The Actor still dedupes run-wide on appId:country:reviewId before billing, logs the count it dropped, and then asserts that the charged-event count equals the delivered row count exactly — and cross-checks the dataset row count — before the run may succeed. That assertion is not decorative: during development it caught a concurrency bug that pushed 1,620 rows for 600 counted ones, and it now guards every run you pay for.

Across runs, dedupe on reviewId downstream — it is Apple's own stable id for the review.


When something goes wrong

Every diagnosis lands in the run's status message and the log, and a run that returns nothing bills $0. A misconfigured input ends the run Succeeded with the explanation attached rather than red-failing — you get the same sentence either way, and your account keeps a clean run history.

  • A wrong app id → validated against Apple's lookup API before anything is walked: "App id 999999999999 does not exist on the App Store (Apple's lookup API returned 0 results) — skipping it." The other apps in the list still run; if none of the ids exist, the run stops there and bills nothing.
  • A wrong country code → shape errors ("usa,gb" in one field) are dropped with the fix spelled out; a well-formed but unreal code (zz) is reported per pair while the real countries deliver.
  • 0 rows overall → the status message lists every app x country pair with its individual outcome, plus how many reviews your filters discarded, so a filter problem never masquerades as an Apple problem. Nothing is billed.
  • Repeated request failures mid-corpus → the pair stops, the log says exactly how many reviews were delivered up to the stop point, and the run warns. Delivered rows are complete up to that point — re-run to continue. Apple's wall is a per-IP rate limit, not a block, so a re-run a few minutes later clears it.
  • The run time limit → the Actor stops fetching before the platform would kill it, pushes everything already collected, and says so: "Stopped early to stay inside this run's time limit — N reviews were delivered and charged." A deep multi-country sweep is never lost to a timeout.
  • No input at all (a bare {} from the API, MCP or an agent) → the Actor runs its documented WhatsApp sample so you always get real rows back, and warns that it did.
  • Billing mismatch → the integrity check errors the run rather than billing wrong. This is the one condition that still fails loudly, deliberately.
  • A storefront with no reviews, or a recent-mode feed ending at 500, is a warning / info, not an error — the log says which and why.

Who buys this

  • App developers watching competitors — the full corpus, their developer-reply behaviour included, not the newest 500.
  • ASO agencies — complaint mining by star window across every storefront a client sells in, in one run.
  • VoC / review-mining and NLP pipelines — clean UTF-8 JSON with stable ids, ISO dates and a fixed schema in both modes; maxItems makes corpus cost exactly predictable ($0.10 per 1,000).
  • Churn and release analysts — recent mode's appVersion on 100% of rows ties sentiment to releases; a scheduled Task turns it into a time series.
  • Support teamsonlyWithDeveloperResponse benchmarks reply rates and reply latency (developerResponseDate minus date) against anyone in the store.

FAQ

Does this need an account, login, cookies or an API key? No. Both routes are public Apple endpoints; the Actor holds no credentials at all.

Can I get every review an app has ever received? Deep mode walks until Apple's corpus ends and tells you when that happens ("corpus exhausted at N reviews"). Verified 150,000 deep on one app x country. Note Apple serves written reviews — a fraction of the advertised star-rating count.

Why are appVersion and votes empty in my deep-mode run? Because Apple's review API does not return them on any parameter combination we could measure. They exist only on the RSS route = recent mode. This is the single most misunderstood thing about App Store review data — see gotcha 2.

Can I sort deep mode by date? No — Apple ignores the sort parameter on its review API (measured). Deep mode is most-helpful order; recent mode is newest-first. order on every row says which you got.

Which countries work? Any storefront Apple runs (~175). Nine verified live in testing. Unknown codes are reported per pair and never billed.

Two runs — will I get duplicates? Within a run, never — deduped before billing and verified by the end-of-run integrity check. Across runs, dedupe on reviewId downstream.

Do I get charged for filtered-out reviews? No. Rating and reply filters run after fetching but before billing.

How fast is it? Measured: 45.7 rows/s across pairs, ~27 rows/s within one pair. The shipped default (600 rows) takes about a minute; 100,000 rows is an hour-plus, rate-limited by Apple.

Something looks wrong — how do I debug it? Read the run log: it prints per-app rating counts, per-pair outcomes, duplicate and filter counts, and measured field fill for every run. That usually separates a filter problem from an Apple-side change in one glance.


This Actor reads public review data from Apple's endpoints without any login, authentication bypass, or personal-data collection beyond the public nickname Apple itself displays on every review. For transparency: Apple's robots.txt on apps.apple.com includes Disallow: /api/* and on itunes.apple.com includes Disallow: /*/rss/* (fetched 2026-08-15) — robots directives aimed at search-engine crawling of those paths; the dedicated API hosts behind the store app publish no robots.txt. This Actor makes targeted, rate-limited reads of reviews for apps you explicitly specify. You are responsible for complying with Apple's terms of use and with how you use the data.

Apple®, App Store® and iTunes® are trademarks of Apple Inc. This Actor is not affiliated with, endorsed by, or connected to Apple.


Feedback

Found a missing field or want a new filter? Open an issue on the Issues tab, and if the Actor earns it, a review on the Reviews tab helps other buyers find it.