App Store Reviews Scraper avatar

App Store Reviews Scraper

Pricing

$0.08 / 1,000 reviews

Go to Apify Store
App Store Reviews Scraper

App Store Reviews Scraper

Scrape Apple App Store reviews to JSON by app ID or URL. No Apple account. One record per review with rating, title, text, author, developer reply, and date. Sort by recent, helpful, favorable, or critical. Empty apps cost $0. $0.08 per 1,000 reviews.

Pricing

$0.08 / 1,000 reviews

Rating

0.0

(0)

Developer

apihq dev

apihq dev

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Share

Export Apple App Store reviews and developer replies as clean JSON from an app id or apps.apple.com URL. No Apple account, no browser. Sort by recent, helpful, favorable, or critical, and pay only for reviews delivered at $0.08 per 1,000.

The contract is simple: an app with no reviews never fails your run, and you only pay for reviews delivered. Scrape a batch of apps and get one row per review with the rating, title, text, author, developer reply, and date. There is no per-run start fee, so apps that return nothing cost $0.

See one run

Input:

{
"appIds": ["324684580", "9999999999"],
"sort": "critical",
"maxReviews": 3,
"country": "us"
}

What comes back:

  • 3 success: true review rows from Spotify (324684580), most critical first, billed
  • 1 success: false row, code: NO_REVIEWS, for the nonexistent app 9999999999, not billed
  • Run status: SUCCEEDED (one bad app never fails the batch)
  • Charged: 3 reviews = $0.00024

appId alone works too. Every knob above is optional: sort (recent, helpful, favorable, critical), maxReviews, and country (the App Store storefront, default us). Good input returns billed rows, a bad app returns a free error row in the same dataset, and the run still succeeds so one bad app never costs you a batch.

Why this Actor

  • Developer replies included. Each review carries the developer's public response (reply_text) and when it was last updated.
  • Sort every app four ways. Order each app's reviews by recent (newest first), helpful (Apple's most-helpful ranking), favorable (highest ratings first), or critical (lowest first), so you pull the exact slice your analysis needs.
  • You pay only for reviews. Billing fires on an explicit per-review event, not on dataset writes, so an app that returns nothing sits in your dataset for free. There is no per-run start fee, so an empty run costs zero.
  • No Apple account. It reads public App Store reviews directly by app id, so there is nothing to log into and no key to provision.

Best for

Data and AI workflows that turn app reviews into text: sentiment and brand-safety analysis, competitor and release-quality monitoring, and building review datasets for LLM pipelines. The failure-free billing matters most when the extraction runs unattended inside a larger pipeline, where one bad app should never take down the batch. It works fine for one-off manual pulls too.

Input example

A single app, most critical reviews first:

{
"appId": "324684580",
"maxReviews": 500,
"sort": "critical"
}

A batch of apps, one country:

{
"appIds": [
"324684580",
"https://apps.apple.com/us/app/instagram/id389801252",
"389801252"
],
"maxReviews": 1000,
"sort": "recent",
"country": "us"
}

appId and appIds are merged and de-duplicated (a numeric id and its apps.apple.com URL count as the same app). Up to 50 unique apps run per job. sort and country apply to every app in the run.

maxReviews is a maximum target per app, not a guaranteed count. If fewer reviews are available, the app finishes normally with no diagnostic row. If a rate limit, outage, timeout, or service-capacity condition stops extraction early, the reviews already delivered are preserved, one free success: false diagnostic row is added, and the run finishes SUCCEEDED. You are charged only for reviews delivered. The Reliability section below shows the full contract.

Output example

One record per review. The app's id is copied onto every row so each row stands alone:

