Ctrio Lab · Updated 2026-10-14
App Store reviews API: get iOS app reviews as JSON
Apple has no public reviews API for other people's apps, but the App Store still serves a public customer reviews feed. It returns the most recent reviews of any app as JSON, without a key. The catch: the feed often returns an empty page, and simple scripts then report zero reviews.
https://itunes.apple.com/us/rss/customerreviews/page=1/id=324684580/sortby=mostrecent/json (replace us with the country and the number with the app ID from the App Store URL). Each page has up to 50 reviews in feed.entry, and there are at most 10 pages. If a page has no entry, request the same page with the parts of the URL in a different order: Apple caches each spelling separately, and another spelling often has the reviews.Step by step
- Get the app ID. It is the number after
idin the App Store URL, for exampleapps.apple.com/us/app/spotify-music-and-podcasts/id324684580. If you only have a bundle ID, the official iTunes Lookup API returns the ID:https://itunes.apple.com/lookup?bundleId=com.burbn.instagram. - Pick the country. Reviews belong to one storefront, so
us,gbandjpreturn different reviews. There is no "all countries" option; you need one request per country. - Read pages 1 to 10. Use
sortby=mostrecentfor the newest reviews orsortby=mosthelpful. Page 11 and later return an error or nothing. - Read the fields. Each entry has
id,title,content(the review text),im:rating(1 to 5),im:version(the app version the reviewer used),author.name,updated(the date) andim:voteCount. Every value is a string insidelabel. - When a page is empty, try the other spellings. The three parts
page=,id=andsortby=can come in any order,customerreviewscan be writtencustomerReviews, andsortby=mostrecentcan be writtensortBy=mostRecent. That gives 24 URLs for the same page.
Copy and paste script (Node.js 18+)
// node appstore-reviews.mjs 324684580 us > reviews.json
const [id = '324684580', country = 'us'] = process.argv.slice(2);
const perms = (a) => a.length <= 1 ? [a] : a.flatMap((x, i) => perms([...a.slice(0, i), ...a.slice(i + 1)]).map(p => [x, ...p]));
const spellings = (page) => ['sortby=mostrecent', 'sortBy=mostRecent'].flatMap(sort =>
perms([`page=${page}`, `id=${id}`, sort]).flatMap(p =>
['customerreviews', 'customerReviews'].map(base => `https://itunes.apple.com/${country}/rss/${base}/${p.join('/')}/json`)));
const reviews = new Map();
for (let page = 1; page <= 10; page++) {
for (const url of spellings(page)) {
const res = await fetch(url);
if (res.status !== 200) continue;
const entries = [].concat((await res.json()).feed?.entry ?? []);
if (!entries.length) continue; // empty cached copy: try the next spelling
for (const e of entries) reviews.set(e.id.label, {
id: e.id.label, date: e.updated.label, rating: Number(e['im:rating'].label),
version: e['im:version'].label, author: e.author.name.label,
title: e.title.label, text: e.content.label, votes: Number(e['im:voteCount'].label),
});
break;
}
}
console.log(JSON.stringify([...reviews.values()], null, 2));
We ran this script on 2026-10-14 for five popular US apps. It takes under a minute per app, because it may try up to 24 URLs for each of the 10 pages.
How often the feed is empty (2026-10-14)
| App (US store) | Usual URL only, pages 1 to 10 | All 24 spellings, one pass |
|---|---|---|
| 0 reviews | 250 reviews | |
| Spotify | 100 reviews | 250 reviews |
| Duolingo | 0 reviews | 100 reviews |
| Netflix | 0 reviews | 50 reviews |
| ChatGPT | 0 reviews | 50 reviews |
The empty pages move around. When we read the same app again a few minutes later, different pages were empty, and pages that were empty before had reviews. So no single pass reliably returns all 500. If you need every recent review, run the script on a schedule and keep the review IDs you have already seen.
Common problems
- Zero reviews for a popular app: this is the cached empty copy described above, not a block. Try the other spellings or try again later.
- Only 500 reviews: the feed never goes past 10 pages. For older reviews there is no public source; the App Store Connect API has full history only for apps you own.
- One country at a time: loop over country codes; each storefront has its own reviews.
- Strings everywhere: ratings and vote counts come as strings such as
"5". Convert them before you average. - The marketing RSS generator: Apple's RSS builder for top charts and new apps does not include reviews. Use the customer reviews feed.
App Store reviews on a schedule, as a dataset
We also run the Apple App Store Scraper on Apify, a paid hosted version of this method. You paste app IDs, App Store URLs or bundle IDs and a list of countries, and it returns one row per review with rating, title, text, version, author and date, plus app details and keyword search results if you want them. It tries the equivalent feed URLs for you, filters by date, and a new-reviews-only mode returns just the reviews added since the last run, which suits a daily schedule. It costs $0.08 per 1,000 results.
Open Apple App Store Scraper Hacker News Who is hiring as JSON
FAQ
Is there an official API for App Store reviews?
Only for your own apps. The App Store Connect API lists customer reviews for apps in your App Store Connect account and needs an API key. For any other app, the public customer reviews feed at itunes.apple.com returns recent reviews as JSON without a key.
How many App Store reviews can I get?
The public feed serves at most 10 pages of 50 reviews, so 500 per app, country and sort order. Older reviews are not available from the feed. In our tests on 2026-10-14 one pass returned between 50 and 250 reviews per app because some pages came back empty.
Why does the App Store reviews RSS feed return no entries?
Apple caches each spelling of the feed URL separately, and a cached copy is often empty. On 2026-10-14 the usual URL returned no reviews on any of the 10 pages for 4 of 5 popular apps, while equivalent spellings of the same URL returned reviews.
Sources: iTunes Search and Lookup API; App Store Connect API; our own requests on 2026-10-14.