Compare an App's App Store Reviews Across Countries
Read one app's App Store reviews in many countries in one run with App Store Reviews Scraper, then compare ratings and top complaints country by country.
The actor referenced in this article. Pay only for results delivered.
An app’s rating and its complaints can differ a lot from one App Store country to the next. Each country’s App Store keeps its own reviews and its own rating, so a US-only view tells you nothing about why India, Germany or Brazil feels different. Checking a dozen storefronts by hand, in several languages, is the kind of job that never gets done.
Try it live: App Store Reviews Scraper: iOS Reviews from 174 Countries. Pay per result delivered. Failed and empty results are never charged.
The App Store Reviews Scraper reads as many App Store countries as you list, or all 174, in one run. Every row says which country it came from and carries that country’s own rating, which makes a side by side comparison a short script.
What you get and who it is for
| Field | Role in the comparison |
|---|---|
country | The App Store the review was written in, upper case |
app_rating, app_ratings_count | That country’s average and number of ratings |
rating | Stars on this review, 1 to 5 |
title, text | The complaint or praise, in the language it was written in |
reviewed_at, app_version | When, and on which build |
app_id, app_name | The app, with the name that country’s store uses |
sort | Which list the review came from, including the featured fallback |
Product teams use it to find market-specific bugs, localization teams to spot translation and payment complaints, and analysts to size a competitor’s weak markets before entering them.
The input
{
"apps": ["310633997", "324684580"],
"countries": ["us", "gb", "in", "de", "br", "jp"],
"maxReviewsPerCountry": 500,
"sort": "mostRecent"
}
appstakes numeric App Store ids or App Store links; these are WhatsApp and Spotify. The country inside a link is ignored.countriesis the list of storefronts to read, as two letter codes. SetallCountriesto true instead to read all 174.maxReviewsPerCountryat 500 takes the whole most recent list Apple’s feed offers in each country. For more history, setsorttobothand raise it to 1,000.- Leave
onlyNewReviewsoff for this job. A comparison wants a full sample every time, not just what changed.
What the output looks like
Two rows, trimmed, from our run on October 7, 2026 for WhatsApp and Spotify in the US and GB. Apple’s recent feed came back empty on that run, so the actor delivered each country’s 10 featured reviews, marked featured. Reviewer names are masked and long texts cut.
[
{
"app_id": "310633997",
"app_name": "WhatsApp Messenger",
"country": "US",
"review_id": "12389964257",
"user_name": "B**************",
"rating": 3,
"title": "Requires update but won’t download",
"text": "Over the weekend, the app began showing a message that required me to update in order to keep using the app. ...",
"reviewed_at": "2025-03-06T21:36:14.000Z",
"app_rating": 4.68,
"app_ratings_count": 18723283,
"sort": "featured",
"position": 6,
"app_url": "https://apps.apple.com/us/app/id310633997"
},
{
"app_id": "310633997",
"app_name": "WhatsApp Messenger",
"country": "GB",
"review_id": "12601429956",
"user_name": "L*******",
"rating": 2,
"title": "Becoming unreliable",
"text": "The last few months every now and then it just stops working and says that I have gone against some terms, ...",
"reviewed_at": "2025-04-30T02:52:48.000Z",
"app_rating": 4.7,
"app_ratings_count": 4198565,
"sort": "featured",
"position": 3,
"app_url": "https://apps.apple.com/gb/app/id310633997"
}
]
The same run, summed up per app and country:
| App | Country | app_rating | app_ratings_count | Featured 10, average stars | Featured 10 with 1 or 2 stars |
|---|---|---|---|---|---|
| WhatsApp Messenger | US | 4.68 | 18,723,283 | 2.8 | 4 |
| WhatsApp Messenger | GB | 4.7 | 4,198,565 | 2.9 | 5 |
| Spotify | US | 4.77 | 42,454,826 | 4.5 | 0 |
| Spotify | GB | 4.74 | 6,992,827 | 3.8 | 3 |
The store averages sit within 0.03 of each other for each app, yet the reviews a visitor reads on the page differ: Spotify’s featured US reviews average 4.5 stars, its GB ones 3.8. Recent reviews split further. In our US run later that day, 41 of WhatsApp’s 100 newest reviews had 1 or 2 stars, and the keyword pass below put 9 of them under bans and login, 6 under updates and design, and 4 under spam, scams and hacking. Spotify’s 20 low-star US reviews leaned on ads: 10 matched ads and premium, 5 crashes and playback. In WhatsApp’s 20 newest GB reviews that morning, 6 had 1 or 2 stars, and 4 of those were about updates and design.
Run it in Apify Console
- Open https://apify.com/themineworks/app-store-reviews-scraper and click Try for free.
- In Apps, enter one app id or App Store link per line.
- In Countries, enter one code per line, or switch on Read every App Store country.
- Set Max reviews per app in each country to 500 and Sort to Most recent first.
- Click Start and watch the Output tab fill country by country.
- Click Export and download CSV, JSON or Excel, then pivot on
country.
Run it from Python
pip install apify-client, then:
import csv
from collections import Counter, defaultdict
from statistics import mean
from apify_client import ApifyClient
THEMES = {
"bans and login": ["bann", "ban ", "restrict", "deactivat", "log in", "login", "appeal"],
"ads and premium": [" ads", "adds", "commercial", "premium"],
"updates and design": ["update", "bubble", "layout", "design"],
"spam, scams, hacking": ["spam", "scam", "hack"],
"crashes and playback": ["crash", "freez", "lag", "restart", "shuffle", "not working"],
}
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("themineworks/app-store-reviews-scraper").call(run_input={
"apps": ["310633997", "324684580"],
"countries": ["us", "gb", "in", "de", "br", "jp"],
"maxReviewsPerCountry": 500,
"sort": "mostRecent",
})
groups = defaultdict(list)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("_type") == "info":
continue # the run summary row, never billed
groups[(item["app_id"], item["country"])].append(item)
summary = []
for (app_id, country), reviews in sorted(groups.items()):
low = [r for r in reviews if r["rating"] <= 2]
themes = Counter()
for r in low:
blob = f" {r.get('title', '')} {r.get('text', '')} ".lower()
for theme, words in THEMES.items():
if any(w in blob for w in words):
themes[theme] += 1
summary.append({
"app_id": app_id,
"app_name": reviews[0]["app_name"],
"country": country,
"store_rating": reviews[0].get("app_rating"),
"store_ratings_count": reviews[0].get("app_ratings_count"),
"reviews_read": len(reviews),
"avg_stars_read": round(mean(r["rating"] for r in reviews), 2),
"low_star_reviews": len(low),
"top_complaints": "; ".join(f"{t} ({n})" for t, n in themes.most_common(3)),
"sorts": ",".join(sorted({r["sort"] for r in reviews})),
})
with open("reviews_by_country.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=list(summary[0]))
writer.writeheader()
writer.writerows(summary)
for row in summary:
print(row["app_name"], row["country"], row["store_rating"],
row["avg_stars_read"], row["low_star_reviews"], row["top_complaints"])
The result is one row per app and country with the store’s own rating, the average of the reviews read, the low-star count and the three most common complaint themes. The sorts column shows featured wherever the fallback kicked in, so you never compare a featured sample against a recent one without noticing. The theme lists are a starting point: replace them with the problems your app actually has. For something stronger than keyword matching, scoring the text with a sentiment pipeline follows the same shape, with reviews in place of Reddit posts.
Repeat it every month
Country gaps move with releases and pricing changes, so a monthly snapshot is a good rhythm. In Apify Console, save the input as a task, open Schedules, create a schedule with 0 7 1 * * (07:00 on the first of each month) and pick the task. Keep onlyNewReviews off so each month is a complete sample. Apify’s Google Sheets integration can add each run to a sheet, or a webhook on a successful run can trigger your own copy of the script above.
What it costs
$0.10 per 1,000 reviews on the Bronze plan, and the same $0.10 on Silver, Gold and the higher plans, plus a flat $0.005 per run. Two apps in six countries at up to 500 reviews each is at most 6,000 reviews: $0.60 plus $0.005. Our every country test run read WhatsApp in all 174 countries at 20 reviews each and returned 3,342 reviews from 173 of them, about $0.33 plus $0.005. Countries where the app is not sold, and countries with no written reviews, cost nothing.
Limits worth knowing
- Apple’s feed holds 500 reviews per country for each sort order, about 1,000 with
both. - Small markets return little. In the every country run, a few countries had only 1 to 7 reviews, so keep the review count next to every average.
app_ratingcovers every star rating in the country, and the reviews are only the latest written ones. Compare countries on the same measure.- Keyword themes only catch the language they are written in. For jp, de or br, add local terms or translate the text before matching.
- When Apple’s feed stays empty, you get the 10 featured reviews instead: older, longer and without
app_versionor votes.
Related
- Monitor New App Store Reviews for Your App Every Day, the companion guide for daily alerts
- Mining 1-star reviews to validate an idea, a method for turning complaints into decisions
- Amazon Reviews Scraper in Python, the same review analysis for physical products
- App Store Reviews Scraper on The Mine Works
Explore the scraper referenced in this article: inputs, outputs, and pricing, then run it on Apify.
Frequently asked questions
How many countries can one run cover? +
All 174 App Store countries. Switch on allCountries instead of listing codes; countries where the app is not sold are skipped and never charged.
Why is the store rating so much higher than the average of the reviews I collected? +
app_rating is the average of every star rating in that country, 18,723,283 of them for WhatsApp in the US in our run, while the reviews you collect are the latest few hundred written ones. Compare countries on the same measure, not one against the other.
What are rows with sort set to featured? +
When Apple's review feed stays empty for a country, the actor delivers the 10 reviews featured on that country's App Store page instead. They are older, longer reviews from the top of the most helpful list and have no app_version or vote counts.
Is the app name the same in every country? +
Not always. app_name is the name the App Store uses in that country, so group and join on app_id, which stays the same everywhere.
Monitor New App Store Reviews for Your App Every Day
Get each day's new App Store reviews of your app in several countries with App Store Reviews Scraper, plus an alert for every 1 and 2 star review.
Trustpilot Business Search: Discover Companies by Category with TrustScore Data
Search Trustpilot by category or keyword in Python to build company lists with TrustScore, review count and verification status, no login required.
Amazon Reviews Scraper: Collect Customer Ratings and Sentiment Without the SP-API
How to pull Amazon customer reviews at scale by ASIN: star rating, verified badge, full review text, helpful votes and images, across 8 marketplaces.
Google Maps Reviews Scraper: Extract Ratings, Text and Owner Replies Without an API
How to pull Google Maps place reviews at scale: star ratings, full text, reviewer details and owner responses, for any hotel, restaurant, shop or attraction.