App Store Reviews Scraper & App Search API avatar

App Store Reviews Scraper & App Search API

Pricing

from $0.10 / 1,000 reviews

Go to Apify Store
App Store Reviews Scraper & App Search API

App Store Reviews Scraper & App Search API

Apple App Store reviews and app search with a live Standby HTTP API, so an AI agent can pull reviews mid-task with no cold start. Clean, LLM-ready JSON: rating, title, text, app version, helpful votes, date. Any storefront, no tokens to rotate. No start fee, pay only for results.

Pricing

from $0.10 / 1,000 reviews

Rating

0.0

(0)

Developer

Omar Nagy

Omar Nagy

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

9 days ago

Last modified

Share

Pull Apple App Store reviews and search the App Store at speed, with clean, LLM-ready JSON. Built for AI agents, review-monitoring pipelines, and product teams who need real user feedback in a structured shape.

Two things make this one different: it runs in Standby mode, so an agent can call a live HTTP endpoint mid-task with no cold start, and it reads Apple's own public feeds, so there is no token to rotate, nothing to unblock, and no proxy bill.

What you get

  • Reviews by app: star rating, review title, review text, app version, helpful votes, timestamp, and a permalink.
  • App search: find an app's numeric App Store ID, plus developer, average rating, rating count, price, genre, and icon.
  • Any storefront: country selects the store, and reviews differ per store, so us, gb, de and eg each return their own.
  • Standby HTTP API: a persistent endpoint your agent or app can hit directly.
  • MCP ready: exposed as a typed tool through Apify's MCP server via the input schema.
  • No dead columns: every field in the output is a field Apple actually serves. Measured on 5 September 2026: 100 of 100 reviews carried a title.

Use cases

  • Watch what users say after each iOS release, and catch a crash wave before the support queue fills up.
  • Compare the same app across storefronts, which is the fastest read on a localisation problem.
  • Feed competitor reviews into an LLM for feature-gap and pain-point analysis.
  • Give an AI agent a live tool that answers "what are people complaining about in this app right now".
  • Collect training or RAG data from real, public product feedback.

Modes

ModeYou give itYou get back
searchquery (app name or keyword)matching apps with their numeric App Store IDs
reviewsappIds (numeric IDs)reviews, paginated up to maxItems

Start with search to get an ID, then run reviews on it. reviews and search are the only two accepted modes, lowercase and exact.

Input

Find an app:

{
"mode": "search",
"query": "notion",
"country": "us",
"maxItems": 5
}

Pull its reviews:

{
"mode": "reviews",
"appIds": ["310633997"],
"country": "us",
"maxItems": 100,
"sortBy": "mostRecent"
}

Compare three apps in one run. maxItems is the budget for the whole run and is split evenly, so this returns 30 reviews of each, not 90 of the first one:

{
"mode": "reviews",
"appIds": ["324684580", "544007664", "310633997"],
"country": "us",
"maxItems": 90
}
FieldTypeDefaultNotes
modereviews or searchreviewsrequired. Any other value is rejected before anything is fetched.
appIdsarray of stringsnumeric App Store IDs, for example 310633997. Required when mode is reviews. Ignored in search.
querystringapp name or keyword. Required when mode is search. Ignored in reviews.
country2-letter codeusApp Store storefront
maxItemsinteger 1 to 5000100budget for the whole run, split evenly across appIds. 100 across 3 apps is 34 / 33 / 33.
maxItemsPerAppinteger 1 to 5000optional. When set, every app gets exactly this many and the even split is ignored, so 3 apps at 50 return up to 150 rows.
sortBymostRecent, mostHelpfulmostRecentreview order, reviews mode only

A run that asks for reviews without appIds, or search without query, fails immediately with a clear input error and returns nothing, so a misconfigured run costs you nothing.

Output

Real output from runs on 5 September 2026. Larger samples of both are in the examples/ folder of the source.

App search:

