App Store Reviews & App Data $0.05/1K - 59 Storefronts
Pricing
$0.05 / 1,000 result rows
App Store Reviews & App Data $0.05/1K - 59 Storefronts
$0.05/1K | Apple caps one storefront at 500 reviews per sort order. This opens both sort windows and every storefront you list: 937 unique reviews per storefront instead of 500, measured. App store data, ios app reviews, app ratings, app store keywords, app store charts.
Pricing
$0.05 / 1,000 result rows
Rating
0.0
(0)
Developer
Snow Leo Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Apple App Store Reviews & App Data — every storefront, not just the US
Apple hands out 500 reviews per storefront per sort order and then stops. Page eleven of the review feed answers HTTP 400. That is the wall every App Store scraper hits, and almost every one of them hits it in a single country and calls it a day.
This Actor walks around the wall twice over:
- it opens both Apple sort windows, which are two different 500-review slices that barely overlap — measured on one app: 500 + 500 gave 937 unique reviews, only 63 were shared;
- it repeats that on every storefront you list. Apple runs 59 storefronts in this Actor's list, each with its own 500-review window and its own reviewers.
On top of the reviews it returns the full store card — price, version, rating, rating count, genres, size, languages, release notes — and it returns that card per storefront, because Apple sells the same app at different prices to different countries. Measured on Notion on 12 September 2026: 90,067 ratings and USD in the US storefront, 50,062 ratings and JPY in the Japanese one.
No API key. No proxy. No headless browser. Four public Apple endpoints, plain
HTTP, and every number on this page is reproducible with curl.
What exactly do you get back?
Two kinds of rows in one dataset, told apart by record_type:
app— one row per app (per storefront, if you ask for that), 60 fields covering identity, pricing, ratings, genres, technical requirements, artwork and where the app was found;review— one row per customer review: stars, headline, body, the app version it was written against, the date, the helpfulness votes and which Apple sort window it came out of.
Both carry app_id, app_name, bundle_id, developer and country, so
joining reviews back onto apps is one key in any spreadsheet or warehouse.
Five ready-made table views ship with the dataset: store cards, customer reviews, what changed since last run, charts and keywords, and all columns.
How do I tell the Actor which apps to look at?
Four ways, and they combine in a single run:
- Paste anything that identifies an app.
appIdsswallows App Store page URLs, bare numeric ids and reverse-domain bundle ids in the same list:https://apps.apple.com/us/app/notion/id1232780281,1232780281andnotion.idall resolve. A country code inside a URL is respected. - Keyword search.
searchTermsruns Apple's catalogue search on your primary storefront. - A whole developer.
developerIdstakes numeric Apple developer ids and collects every app they publish. - Charts.
chartswalks Top Free, Top Paid, Top Grossing, New Apps, New Free Apps and New Paid Apps, optionally narrowed to any of the 25 App Store genres.
Why do the charts matter more than the keyword search?
Because Apple's keyword search is a dead end, and it does not say so.
Measured on 12 September 2026: limit=500 on the search endpoint returns 194
results. limit=200 returns 194. And the offset parameter is accepted,
returns HTTP 200, and is silently ignored — a request with offset=200
comes back with exactly the same first trackIds as offset=0. There is no
page two. Apple stops keyword search at about 200 results per term, full stop.
The charts are the way past it. Each chart is capped at 100 positions per
genre, but there are 25 genres and six chart feeds, so one storefront yields
thousands of distinct apps instead of 200. Every app collected this way carries
chart and chart_rank, in the order Apple ranked it.
When a keyword search comes back full, the run log says so instead of letting you believe the store only has 194 apps for your term.
How far into the reviews can this actually get?
Exactly as far as Apple allows, and the Actor tells you the number in the data.
The review feed is ten pages of fifty. Page eleven answers HTTP 400. So one storefront, one sort order, is 500 reviews per storefront — for an app with 90,067 ratings.
Two things multiply that:
- Sort windows.
mostRecentandmostHelpfulare not the same 500 reviews ranked differently — they are different slices. Measured: 500 from each, 63 in common, 937 unique. Both windows are on by default; each row records which one it came from inreview_sort_window. - Storefronts. Every Apple storefront keeps its own reviews. Measured on five storefronts (us, gb, de, jp, br), reading only the first page of each: 250 unique reviews, against 50 from the US alone. All 59 storefronts on the list were checked live: every one returned both a store card and reviews.
Every app row carries reviews_reachable — how many reviews of that app this
particular run configuration can actually reach, capped by the app's own rating
count. It is there so you never have to guess whether a short review list means
a quiet app or a ceiling.
What is the trap in Apple's lookup endpoint?
This one is worth knowing even if you never use this Actor.
itunes.apple.com/lookup accepts a comma-separated list of app ids. Ask for
200 ids, get 200 back. Ask for 215, and it truncates at 210 — HTTP 200, no
error, no warning, no field saying anything was dropped. Measured on 230
verified-alive ids: 210 came back, 20 vanished silently.
Any scraper that batches 250 ids per call loses forty apps on a green run and nobody notices. This Actor batches at 200, below the cut, and the live test suite re-measures the cut on every run so that a change on Apple's side shows up here before it shows up in your data.
Does it charge me twice for the same review?
Not if you turn on onlyNew.
The Actor keeps a named key-value store that survives between runs and remembers what it has already delivered. On the next run:
- a review it has handed you before is skipped entirely;
- an app row comes back only when something that matters moved — version, price, rating, rating count or release notes. A reworded description does not count as a change, because Apple edits store text constantly and everything would look "updated" every single day;
- every row carries
change_type:NEW,UPDATEDorUNCHANGED.
Turn on emitUnchanged if you want the unchanged rows back anyway, tagged.
Rows are marked as delivered after they reach the dataset, never before. A container that dies mid-push therefore loses nothing permanently: the next run delivers the same rows again rather than skipping them forever. That ordering is covered by a test that kills the push on purpose.
What happens when a run returns nothing?
It tells you which of the five possible reasons it was, in the REPORT record
and as a warning in the log:
nothing-changed— incremental mode did its job, everything had already been delivered, nothing was charged;filtered-out— rows were collected and your filters removed all of them; the report lists how many each filter took;source-returned-nothing— Apple has no card for those ids on that storefront, which usually means the app was pulled or is not sold there;no-input— no ids, no keywords, no developers, no chart;charge-limit-reached— the spending limit on the run was already used up.
A silent empty dataset is the worst failure a scraper can have, because the run looks green and you are left guessing whether the data or the tool is at fault. There is no path through this Actor that produces one.
How do the filters behave when a field is empty?
They let the row through. Always.
Missing data is not the same as a mismatch, and a filter that confuses the two
quietly deletes your results. An app that Apple publishes without a rating is
not "rated below four stars" — it is unrated, and minAppRating keeps it. A
review with stars but no text is not "missing your keyword" — there is nothing
to match, and keywords keeps it.
Filters also know which kind of row they belong to. minReviewRating never
removes an app row. genres never removes a review — instead it decides which
apps get their reviews fetched at all, which is both cheaper and what you
actually meant.
And if you set a review filter with includeReviews off, the Actor switches
reviews back on and says so in the log, rather than running a condition that
can never match.
Which fields come back?
Identity and discovery: record_type, app_id, bundle_id, app_name,
app_name_censored, developer, developer_id, developer_url,
seller_name, seller_url, app_url, country, chart, chart_rank,
search_term, scraped_at, change_type.
Store card: description, release_notes, version,
current_version_released_at, released_at, app_age_days,
days_since_update, price, currency, formatted_price, is_free,
rating, rating_count, rating_current_version,
rating_count_current_version, reviews_reachable, content_rating,
advisories, primary_genre, genres, genre_ids, kind.
Technical: min_os_version, file_size_bytes, file_size_mb,
languages, supported_devices, features, is_game_center_enabled,
icon_url, screenshot_urls, ipad_screenshot_urls,
appletv_screenshot_urls.
Review: review_id, review_rating, review_title, review_text,
review_author, review_app_version, review_updated_at,
review_vote_sum, review_vote_count, review_sort_window.
Screenshot lists and the supported-device list are long and are left out unless
you turn on includeScreenshots. Numbers are numbers: an empty rating is
null, never an empty string, so a typed consumer such as pandas, BigQuery or
Excel does not choke on the column.
How much of this can I switch off?
compactOutput cuts the row down to who, where, what was said and what it
costs. excludeEmptyFields drops empty columns from every row, which matters
when an AI agent is paying per token. Both are safe with every filter: filters
run on the complete row before any of this trimming happens, and a test asserts
that a filter plus both compacting switches still returns rows. That exact
combination — a filter reading a field that a lighter output mode had already
removed — is a known way to turn a green run into an empty dataset.
What does this Actor NOT do?
Stated plainly, because the alternative is you finding out after paying:
- No star histogram. Apple's public endpoints give the average rating and the rating count, not the 1-to-5 breakdown. Nobody scraping these endpoints has it.
- No download or revenue estimates. Those are modelled numbers from paid data vendors; this Actor only returns what Apple publishes.
- No in-app purchase list and no keyword rank tracking.
- No custom JavaScript map function. Two competing Actors expose one. Here you get field selection, compacting and empty-field dropping instead, which covers the common cases but not arbitrary transforms.
- The review date cut-off is relative, not absolute.
reviewsWithinDayscounts back from now, which is what a scheduled monitor wants; there is no "stop at 3 March 2026" input. - No Google Play. This is the Apple App Store only.
- Review author pseudonyms are returned; reviewer profile links are not. The nickname is published by Apple alongside the review and without it one review cannot be told from the next. The link to a reviewer's personal page serves no analytical purpose and is deliberately left out.
- Reviews are capped by Apple, not by us. 500 per storefront per sort order. This Actor multiplies the windows; it cannot remove the cap.
How do I reproduce the numbers on this page?
Every one of them, with plain curl:
# 500 reviews per storefront: page 10 works, page 11 is HTTP 400curl -s -o /dev/null -w '%{http_code}\n' \'https://itunes.apple.com/us/rss/customerreviews/page=10/id=1232780281/sortby=mostrecent/json'curl -s -o /dev/null -w '%{http_code}\n' \'https://itunes.apple.com/us/rss/customerreviews/page=11/id=1232780281/sortby=mostrecent/json'# keyword search stops at about 200 and ignores offsetcurl -s 'https://itunes.apple.com/search?term=fitness&entity=software&country=us&limit=500' \| python3 -c 'import json,sys; print(json.load(sys.stdin)["resultCount"])'# the same app, two storefronts, two different rating countsfor c in us jp; do curl -s "https://itunes.apple.com/lookup?id=1232780281&country=$c" \| python3 -c 'import json,sys; r=json.load(sys.stdin)["results"][0]; print(r["currency"], r["userRatingCount"])'; done
The Actor's own test suite re-measures all of it.
python3 tests/run_all.py --liveWhat does it cost to run?
Pay per result: $0.05 per 1,000 rows, an app store card and a review costing the same. No charge for starting a run, no monthly rent.
For scale, measured across 162 priced Actors in this niche on 12 September 2026: the median is $1.00 per 1,000 results and the quartiles are $0.20 and $4.00. The most-used competitor charges $0.10 per 1,000.
The run report tells you exactly what was collected, what your filters removed before billing, and how many duplicate reviews the two sort windows shared and therefore did not bill you for. Rows with no usable content — a review with a rating but no text and no headline — are dropped before the dataset, so you are not charged for them either.
Compute is modest on purpose: plain HTTP, no browser, 1024 MB by default.
FAQ
Which storefronts can I use?
Two-letter country codes; 59 Apple storefronts are supported. The first entry
in countries is the primary storefront — searches, charts and app cards come
from it. Reviews come from all of them.
Why is the first storefront special?
Because chart positions and search results are storefront-specific, and running
every keyword against every storefront would multiply your bill without adding
much. If you do want the app card from each country — different price, different
rating count, different currency — turn on appsFromEveryCountry.
Can I get more than 500 reviews for one app in one country? Yes, up to about 937, by keeping both sort windows on. Beyond that, only by adding storefronts. Apple does not offer a deeper feed at any price.
Does it work for iPad and Mac apps?
Yes. platform switches keyword search and developer lookups between iPhone,
iPad and Mac catalogues. Mac apps often have no ratings at all, and their rows
come back with rating as null rather than zero.
What is reviews_reachable for?
It answers "did I get everything?" without arithmetic. It is the smaller of the
app's rating count and what your storefront and sort-window settings allow.
How do I run this as a daily monitor?
Schedule it with onlyNew turned on. The first run pays for the backlog; every
run after that pays only for reviews posted since, and for app cards whose
version, price or rating actually moved. A run where nothing changed returns
zero rows, says nothing-changed in the report, and bills nothing beyond
compute.
Why are some rows missing screenshot columns?
They are off by default because they are long. Turn on includeScreenshots.
An app I asked for is missing. Why? It is either withdrawn or not sold on that storefront. Apple answers HTTP 200 with an empty result in both cases; the run report counts it and the empty reason names it.
Is any of this against Apple's terms? These are Apple's own public, unauthenticated endpoints — the same ones that power the store's own web pages and countless app-marketing dashboards. No login is used, no rate limit is circumvented, and no personal account data is touched.