# App Store Reviews Scraper: iOS Ratings, Titles & Text (`plainrows/app-store-reviews-scraper`) Actor

Scrape Apple App Store reviews of any iPhone or iPad app: stars, review title, text, date and app version, in 20 countries (up to 500 per app and country). Paste an App Store ID or link. No reviewer names. Only-new-reviews mode for daily alerts. Pay per review plus small fetch and start fees.

- **URL**: https://apify.com/plainrows/app-store-reviews-scraper.md
- **Developed by:** [PlainRows](https://apify.com/plainrows) (community)
- **Categories:** Developer tools, Automation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / 1,000 reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## App Store Reviews Scraper: iOS Ratings, Titles & Review Text

Export **Apple App Store reviews of any iPhone or iPad app** as clean rows: **stars, review title, review text, date and app version**, plus the app's average rating and number of ratings on every row. Paste App Store IDs (`324684580`) or `apps.apple.com` links, in any of 20 countries, up to **500 reviews per app and country** (the App Store's own limit).

It calls a commercial app data API instead of driving a browser: **no proxies, no CAPTCHAs, no Apple account**, results in under a minute. **Reviewer names and profile pictures are not collected**: you get the opinion, not the person.

The same list also accepts Google Play apps (package name or link), so you can mix both stores in one run if you need to.

### Typical uses

- **Product feedback and bug triage**: read what iOS users say about the latest version, newest first, with the app version each review was written for.
- **Competitor research**: compare your app's ratings and complaints with competitors' on the App Store, country by country.
- **Review monitoring**: turn on **Only new reviews**, schedule a daily run and alert your team in Slack or a spreadsheet: you never get (or pay for) the same review twice.
- **Sentiment analysis and AI summaries**: feed clean review titles and text to an LLM, a BI tool or an AI agent (MCP).
- **App Store Optimization (ASO)**: find the words users use in titles and reviews, and what drives 1-star ratings.

### What you get

One row per review:

| Field | Description |
|---|---|
| `store`, `appId` | `app_store` and the App Store ID |
| `appTitle`, `appRating`, `appRatingCount` | App name, its average rating out of 5 and number of ratings in this country |
| `position`, `reviewId` | Position in the order you chose; the App Store's review ID (stable: use it to keep only new reviews) |
| `rating`, `title`, `text` | Stars (1-5), review title and review text |
| `reviewedAt`, `appVersion` | Review date (the App Store gives the day, time set to 00:00 UTC) and the app version it was written for, when shown |
| `appUrl` | The app page in this country's App Store |
| `searchCountry`, `languageCode`, `observedAt` | Store country, language and when the data was fetched (UTC) |

The rows also carry `helpfulCount`, `developerReply` and `developerReplyAt`, filled for Google Play apps; on App Store rows they were empty in our test runs. Missing values are always `null`, never guessed.

### Input

```json
{
  "apps": ["https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580", "570060128"],
  "country": "US",
  "maxReviewsPerApp": 100,
  "sortBy": "newest"
}
```