{
"type": "app",
"appId": 1232780281,
"bundleId": "notion.id",
"name": "Notion: Notes, Tasks, AI",
"developer": "Notion Labs, Incorporated",
"rating": 4.77668,
"ratingCount": 89975,
"price": "Free",
"genre": "Productivity",
"url": "https://apps.apple.com/us/app/notion-notes-tasks-ai/id1232780281?uo=4",
"icon": "https://is1-ssl.mzstatic.com/image/thumb/Purple221/v4/2e/aa/40/2eaa406d-99e0-e722-530a-ce20259f3834/AppIconProd-0-0-1x_U007epad-0-0-0-1-0-0-P3-85-220.png/100x100bb.jpg"
}

A review:

{
"type": "review",
"appId": "310633997",
"country": "us",
"reviewId": "14505487796",
"author": "Barirah Ibrahim",
"rating": 1,
"title": "Terrible",
"text": "Keeps of restricting my account for no reason, usually I get my account back after a few hours but this time it's been 5 days. I still can't login!!!",
"version": "26.34.72",
"votesHelpful": 0,
"votesTotal": 0,
"updatedAt": "2026-09-03T05:29:13-07:00",
"url": "https://itunes.apple.com/us/reviews/id1964520100"
}

Example run

Input: the two blocks above. Output on 5 September 2026: 100 reviews for 310633997 in about 1 second, and 5 apps for the notion search. Every one of the 100 reviews had a non-empty title and text.

Use it from an agent (Standby)

Standby keeps the Actor warm and answers over plain HTTP, so there is no per-call container start.

GET {standbyUrl}/search?query=notion&country=us&maxItems=5
GET {standbyUrl}/reviews?appId=310633997&country=us&maxItems=50&sortBy=mostRecent

Every successful response is:

{
"ok": true,
"count": 90,
"perApp": [
{ "appId": "324684580", "requested": 30, "fetched": 30, "charged": 30, "error": null },
{ "appId": "544007664", "requested": 30, "fetched": 30, "charged": 30, "error": null },
{ "appId": "310633997", "requested": 30, "fetched": 30, "charged": 30, "error": null }
],
"items": [ ... ],
"tookMs": 2410
}

The numbers above show the shape of a three-app call at maxItems: 90, not a recording of one particular request.

perApp is the run's own accounting: what each app was allotted, what it returned, and what it was billed. An app id that cannot be read gets an error string and charged: 0 while the rest of the call keeps its full budget, so one bad id does not fail the request.

GET {standbyUrl}/ returns a small service document with the modes and the running build number.

appId (singular) is accepted as a convenience alongside a comma-separated appIds.

Errors are typed, so an agent knows whether to retry

StatusWhenBody
404the path is not /reviews or /search, for example /foobar, /REVIEWS, /v1/reviews{ "ok": false, "error": "...", "statusCode": 404, "modes": ["reviews","search"] }
400the path is valid but the parameters are not, for example /reviews with no appIdsame shape, statusCode: 400
500an upstream failuresame shape

404 and 400 mean "fix the call", not "try again". Neither fetches any data, so neither returns anything billable.

Good to know

  • App IDs are numeric, for example 310633997 for WhatsApp Messenger. Get them from mode: "search", or read them off the end of an App Store URL.
  • Reviews are per storefront. The same app returns a different set in us and in de. There is no global feed.
  • Apple's paging has holes, and this Actor reads through them. The feed serves up to 10 pages of about 50 reviews, but an individual page can come back empty while later pages are full, and which pages are empty moves over minutes. One 10-page sweep of 389801252 on 6 September 2026 read [0, 50, 50, 50, 50, 50, 50, 0, 0, 50], and re-reading an empty page URL five times a second apart returned 0 every time, so an in-run retry buys nothing. This Actor therefore reads every one of the 10 pages until your budget is full: a run of empty pages, however long, never ends the pull early. It can still return fewer rows than the app really has, if Apple serves those pages empty for the whole run. Results are de-duplicated by review ID.
  • The practical ceiling is roughly 500 reviews per app and storefront, which is what Apple exposes. Ask for more across several storefronts if you need more.
  • maxItems is split evenly across appIds. Three apps at maxItems: 90 return 30 each, and an app that runs out early leaves its remainder unspent rather than handing it to the next app, so no app can spend another app's budget. Set maxItemsPerApp when you want a fixed number each regardless of how many apps you list. (Until 6 September 2026 the first app in the list took the whole budget and the rest returned nothing. That is fixed.)
  • Per-app accounting is in the run. Every batch run writes a summary to the key-value store as OUTPUT, including a mode: search run where the per-app list is empty, and logs one [app] <id> requested=N fetched=N charged=N line per app. Standby answers over HTTP and does not write to the key-value store: it returns the same breakdown as perApp in the response body instead.
  • Reviews are public data published by users on the App Store. Respect Apple's terms and any applicable privacy law in how you store and use it.