{
"success": true,
"review_id": "14282988831",
"app_id": "324684580",
"user_name": "Neightfrog",
"rating": 1,
"title": "App has become unreliable",
"text": "The app has become unreliable and will stop playing randomly.",
"posted_at": "2026-07-09T18:01:47Z",
"is_edited": true,
"reply_text": "Hello. We appreciate the review. We'd recommend a clean reinstall.",
"reply_updated_at": "2026-07-08T18:15:11Z",
"url": "https://apps.apple.com/us/app/id324684580?see-all=reviews"
}

An app that cannot be found lands in the same dataset and is not charged:

{
"success": false,
"app_id": "9999999999",
"code": "NO_REVIEWS",
"error": "Apple App Store returned no reviews for app: 9999999999",
"request_id": "req_911f37d2e55644ff9d9e4a3f",
"status_code": 404
}

Split hits from misses on the success field. Quote request_id in any support issue and we can trace the exact request.

What you get

Every review is one record with success: true:

FieldTypeWhat it is
successbooleantrue for a review (billed). false for a diagnostic row (never billed): a single bad or empty app, or a global row marking that the walk stopped early.
review_idstringApple's unique review id.
app_idstringThe numeric App Store app id the review belongs to.
user_namestringReviewer display name.
ratingintegerStar rating, 1 to 5.
titlestringThe review title. May be empty.
textstringThe review body. May be empty.
posted_atstringISO 8601 UTC timestamp the review was posted.
is_editedbooleanTrue when the reviewer edited the review after first posting.
reply_textstringThe developer's reply body. Absent when there is no reply.
reply_updated_atstringISO 8601 UTC timestamp the developer reply was last modified. Absent when there is no reply.
urlstringApp Store listing URL.

Service-generated success: false rows carry app_id, a machine-readable code, a human-readable error, the service request_id, and the HTTP status_code, and are never charged. (The one exception is the NO_INPUT row when a run has no usable app id, which carries only code and error.) A code of NO_REVIEWS or VALIDATION_FAILED marks one bad or empty app while the rest of the batch continues. The codes APP_STORE_RATE_LIMITED, APP_STORE_OVERLOAD, APP_STORE_UPSTREAM_UNAVAILABLE, APP_STORE_REVIEWS_TIMEOUT, and DEADLINE_EXCEEDED mark a global early stop: the walk halted after the reviews already delivered. The Reliability section explains what to do with each.

Pricing

Pay-per-review. One charge per review delivered: $0.00008 each, which is $0.08 per 1,000 reviews. The charge fires only after a review row lands in your dataset.

  • 1,000 delivered reviews cost $0.08.
  • A run that hits only empty or nonexistent apps costs $0.
  • There is no per-run start fee, so an empty run is genuinely free.

Platform compute is included in the per-review price, so there is no separate usage charge. Cap the maximum spend of a single run from Apify's Run Limits panel; the Actor honors the cap and stops cleanly mid-app when the budget runs out.

What this Actor does not do

Honest scope, so you know before you run it:

  • No app-version or helpful-vote fields. The review source this Actor reads does not carry the review's app version or its helpful-vote count, so those fields are not in the output. (Apple's public RSS feed exposes those two fields but is limited to about 500 reviews per country and sort.)
  • Reviews are per country. Apple serves a country-specific storefront (default us). To cover another market, run the app again with a different country. One run is one country.
  • Developer replies appear only when the developer replied. Most reviews have no reply; reply_text is simply absent on those rows, not an error.
  • Public reviews only. It returns what a signed-out visitor sees on the App Store listing. Apple exposes no per-review permalink, so url is the app's listing page.

How to use this Actor

  1. Open the Actor in the Apify Console.
  2. Set appId (single) or appIds (a list). Each accepts a numeric App Store id (for example 324684580) or an apps.apple.com URL. Up to 50 unique apps run per job.
  3. Set maxReviews to cap how many reviews to return per app, sort to recent, helpful, favorable, or critical, and optionally country for the App Store storefront.
  4. Click Start. Each review is one success: true record. Apps that cannot be listed produce one success: false record and do not stop the run. Only reviews are charged.

