App Store & Google Play Reviews Scraper avatar

App Store & Google Play Reviews Scraper

Pricing

$0.20 / 1,000 reviews

Go to Apify Store
App Store & Google Play Reviews Scraper

App Store & Google Play Reviews Scraper

User reviews of iOS and Android apps in one Actor, with developer replies where the store publishes them.

Pricing

$0.20 / 1,000 reviews

Rating

0.0

(0)

Developer

Lantern Lab

Lantern Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

A Lantern Lab Actor. Give it iOS and Android apps and get their user reviews: one row per review with the rating, title, text, app version, publish time, reviewer name and - on Google Play - the developer's public reply. Both stores in one run, any storefront, including the Chinese App Store. No login, no cookies, no account of your own.

Every app and country gets a summary row saying whether its reviews were collected in full. An app that was cut short is marked partial: true with the reason, and one that could not be read is failed - neither is ever reported as "0 reviews".

What it does

  • Reads App Store reviews from Apple's public customer-review feed, page by page, and Google Play reviews from the store page's own review endpoint, following its pagination.
  • Takes both stores in one apps list: App Store links or IDs, Google Play links or package names, mixed freely.
  • Reads every app once per country in countries, so one line covers as many storefronts as you need.
  • Carries the developer's reply on Google Play rows: who answered, what they wrote and when.
  • Says per app and country how complete the result is, and ends with a RUN_SUMMARY holding the run totals, the request count and the reason the run stopped.

What it does not do

  • No app details, charts, or store search. Reviews only.
  • No sentiment scores and no AI summaries. The text is the store's, unchanged.
  • No developer replies on App Store rows. Apple's public review feed does not carry them, so developerReply is null on every App Store row and the summary row says developerRepliesAvailable: false. Google Play rows carry the real reply. The field is never filled with a guess.
  • No review titles on Google Play rows: that store has no title field, so title is null.
  • No guessing when a store returns nothing for an app in a storefront: that pair is reported not_found with the reason, never as an app without reviews. For the App Store the empty feed is checked against Apple's public lookup first, so "no such app" and "no reviews yet" stay apart.
  • No scheduling or monitoring built in; use Apify schedules.

Input

FieldDefaultMeaning
apps-One app per line: an App Store link (https://apps.apple.com/us/app/id284882215), a bare App Store ID (284882215 or id284882215), a Google Play link (https://play.google.com/store/apps/details?id=com.spotify.music), or a bare package name (com.spotify.music). Required.
countries["us"]Two-letter storefront codes. Each app is read once per country.
maxReviewsPerApp200Reviews per app and country (1-5000).
sortnewestnewest, mostHelpful, or rating.
maxUpstreamRequestsderivedHard ceiling on store requests for the whole run, counted in HTTP attempts.

Example:

{
"apps": [
"https://apps.apple.com/us/app/id284882215",
"com.spotify.music"
],
"countries": ["us", "gb"],
"maxReviewsPerApp": 200,
"sort": "newest"
}

The same app entered twice is read once. The country in an App Store link is ignored: countries decides which storefronts are read.

Two store limits are reported rather than worked around:

  • The public App Store feed holds at most 500 reviews per app and country. Ask for more and that pair ends partial with partialReasonCode: "store_page_limit".
  • That feed has no rating sort. With sort: "rating" an App Store app is read newest-first and its summary row shows sortRequested: "rating", sortApplied: "newest". Google Play supports all three orders.

maxUpstreamRequests gives you a known upper bound before the run starts. Left empty, the Actor derives one from your input - (sum over app/country pairs of ceil(reviews wanted / 50) + 1) x 2 + 2, which is 12 for one app, one country and 200 reviews - so a run is never uncapped. When the ceiling is reached, the pair being read is marked partial with partialReasonCode: "request_cap", every pair after it is written as not_collected, and the run ends normally. That is your limit, not a problem at the store.

Output

One dataset; recordType tells the rows apart. Two table views are predefined: Reviews and App summaries. A RUN_SUMMARY record in the key-value store holds the run totals and the status of every app and country.

Review rows (recordType: "review"):

FieldMeaning
storeappStore or googlePlay.
appIdNumeric App Store ID, or Google Play package name.
countryThe storefront this row was read from.
reviewIdThe store's own ID for the review.
parentCommentIdAlways null: neither store threads reviews.
ratingStars, 1-5.
titleReview title. null on Google Play, which has no title field.
textThe review as the user wrote it.
versionApp version the review was written against, when the store publishes it.
publishedAtWhen the store says it was posted (UTC). Apple updates this timestamp when a review is edited.
userNameThe public display name shown next to the review.
helpfulVotesGoogle Play: thumbs-up count. App Store: Apple's net helpful-vote sum.
developerReply{ developerName, text, repliedAt }, or null. Always null on App Store rows.
appUrl, reviewUrlPublic links. reviewUrl is null on App Store rows: Apple has no per-review link.
collectedAtWhen we read the row (UTC).

App summary rows (recordType: "app_summary"), one per app and country:

FieldMeaning
collectionStatuscomplete, partial, empty, not_found, failed, or not_collected.
partialtrue when this pair was not collected in full.
partialReason / partialReasonCodeWhy collection was short, in words and as a stable code: request_cap, charge_limit, store_page_limit, store_blocked, store_error. The code column never carries anything else, so it is safe to branch on.
statusReasonThe status in words, including statuses that have no code - for example an app that is not in this storefront.
reviewsCollected / reviewsRequestedWhat we got, and what the run asked for.
duplicatesSkippedReviews the store returned twice while paging; written once.
pagesReadStore pages read for this pair.
developerRepliesHow many of the collected reviews had a developer reply.
developerRepliesAvailableWhether this store publishes replies at all.
sortRequested / sortAppliedWhat you asked for, and what the store could serve.

Statuses in one line: complete - everything you asked for, or everything the store has; partial - cut short, reason given; empty - the app exists here and has no reviews; not_found - no such app in this storefront; failed - the store could not be read; not_collected - the run stopped before this pair was reached.

Collection boundaries

Only what the stores show publicly, signed out. No login, no cookies, no account. Reviewer fields are limited to the display name the store prints next to the review; no avatars, profile links or other personal data are collected.