Parity with the Google Play Actor

There is a sibling Actor, Google Play Reviews Scraper & App Search API, with the same two modes, the same Standby routes, the same error shapes and the same pay-per-event model. Input is the same except for two fields, and the review record maps field for field with five differences. Every difference below is a difference in what the two stores publish, not a difference in style.

Input:

FieldApp StoreGoogle Play
mode, appIds, appId, query, country, maxItems, maxItemsPerAppsamesame
review ordersortBy: mostRecent, mostHelpfulsort: newest, rating, helpfulness
review languagenot accepted, Apple serves per storefront onlylang

Review output:

What it meansApp StoreGoogle Play
record kindtypetype
app identifierappId (numeric, 310633997)appId (package name, com.whatsapp)
storefrontcountrycountry
review idreviewIdreviewId
author display nameauthorauthor
stars, 1 to 5ratingrating
review bodytexttext
app versionversionversion
permalinkurlurl
when it was postedupdatedAtdate
review languagenot servedlang
helpfulnessvotesHelpful and votesTotalthumbsUp
headlinetitlenot served
developer replynot servedreplyText, replyDate

The five differences, each measured rather than assumed:

  1. Timestamp name. Apple's customer-reviews feed names its only time field updated, so this Actor exposes updatedAt. Google Play carries a review date, exposed there as date.
  2. Language. A live Apple feed entry carries exactly these keys: author, content, id, im:contentType, im:rating, im:version, im:voteCount, im:voteSum, link, title, updated (read 6 September 2026, storefront us, app 324684580, 50 entries). There is no language key, so there is nothing to expose.
  3. Helpfulness. Apple gives two numbers, a sum and a count, exposed as votesHelpful and votesTotal. Google Play gives one, thumbsUp.
  4. Headline. Apple serves a review title. Google Play no longer does: zero of 1,200 reviews across 8 apps carried one on 5 September 2026, so that field is absent there.
  5. Developer reply. Apple's feed has no reply key at all (see the key list in point 2). Google Play serves one and it is common there (111 of 150 reviews on Adobe Scan, measured 5 September 2026).

One behavioural difference worth knowing when you compare depth: Apple serves up to 10 fixed pages and an individual page can come back empty while later pages are full, which this Actor skips rather than treating as the end. Google Play pages with a continuation token until it runs out.

Pricing

You pay for results, not for time. There is no start fee, and nothing is charged for a run that returns nothing.

  • review: one App Store review row returned, in batch mode or through Standby.
  • app: one app record returned by a search.

A 1,000-review pull is charged as 1,000 review events. Finding an app costs a handful of app events. Current rates are on the Pricing tab of this page.

FAQ

How do I find an app's ID? Run mode: "search" with the app name. The appId in the output is the numeric ID.

Can I get every review an app ever received? No. Apple exposes a recent window per storefront, around 500 reviews. Pull the same app from several storefronts for a wider picture, or run it on a schedule and accumulate.

Does it need a proxy? No. It reads Apple's public feeds directly.

Can I run it on a schedule? Yes. Use Apify's scheduler, or call the Standby endpoint from your own job.

Do you support Google Play too? Yes, in a separate Actor in the same series.


Built by Omar Nagy. Part of an agent-native data-tool series on Apify.