- **apps**: one per line, up to 500. The numeric App Store ID (`324684580`, the `id…` part of the `apps.apple.com` link) or the link itself.
- **country**: US, GB, CA, AU, IE, IN, DE, AT, CH, FR, BE, ES, MX, IT, NL, PT, BR, PL, SE, JP. Each country has its own App Store and its own reviews. **languageCode** (optional) defaults to the country's main language.
- **maxReviewsPerApp**: up to 500 for App Store apps (higher values are read as 500): **the App Store gives at most 500 reviews per app and country** (a store limit). Run several countries to get more.
- **sortBy**: `newest` (default) or `most_relevant` (the App Store's "most helpful" order).
- **onlyNewReviews** (optional, monitoring): return only reviews never delivered to you before for the same app, country and language. See below.
- **monitorName** (optional): name of the key-value store in your account that remembers delivered reviews (default `plainrows-app-reviews-monitor`).

### Monitor apps: get only new reviews

Turn on **Only new reviews** (`"onlyNewReviews": true`), keep `sortBy: "newest"` and add an Apify **schedule** (daily, for example). The first run returns the reviews it finds and remembers their IDs in a key-value store of your own Apify account; each later run returns **and bills only reviews it has never delivered**. An app with nothing new gets a free row with `notFoundReason: "no-new-reviews"`. The blocks requested are still charged on every check (the data source bills them either way): with `maxReviewsPerApp` left at 100, one app costs 4 blocks per check, with 25 only 1.

- Each run reads one page of the newest reviews: `maxReviewsPerApp`, rounded up to whole blocks of 25. **Set `maxReviewsPerApp` above the number of new reviews you expect between two runs**: if more new reviews arrive than that page holds, the older new ones are not read again and are missed. When a check finds a full page of reviews and none of them was delivered before, the run warns you (`more than … new reviews since the last run`, also counted in `appsPossiblyMissingReviews` in the run summary): raise `maxReviewsPerApp` or run the check more often. When a check reads new reviews that your limit leaves out (for example 15 of a block of 25 with `maxReviewsPerApp` at 10), the run warns too (`reviewsBeyondLimitNotDelivered` in the run summary).
- Use a different **monitorName** per monitoring task to keep separate histories, or a new name to start over.

### Output example

Real row from a run on 2026-10-14 (App Store, US, Duolingo `570060128`):

```json
{
  "store": "app_store",
  "appId": "570060128",
  "found": true,
  "appTitle": "Duolingo: Learn Languages",
  "appRating": 4.7,
  "appRatingCount": 5505486,
  "position": 3,
  "reviewId": "14658938893",
  "rating": 5,
  "title": "It works",
  "text": "I love it. I really wanted to learn Japanese I have a lot of time on my hands and man I look forward to getting on the app everyday and learning. I share with my friends what I learn I catch my self alone repeating words and phrases or sentences iv learned money well spent.",
  "reviewedAt": "2026-10-12T00:00:00.000Z",
  "appVersion": "7.144.0",
  "helpfulCount": null,
  "developerReply": null,
  "developerReplyAt": null,
  "appUrl": "https://apps.apple.com/us/app/id570060128",
  "searchCountry": "US",
  "languageCode": "en",
  "observedAt": "2026-10-13T22:47:02.695Z",
  "schemaVersion": "1.0"
}
```

### Pricing

Pay per result, no subscription, no proxy costs. See the **Pricing** tab for current prices. Three events, nothing else:

- **Review**: one per review returned, cheaper on higher Apify plans. Title, version and the app's rating are included.
- **Block of reviews requested**: App Store data is fetched in blocks of up to **25 reviews** per app and country, and the data source bills us every block requested. So 100 reviews = 4 blocks, 25 reviews = 1 block. A block is charged once the store has answered, even if the app has fewer reviews than you asked for, or none. Tip: set `maxReviewsPerApp` to what you need to pay for fewer blocks (with Only new reviews, keep it above the number of new reviews expected between two runs).
- **Actor start**: a small fixed fee per run, charged by Apify when the run starts.

Example, 100 reviews of one app at free Apify plan prices, run start included: about $0.017.

Duplicates and input mistakes cost nothing beyond the start fee, and requests the store does not answer are not charged. A review that comes back without its text or date field at all (the data source changed its format) is neither delivered nor charged, and neither are the blocks of an app where no review was readable. The run never spends more than the maximum cost you set.

**Free Apify plan:** each run returns up to 50 reviews for up to 2 apps, so you can check the output. A paid Apify plan removes these limits.

### Use it from code, automations or AI agents

**API (one call, results returned directly):**

```bash
curl -X POST "https://api.apify.com/v2/acts/plainrows~app-store-reviews-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"apps": ["324684580"], "country": "US", "maxReviewsPerApp": 50}'
```

**n8n, Make, Zapier:** use the Apify integration, pick `plainrows/app-store-reviews-scraper`, schedule it daily and post new `reviewId`s with 1 or 2 stars to Slack.

**AI agents (MCP):** add `https://mcp.apify.com?tools=plainrows/app-store-reviews-scraper` to Claude, Cursor or any MCP client. The agent gets a typed tool and pays per result.

### What this is not

- No reviewer names, profile pictures or user IDs.
- Not every review ever written: the App Store exposes the 500 most recent (or most helpful) reviews per app and country.
- Ratings without text are not reviews and are not returned; `appRatingCount` counts them.
- Not affiliated with Apple.

### Run summary

Each run stores a summary in the key-value store (`OUTPUT`): apps submitted, apps run, blocks of reviews charged, how many returned nothing, reviews billed, requests the store did not answer, monitored apps that probably got more new reviews than one check reads (`appsPossiblyMissingReviews`), duplicates and invalid values, reviews dropped because the data source changed its format (`reviewsWithChangedFormat`), and anything skipped because of the free-plan or budget limit.

### FAQ

**How do I export App Store reviews of an iPhone app?**
Paste the App Store ID (`324684580`) or the `apps.apple.com` link and run: one row per review with stars, title, text, date and version.

**How many reviews per app?**
The App Store gives at most 500 reviews per app and country. Run the same app in several countries (US, GB, CA, AU…) to get more.

**Does it include reviewer names?**
No: reviewer names, pictures and user IDs are not collected.

**How do I get only new reviews every day?**
Turn on **Only new reviews**, keep `sortBy: "newest"`, schedule the run daily and set `maxReviewsPerApp` above the number of new reviews the app gets per day (see Monitor apps above).

**Can I add Google Play apps too?**
Yes, the same list accepts Google Play package names and links; for both stores in one tool see [App Store & Google Play Reviews Scraper](https://apify.com/plainrows/app-reviews-scraper).

### More PlainRows tools

Same pay-per-result pricing, same clean JSON, built to chain together in n8n, Make, Zapier or AI agents.

- **SEO and keywords:** [Keyword Search Volume, CPC & Difficulty](https://apify.com/plainrows/keyword-search-volume) · [Keyword Ideas Generator](https://apify.com/plainrows/keyword-ideas-generator) · [Google Autocomplete & People Also Ask](https://apify.com/plainrows/google-autocomplete-questions) · [Google Trends Explorer](https://apify.com/plainrows/google-trends-explorer) · [Website Organic Traffic & Top Keywords](https://apify.com/plainrows/domain-seo-overview) · [Bulk Domain Authority Checker](https://apify.com/plainrows/domain-authority-checker) · [Backlink Checker](https://apify.com/plainrows/backlink-checker) · [Broken Link Checker](https://apify.com/plainrows/broken-link-checker) · [AI Search Visibility Tracker (ChatGPT, Gemini, AI Mode)](https://apify.com/plainrows/ai-search-brand-visibility) · [Google Maps Rank Tracker (Geo-Grid Local SEO)](https://apify.com/plainrows/google-maps-rank-tracker)
- **Leads and companies:** [Google Maps Scraper](https://apify.com/plainrows/google-maps-businesses) · [Google Maps Email Extractor](https://apify.com/plainrows/google-maps-email-extractor) · [Google Maps Businesses Without Website](https://apify.com/plainrows/google-maps-no-website-leads) · [Website Technology Checker](https://apify.com/plainrows/website-tech-stack) · [Website Email Extractor](https://apify.com/plainrows/website-email-extractor) · [ATS Jobs Scraper (Workday, Greenhouse, Lever, Ashby)](https://apify.com/plainrows/ats-job-postings) · [Workday Jobs Scraper](https://apify.com/plainrows/workday-jobs-scraper) · [Greenhouse Jobs Scraper](https://apify.com/plainrows/greenhouse-jobs-scraper) · [Lever Jobs Scraper](https://apify.com/plainrows/lever-jobs-scraper) · [Ashby Jobs Scraper](https://apify.com/plainrows/ashby-jobs-scraper) · [Google Jobs Scraper](https://apify.com/plainrows/google-jobs-scraper) · [Google Ads Scraper (Transparency Center)](https://apify.com/plainrows/google-ads-transparency) · [Company Registry Lookup (SIRENE, LEI, Brreg)](https://apify.com/plainrows/company-registry-lookup) · [Public Tenders Search (EU TED & UK)](https://apify.com/plainrows/public-tenders-search)
- **E-commerce and travel:** [Amazon Product Search Scraper](https://apify.com/plainrows/amazon-product-search) · [Google Shopping Prices Scraper](https://apify.com/plainrows/google-shopping-prices) · [Google Hotels Prices Scraper](https://apify.com/plainrows/google-hotels-prices) · [Tripadvisor Reviews Scraper](https://apify.com/plainrows/tripadvisor-reviews) · [Trustpilot Reviews Scraper](https://apify.com/plainrows/trustpilot-reviews)
- **Content and media:** [Google News Scraper](https://apify.com/plainrows/google-news-scraper) · [YouTube Search Scraper](https://apify.com/plainrows/youtube-search-scraper) · [YouTube Comments Scraper](https://apify.com/plainrows/youtube-comments-scraper) · [Google Images Scraper](https://apify.com/plainrows/google-images-scraper) · [Website Screenshot API](https://apify.com/plainrows/website-screenshot) · [Google Maps Reviews Scraper](https://apify.com/plainrows/google-maps-reviews) · [Google Reviews Scraper](https://apify.com/plainrows/google-reviews-scraper) · [App Store & Google Play Reviews Scraper](https://apify.com/plainrows/app-reviews-scraper) · [Google Play Reviews Scraper](https://apify.com/plainrows/google-play-reviews-scraper)

### Support

Missing a field, a country or found a bug? Open an issue on this page. Issues are read and answered.

# Actor input Schema

## `apps` (type: `array`):

One per line: an App Store ID ("324684580", the id… part of the apps.apple.com link) or the link to the app page. Google Play package names and links work too, in the same list. Up to 500 apps per run.

## `country` (type: `string`):

Store country: reviews written in this country's store (the App Store is separate per country; Google Play filters by country and language).

## `languageCode` (type: `string`):

Two-letter language code of the reviews, e.g. "en" or "de". Leave empty to use the country's main language.

## `maxReviewsPerApp` (type: `integer`):

Google Play: up to 5,000. App Store: the store gives at most 500 per app and country. Each review returned is billed; see Pricing.

## `sortBy` (type: `string`):

Newest first suits monitoring. "Most relevant" uses Google Play's relevance order and the App Store's most helpful order.

## `onlyNewReviews` (type: `boolean`):

Return only reviews this tool has never delivered to you for the same app, country and language. The first run returns the reviews and remembers them; later runs (for example a daily schedule) return and bill only new reviews. Each run reads only the newest "Max reviews per app" (in whole blocks): set it above the number of new reviews expected between two runs, or older new reviews are missed (the run warns you). The block fee still applies.

## `monitorName` (type: `string`):

Name of the key-value store in your Apify account that remembers delivered reviews (default "plainrows-app-reviews-monitor"). Use a different name per monitoring task to keep separate histories, or a new name to start over. Lowercase letters, digits and hyphens.

## Actor input object example

```json
{
  "apps": [
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
    "570060128"
  ],
  "country": "US",
  "maxReviewsPerApp": 100,
  "sortBy": "newest",
  "onlyNewReviews": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "apps": [
        "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
        "570060128"
    ],
    "country": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainrows/app-store-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "apps": [
        "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
        "570060128",
    ],
    "country": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("plainrows/app-store-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "apps": [
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
    "570060128"
  ],
  "country": "US"
}' |
apify call plainrows/app-store-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plainrows/app-store-reviews-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/JnDSvaBCJ0MgpVlba/builds/EuDodMXt0f6HBhVPH/openapi.json
