If you ship an app on both platforms, your users' frustration is split across two review walls that look superficially alike and behave nothing alike. To find the bug that spiked your one-star reviews, or to mine a competitor's pain points, you need both sets in one place, in one shape. This guide is the practical version: how to grab the right identifiers, beat the country gating that hides most reviews, reconcile two incompatible schemas, and end up with a table you can actually pivot. It assumes you want answers, not a tour of a dashboard.
Step 1: get the two identifiers (they are not the same)
Each store keys its app off a different kind of ID, and using the wrong one is the most common first mistake.
- Apple App Store uses a numeric App ID. Open the listing and read it off the URL: in
apps.apple.com/us/app/slack/id618783545the ID is618783545. Theusin that path is the storefront country — remember it for step 2. - Google Play uses a reverse-DNS package name. In
play.google.com/store/apps/details?id=com.Slackthe identifier iscom.Slack, taken verbatim from theid=query parameter.
You feed the numeric App ID to the Apple side and the package name to the Play side. They never interchange.
Step 2: the country gating trick
This is the detail that surprises everyone the first time. App reviews are not one global feed — they are served per storefront country. Scrape only the US storefront for a global app and you will quietly drop the German, Brazilian and Japanese reviews entirely, then wonder why your "complete" dataset is a quarter of the real volume. Apple's public review feed also caps depth per country (you will typically pull a few hundred of the most recent, not all of them), which makes looping over countries the only way to approach real coverage.
So decide your country list deliberately. For a churn investigation on an English-language app, ["us","gb","ca","au"] usually covers the bulk. For a truly global app, add the largest non-English storefronts. More countries means more reviews and more runtime, so scope it to the markets you actually care about.
Step 3: run both platforms
Hand both identifiers, your country list and a sort order to the scraper. sort: "newest" is what you want for monitoring and version analysis; "most_helpful" surfaces the loudest recurring complaints. A single call against the App Store Scraper Actor covers both stores:
curl -X POST "https://api.apify.com/v2/acts/renzomacar~app-store-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"appleAppId": "618783545",
"googlePackageName": "com.Slack",
"countries": ["us", "gb", "ca", "de"],
"sort": "newest",
"maxReviewsPerCountry": 300,
"includeRatingHistogram": true
}'
Step 4: normalise two stubborn schemas
This is where most one-off scripts fall apart. Apple and Google describe the same thing — a person rating your app — with different keys, and one carries fields the other simply does not have. Map both onto one common shape before you analyse anything:
| Common field | Apple App Store | Google Play |
|---|---|---|
| rating (1–5) | rating | score |
| title | title | none — Play has no title |
| body | review | text |
| author | userName | userName |
| date | updated | at |
| app version | version | reviewCreatedVersion (often null) |
| helpful votes | none | thumbsUp |
| developer reply | rarely exposed | replyContent + repliedAt |
Two consequences worth internalising: you cannot compare "title sentiment" across stores because Play has no titles, and you cannot reliably compare per-version on Play because reviewCreatedVersion is frequently null. Decide up front which cross-store metrics are even valid before you build a chart on a field one store doesn't populate.
platform: "ios" | "android" field to every normalised row as you merge. Half your useful insights ("are Android users angrier about the new paywall than iOS users?") only exist because you can group by it afterwards.A worked example: which release broke retention?
The question
Your one-star rate jumped this month and you suspect a specific update. Here is the analysis the merged dataset makes trivial.
- Filter to
rating ≤ 2on the iOS rows (whereversionis reliably populated). - Group by
versionand count. You see7.4.0carrying 3× the one-star volume of7.3.x— that release is the suspect. - Read the
title+bodyof the7.4.0one-stars. A cluster mentions "login loop after update". Now you have a reproducible bug, not a vibe. - Cross-check Android. Filter the same date window on
platform: "android". If the login-loop complaints are absent there, it is an iOS-only regression — which tells your engineers exactly where to look. - Quantify the reply gap. Count Android one-stars where
replyContentis null: those are angry users you never answered, a concrete support backlog.
None of that needs sentiment AI. It is grouping and counting on fields you already normalised — the value was in getting both stores into one comparable table.
Troubleshooting thin or stalled pulls
- I got 300 reviews but the app has 50,000
- That is the per-country feed cap, not a failure. The 50,000 is a lifetime global total. Add more countries to your list and raise
maxReviewsPerCountry; combine the runs to build volume. - Apple version field is great, Play version is mostly null
- Expected. Google often omits
reviewCreatedVersion. Fall back to the reviewdateand your own release calendar to bucket Android reviews by release window. - The run slows to a crawl on a big country list
- You are multiplying countries by reviews-per-country. Trim to the storefronts that matter, or split into several smaller runs by region and merge the datasets afterwards.
- Ratings look skewed positive
- If you sorted by
most_helpful, you are seeing the most-voted reviews, which skew old and polarised. Switch tonewestfor a representative recent sample.
includeRatingHistogram) reflects the rating right now; neither store hands you a rating timeline. If you want a trend line, you have to build it yourself from the dated individual reviews you scrape and bucket them by month. Plan to collect dated reviews continuously rather than expecting to rewind history later.Scrape both stores with one Actor
The App Store Scraper pulls Apple App Store and Google Play reviews, ratings and metadata by country — one input, clean JSON for both platforms, ready to normalise and pivot. Free Apify credits to start.
Run the App Store Scraper → Or get done-for-you leadsFAQ
Why do I get far fewer reviews than the app's total review count?
Both stores paginate and serve reviews per country, and Apple caps how deep its public feed goes — often a few hundred recent reviews per country. The millions-of-reviews figure on the listing is a lifetime global total. To approach it, loop over many countries and combine the results.
Can I get the historical star rating over time?
Not directly — neither store exposes a rating timeline. Reconstruct one yourself by bucketing the dated individual reviews you scrape by month or by app version. The single aggregate star number is current-only.
Are the Apple and Google review fields the same?
No. Apple has title + review text, a rating, an updated date and a version; Google Play has no title, exposes thumbsUp and a developer replyContent, and calls the rating score. Map both onto one common shape before comparing — see the table above.
Disclosure: links to Apify on this page are affiliate links, marked rel="sponsored". If you create a paid account through them we may earn a commission at no extra cost to you. We recommend Apify because we build and ship Actors on it ourselves, including the App Store Scraper linked above.