The Actor is also callable from the Apify API and every official integration (Make, Zapier, n8n, Slack, webhooks). The API tab in the Console has ready-to-paste JavaScript, Python, and curl snippets.

Reliability

A bad app never fails the batch. A mistyped id, a non-apps.apple.com URL, or an app with no reviews becomes a success: false record with a specific code. The run keeps going and finishes successfully.

You never pay for a miss. Billing fires on an explicit per-review charge event, not on dataset writes, so success: false records are free. There is no per-run start fee either.

Partial results stay usable. maxReviews is a maximum target, not a guaranteed count. If Apple rate-limits requests, becomes unavailable, or the extraction reaches a timeout or a service-capacity limit, the Actor stops the remaining walk instead of adding to the pressure. Reviews already delivered stay in the dataset, followed by one free success: false diagnostic row, and the run finishes SUCCEEDED. You are charged only for the reviews delivered.

{
"success": false,
"app_id": "324684580",
"code": "APP_STORE_RATE_LIMITED",
"error": "Extraction stopped early: Apple rate-limited the request (persistent 429 after retries). Reviews already delivered are preserved; remaining apps were not processed to avoid worsening the upstream condition.",
"request_id": "req_5f21c0e9a1b2483d",
"status_code": 429
}

If this row follows 200 review rows from a maxReviews: 500 request, you get 200 delivered and billed reviews, one free diagnostic row, and 300 reviews not processed. In a batch, the apps after the stop are skipped for the same reason. The early-stop codes are APP_STORE_RATE_LIMITED, APP_STORE_OVERLOAD, APP_STORE_UPSTREAM_UNAVAILABLE, APP_STORE_REVIEWS_TIMEOUT, and DEADLINE_EXCEEDED.

FAQ

Do I need an Apple account or API key?

No. The Actor reads public App Store reviews directly by app id.

How do I point it at an app?

Use the numeric App Store id (324684580) or an apps.apple.com URL (https://apps.apple.com/us/app/spotify/id324684580). Both resolve to the same app. An unrecognizable value comes back as a success: false record with code: VALIDATION_FAILED, not a rejected run.

How many reviews can I get per app?

Up to your maxReviews, subject to what Apple serves and to upstream conditions. maxReviews is a target, not a guarantee: an app with fewer reviews, or an upstream rate limit, outage, timeout, or capacity stop, can return fewer. The next question covers what an early stop looks like.

What if the Actor stops before maxReviews?

You keep everything delivered so far. If Apple rate-limits, becomes unavailable, or the run reaches a timeout or a service-capacity limit, the Actor stops the remaining walk rather than adding to the pressure. The reviews already delivered stay in the dataset and are billed, one free success: false diagnostic row records why it stopped (for example code: APP_STORE_RATE_LIMITED), and the run still finishes SUCCEEDED. In a batch, the apps after the stop are skipped. You are never charged for the diagnostic row or for reviews that were not delivered.

Can I get reviews from other countries?

Yes. Set country (for example gb, de). Apple serves a country-specific storefront, so this selects which reviews you get. One run covers one country; run the app again per market for wider coverage.

What if an app has no reviews?

It comes back as a success: false record with code: NO_REVIEWS. You are not charged.

Can I also scrape Google Play reviews?

Yes, with the sibling Actor: Google Play Reviews Scraper. Same failure-free, pay-per-review contract for the Android side.

Can I use this Actor from my own code?

Yes. Use the Apify API or one of the official SDKs (Node.js: apify-client, Python: apify-client). The Console shows ready-to-paste code samples on the API tab.

How does billing know an app returned nothing?

Billing fires on an explicit per-review charge event, not on dataset writes. The Actor only fires it when a review is delivered, so success: false records sit in your dataset for free. You get every result in one place and still branch on success and code, with a request_id for support correlation.

Found a bug or want a feature?

Open an issue on this Actor's Issues tab and include the request_id from any error record you saw. We respond within one business day.