App Store & Google Play Reviews Scraper API | iOS + Android avatar

App Store & Google Play Reviews Scraper API | iOS + Android

Pricing

from $0.10 / 1,000 reviews

Go to Apify Store
App Store & Google Play Reviews Scraper API | iOS + Android

App Store & Google Play Reviews Scraper API | iOS + Android

Scrape App Store and Google Play reviews in one run: ratings, text, dates, versions, developer replies, sentiment and topics, app details and top charts. One stable schema, CSV/Excel-ready. Multi-country, star/date/keyword filters, new-reviews-only monitoring. From $0.10 per 1,000 reviews.

Pricing

from $0.10 / 1,000 reviews

Rating

0.0

(0)

Developer

Aaron Tuttle

Aaron Tuttle

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Share

Scrape App Store and Google Play reviews in one run, in one stable schema, from $0.10 per 1,000 reviews. Ratings, review text, dates, app versions, developer replies, free sentiment and topic tags, app details, search results and top charts, ready for CSV, Excel, Google Sheets or your API.

Both stores, one runApp Store (iOS)Google Play (Android)
Reviews: stars, title, text, date, reviewer name, link✅✅
App version and helpful votes per review✅✅
Developer replies (text and date)Partly (Apple's reviews feed leaves them out)✅
Sentiment + topics per review (free, no AI service)✅✅
App details: rating, histogram, price, version, category…✅✅ + installs, data safety
Search by name, top charts per category✅✅
Many countries in one run✅ + sweep presets (top10, top25, all)✅ + many languages
Same fields for both stores (items or flat rows)✅✅

Paste app URLs, Apple app ids or Android package names (or search by name), pick countries, click Start.

💸 Pricing

Pay per result. Compute is included, there are no platform fees, and summaries, sentiment/topic tags and the competitor comparison are free. Prices drop as your Apify plan's discount tier goes up:

EventFree planBronzeSilverGoldPlatinumDiamond
Review$0.00015$0.00013$0.00012$0.0001$0.0001$0.0001
App details (per app × country)$0.002$0.002$0.0015$0.001$0.0008$0.0006
Search result or top-chart entry$0.0006$0.0005$0.0004$0.0003$0.0003$0.0002
Run start$0.001$0.001$0.001$0.001$0.001$0.001

That is $0.15 per 1,000 reviews on the free plan and from $0.10 per 1,000 reviews on Gold and above.

ExampleFree planGold
1,000 reviews$0.15$0.10
1 Google Play app with 200 reviews + app details$0.033$0.022
10 Google Play apps × 200 reviews + app details$0.32$0.21
Daily monitoring of 5 apps, ~20 new reviews a day, for 30 days≈ $0.12≈ $0.09
100 apps, details only$0.20$0.10
Top 100 of one chart$0.061$0.031

Never charged: apps that can't be found, storefronts where an app isn't sold, requests the stores refuse after all retries, reviews outside your date / star / keyword / reply filters, reviews already delivered before (monitoring mode), and duplicate reviews across countries. To cap a run, set Apify's Maximum cost per run: the scraper stops cleanly at the limit, across all event types and parallel sessions. Free-plan accounts are limited to 5 apps and 50 reviews per app per run (Apify Store rule); the log says so.

🚀 Quick start

1. Reviews of one app from both stores (the prefilled input):

{ "apps": ["https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580", "https://play.google.com/store/apps/details?id=com.spotify.music"], "countries": "us", "maxReviewsPerApp": 200 }

2. Export reviews to Excel: complaints only (1–2★) from the last 30 days, as flat rows. Run it, then click Export → Excel (or CSV) on the results:

{ "apps": ["com.spotify.music", "324684580"], "countries": "us, gb, de", "maxRating": 2, "reviewsNewerThan": "30 days", "outputFormat": "rows" }

3. Only new reviews, every day: schedule this as a task and connect Slack or a webhook (see Monitor new app reviews daily):

{ "apps": ["com.spotify.music", "324684580"], "onlyNewReviews": true, "includeAppDetails": false, "reviewSort": "newest", "maxReviewsPerApp": 200 }

How to scrape App Store reviews

  1. Paste App Store URLs (https://apps.apple.com/us/app/…/id324684580) or numeric Apple ids into Apps. iOS bundle ids work too when Stores is set to App Store.
  2. Set Countries. Each App Store storefront has its own reviews, so more countries means more reviews. For a sweep, use a preset: top5, top10, top25, top50 or all (every storefront). Reviews that show up in several storefronts are delivered once, and the run reports reviews per country.
  3. Choose Max reviews per app (per country), Review order and any filters, then click Start.

Apple shows at most the 500 most recent reviews per app per country (see Why fewer reviews than requested?). App Store reviews have a title, app version and helpful votes.

How to scrape Google Play reviews

  1. Paste Google Play URLs (https://play.google.com/store/apps/details?id=com.spotify.music) or package names (com.spotify.music).
  2. Set Languages (e.g. en, de): Google Play returns a different set of reviews per language. Thousands of reviews per app are possible.
  3. Use Only reviews newer than with Newest first so paging stops at the date you need.

Google Play reviews include the app version, thumbs-up count and the developer's reply with its date.

Export App Store and Google Play reviews to CSV, Excel or Google Sheets

  • Set Output format to Flat rows: one row per record, with the same columns on every row and in every run, so spreadsheets, BI imports and pivot tables keep working.
  • After the run, use Export for CSV, Excel, JSON or XML, or the dataset API URL in Google Sheets (=IMPORTDATA(...) with format=csv), Make, Zapier or n8n.
  • The dataset has ready-made views: Overview, Reviews, App details, Search results & top charts, Per-app summary, Competitor comparison and Flat rows.

Monitor new app reviews daily

Turn on Only new reviews (monitoring). The scraper remembers, per store × app × country, which reviews it has already delivered (in your account's key-value store app-reviews-monitor), and delivers and charges only new ones. The first run is the baseline: it delivers what it fetches. Later runs that find nothing new succeed with 0 reviews and cost only the run start. The run's OUTPUT record and the per-app summaries report newReviewsCount.

Recipe:

  1. Create a task with your apps, "onlyNewReviews": true, "reviewSort": "newest" and, usually, "includeAppDetails": false (details are charged on every run).
  2. Schedule it (Apify Console → Schedules) daily or hourly.
  3. Get the new reviews where you work:
    • Slack: add the Slack integration to the task, or a webhook on Run succeeded that posts {{resource.defaultDatasetId}} items to a Slack incoming webhook.
    • Webhook / your backend: an Apify webhook on ACTOR.RUN.SUCCEEDED calls your URL; fetch https://api.apify.com/v2/datasets/{defaultDatasetId}/items?clean=true.
    • Email, Sheets, Jira, Zendesk: Make, Zapier or n8n with the Apify app, trigger "Task run finished".
  4. Optional: "maxRating": 2 to alert on complaints only, "developerReplyFilter": "withoutReply" for reviews still waiting for an answer, or "includeKeywords": ["refund", "crash"]. Filtered-out reviews are remembered too, so they never come back as "new".

Use Monitor name (monitorKey) to keep separate monitors apart, for example one per team.

Compare competitor app reviews

List 2 or more apps (any mix of stores) and keep Competitor comparison on. You get one free comparison item with, per app: store rating, average rating of the fetched reviews, % of 1–2★ reviews, sentiment counts, top topics in negative reviews, developer reply rate, median reply time (hours), and average rating by week and by app version. In flat rows mode it becomes one row per app × metric, ready for a pivot table.

{ "apps": ["com.spotify.music", "com.apple.android.music", "deezer.android.app"], "maxReviewsPerApp": 500, "reviewsNewerThan": "90 days" }

Every review also carries sentiment (positive, neutral, negative: from the stars, nudged by a small word list with negation) and topics (crash-bug, login-account, ads, pricing-subscription, performance, ui-ux, support, feature-request, privacy), from keyword dictionaries in English, Spanish, German, French and Portuguese. They're computed locally, cost nothing, and can be turned off.

✅ Built for the problems other review scrapers have

Why fewer reviews than requested? The scraper says why, in the run log and, with app details on, in the app item's warnings:

  • Apple's cap: Apple shows at most the 500 most recent reviews per app per country. Asking for 2,000 App Store reviews in one country gets 500 at most. For more, add countries or use a sweep preset (top25, all): each storefront has its own 500, and duplicates are removed.
  • Your filters: reviews outside your date, star, keyword or reply filters are dropped, and they're free. OUTPUT.reviewsFiltered counts them.
  • The app has fewer reviews in that country or language.
  • Your cost limit: the run stops cleanly at Maximum cost per run and says so.

No schema drift. Every review, app, listing and summary item has exactly the same fields in the same order for both stores, in every run. Missing data is null, never a missing key. New fields are only ever added at the end (as sentiment and topics were), and flat rows have a fixed column list (below).

The right app and country. Every item carries store, appId, appTitle and country, and the country always comes from your Countries setting, so you can check exactly what you got.

One error never crashes the run. Requests that get a 429, 403, 5xx or network error are retried on a fresh session with capped backoff. An app that still fails becomes an error item, not charged, and the rest of the run continues. Runs resume after restarts without charging anything twice.

Dates and versions. Dates are ISO 8601 (UTC). App versions are filled whenever the store publishes them.

📊 Output fields

Review (type: "review"), same fields for both stores:

FieldDescription
storeios or android
appId, appTitleApple id / package name and app name
country, languageStorefront and language the review was fetched for
reviewIdThe store's review id
userNameReviewer's public display name
ratingStars, 1–5
title, textReview title (App Store) and text
dateReview date, ISO 8601
versionApp version the review was written for
thumbsUp, voteCountHelpful votes
developerReplyText, developerReplyDateDeveloper's reply
urlLink to the review / reviews page
scrapedAtWhen it was scraped
sentimentpositive, neutral or negative (null if tagging is off)
topicsTopic ids, e.g. ["crash-bug", "ads"] (null if tagging is off)

App details (type: "app"): title, developer and developer id, rating, rating count and 1–5 star histogram, price, currency, free / in-app purchase flags, installs (Android), version, released / updated dates, release notes, category, content rating, size, minimum OS, store URL, icon, screenshot count, data safety summary (Android; privacy is null for App Store apps), warnings.

Per-app summary (type: "summary", free, one per app × country): average rating, counts by star, % negative, average rating by version, top words in 1–2★ reviews, sentiment counts, topic counts, top negative topics, developer reply rate, oldest / newest review date, and newReviewsCount in monitoring mode.

Listing (type: "listing"): listingType (search or top-chart), query or collection/category, rank, appId, title, developer, rating, price, currency, free, url. Comparison (type: "comparison"): see above. Error (type: "error"): app, country and what went wrong; never charged.

Flat rows (Output format: rows): every row has these columns, in this order, in every run. Columns are only ever added at the end.

recordType, store, appId, appTitle, country, language, reviewId, userName, rating, title, text, date, version, thumbsUp, developerReplyText, developerReplyDate, developer, developerId, ratingCount, price, currency, free, installs, category, contentRating, released, updated, releaseNotes, listingType, query, collection, rank, summaryMetric, summaryKey, summaryValue, url, error, scrapedAt, sentiment, topics

recordType is review, app, listing, summary, comparison or error. Summary and comparison metrics use summaryMetric / summaryKey / summaryValue (e.g. averageRatingByWeek / 2026-W40 / 3.8). topics is one cell like crash-bug; ads.

A review item (Google Play):

{
"type": "review",
"store": "android",
"appId": "com.spotify.music",
"appTitle": "Spotify: Music and Podcasts",
"country": "us",
"language": "en",
"reviewId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d51",
"userName": "Priya S",
"rating": 1,
"title": null,
"text": "Keeps crashing on my phone since the latest update. Ads every two songs and shuffle is broken.",
"date": "2026-10-04T15:02:44.000Z",
"version": "9.0.88.100",
"thumbsUp": 48,
"voteCount": null,
"developerReplyText": "Hi Priya, sorry about the crashes. Please reach out to us on the Spotify Community so we can take a closer look.",
"developerReplyDate": "2026-10-05T08:10:00.000Z",
"url": "https://play.google.com/store/apps/details?id=com.spotify.music&reviewId=b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d51",
"scrapedAt": "2026-10-06T09:00:00.000Z",
"sentiment": "negative",
"topics": ["crash-bug", "ads"]
}

Input reference

InputDefaultWhat it does
appsSpotify on both storesApp Store / Google Play URLs, Apple ids, package names (bundle ids with Stores = App Store)
searchTermsnoneFind apps by name; the top maxSearchResults per store are fetched
storesbothboth, ios or android
countriesusCountry codes, e.g. us, gb, de; App Store sweep presets top5, top10, top25, top50, all
languagesenLanguages for app details and Google Play reviews
includeAppDetailstrueOne app details item per app × country (charged)
includeReviewstrueReview items (charged per review)
maxReviewsPerApp200Per app, country and language
reviewSortnewestnewest, rating or helpfulness
reviewsNewerThannoneDate (2026-01-31) or period (30 days)
minRating, maxRating1, 5Star range
includeKeywords, excludeKeywordsnoneKeep / drop reviews containing these words (case- and accent-insensitive)
developerReplyFilteranyany, withReply or withoutReply
addSentimentAndTopicstrueFree sentiment and topics on every review
includeSummarytrueFree per-app summary per country
includeComparisontrueFree comparison item when 2+ apps are covered
onlyNewReviewsfalseMonitoring: deliver and charge only reviews not delivered before
monitorKeydefaultName of the monitor (keeps independent monitors apart)
includeSearchResultsfalseAlso deliver search result lists (charged per entry)
maxSearchResults20Apps per search and entries per top chart
topChartsnoneCharts as collection:category, e.g. topselling_free:GAME
outputFormatitemsitems (JSON) or rows (flat, spreadsheet-ready)
proxyConfigurationoffApify Proxy, if you see many retries
maxConcurrency4Parallel sessions (1–10)
maxRetries6Retries per request on a fresh session

More input examples

Find competitors by name and get their details and reviews, plus the search result lists:

{ "searchTerms": ["budget planner", "expense tracker"], "stores": "both", "maxSearchResults": 10, "includeSearchResults": true, "maxReviewsPerApp": 100 }

App Store sweep: the 25 biggest storefronts, newest 100 reviews each, reviews only:

{ "apps": ["324684580"], "stores": "ios", "countries": "top25", "maxReviewsPerApp": 100, "includeAppDetails": false }

Top charts only:

{ "topCharts": ["topselling_free:GAME", "topgrossing:FINANCE", "topfreeapplications:6014", "topgrossingapplications"], "countries": "us, jp", "maxSearchResults": 50 }

Google Play chart names: topselling_free, topselling_paid, topgrossing, optionally with a category such as GAME, GAME_PUZZLE, FINANCE, PRODUCTIVITY, SOCIAL. App Store feeds: topfreeapplications, toppaidapplications, topgrossingapplications, newapplications, newfreeapplications, newpaidapplications, optionally with a numeric genre id (6014 Games, 6015 Finance, 6005 Social Networking, 6007 Productivity).

🔌 Integrations: API, Make, Zapier, n8n, MCP

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });
const run = await client.actor('AaronOptimus/app-store-reviews-scraper').call({
apps: ['com.spotify.music', 'https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580'],
countries: 'us',
maxReviewsPerApp: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python:

from apify_client import ApifyClient
client = ApifyClient("MY_APIFY_TOKEN")
run = client.actor("AaronOptimus/app-store-reviews-scraper").call(run_input={
"apps": ["com.spotify.music", "324684580"],
"countries": "us",
"maxReviewsPerApp": 100,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
  • Make, Zapier, n8n: use the Apify app/node: "Run Actor" or "Run task", then "Get dataset items". Pair with Only new reviews for alerts.
  • Webhooks and Slack: Apify integrations on the task (Slack, email, webhooks, GitHub, Google Drive).
  • AI agents (MCP): call the scraper as a tool through Apify's MCP server: "get the latest 1-star reviews of app X and their top topics" becomes one structured tool call.

🎯 Use cases

  • ASO and product teams: ratings by version and by week, the complaints behind a rating drop, iOS vs Android side by side.
  • Competitor monitoring: weekly comparison of your category's apps; top negative topics and reply rates.
  • Support and QA: new 1–2★ reviews without a developer reply, routed to the right team.
  • Investors and analysts: review velocity, rating trends and installs across a portfolio and markets.
  • Research and AI: a clean, tagged corpus of reviews with ratings, dates and versions.

💡 Tips

  • Big lists: raise Parallel sessions to 8–10, turn off app details if you only need reviews, and use Only reviews newer than with Newest first.
  • Sweeps are polite on purpose: App Store requests are spaced out across all parallel sessions, so a top50 or all sweep takes a few minutes per app.
  • Rate limits: proxy is off by default because both stores accept moderate datacenter traffic. If the log shows many retries, turn on Apify Proxy or lower Parallel sessions.
  • App Store privacy labels aren't included (privacy is null for App Store apps); Google Play apps get the data safety summary.

❓ FAQ

How many reviews can I get? Google Play: thousands per app, country and language (150 per page, paginated). App Store: up to the 500 most recent per app per country, so a top25 sweep can return up to 12,500 per app.

Is Apple's reviews feed reliable? Mostly. Apple's public reviews feed is tried first on every run. On days when it comes back empty or unavailable for an app (it did briefly in early October 2026), the scraper falls back to the reviews shown on the public App Store web page: about 10 per device view, so 10–40 per app per country, chosen by Apple, with developer replies but without app version or helpful votes. The app item's warnings and the log say when that happened, and OUTPUT.appleWebPageFallbacks counts it.

Does it sort by rating on the App Store? Apple only offers "most recent" and "most helpful". For Highest rating first, the most recent reviews are fetched and sorted by rating locally.

How does "Only new reviews" decide what's new? A review is new if its id wasn't delivered (or filtered out) by an earlier run with the same monitor name, and it isn't older than the newest review seen before minus 3 days (stores sometimes publish reviews late). Edited reviews keep their id, so they aren't sent again.

How accurate are sentiment and topics? They're keyword-based: fast, free, transparent and consistent between runs, but not an AI model. Sentiment leans on the stars, so a 1★ review is always negative and a 5★ review always positive. For nuanced analysis, feed the review text to your LLM of choice; the tags are a good first filter.

What happens when a store blocks a request? It's retried on a fresh session with capped backoff (and a fresh IP with Apify Proxy). If an app still fails, it's delivered as an error item and not charged; the rest of the run continues.

Can I search for apps by name? Yes. Search terms are searched in the selected store(s) and the top Max results per search apps are fetched with details and reviews. Turn on Include search results to also get the ranked result list.

Is it legal? The scraper only reads publicly available store pages and feeds: no login, no CAPTCHA solving, no private APIs. Reviewer names are the public display names the stores show to everyone. You're responsible for using the data in line with the stores' terms and your local laws, including data-protection rules if you store reviewer names.

🛠 Support

Found a problem or need a feature? Open an issue on the Issues tab. See the Changelog for updates.