# App Store Reviews Scraper (`apifry/app-store-reviews-scraper`) Actor

Extracts Apple App Store reviews by app id or URL across one, many or all countries; returns rating, title, text, date, app version, helpful votes and reviewer as JSON. Only-new mode for monitoring, star and keyword filters. Export, API, schedules, MCP.

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

## Pricing

from $0.11 / 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 extracts **Apple App Store reviews** by app id or app URL — from one country, a list of countries, or all ~175 App Store countries in one run. One row = one review: star rating, review title and text, date, app version, helpful votes, and the reviewer's public nickname and id. You pay **$0.15 per 1,000 reviews stored** (down to $0.105 on higher Apify plans) — reviews skipped by your date, star or keyword filters are free.

**Why several countries matter:** Apple shows only the newest 500 written reviews per country (and 500 "most helpful"). Every country has its own reviews, so the same app gives ~1,000 reviews in the US, another ~1,000 in the UK, Germany, Japan and so on. In our test, Instagram + WhatsApp in 3 countries gave **5,979 unique reviews in one run**.

Built for **review monitoring**: set *Only new since the last run*, schedule it daily, and each run returns only the reviews posted since the previous one. App rating, total ratings, the 1–5 star distribution and reviews per country are saved once per app in a separate summary, so your review table stays clean.

### What data does App Store Reviews Scraper extract?

| Field | Example | Notes |
|---|---|---|
| `targetId` | `389801252` | App Store app id |
| `targetName` | `Instagram` | App name |
| `reviewId` | `14700000001` | Unique review id — use it to deduplicate across runs |
| `rating` | `2` | Stars, 1–5 |
| `title` | `Keeps logging me out` | Review title |
| `text` | `Since the last update the app …` | Full review text |
| `publishedAt` | `2026-11-03T18:39:07Z` | Posted or last edited, ISO 8601 UTC |
| `appVersion` | `454.0.0` | App version the reviewer used |
| `helpfulCount` | `3` | "Helpful" votes |
| `country` | `GB` | App Store country the review was posted in |
| `authorName` | `Ann B` | Reviewer's public nickname |
| `authorId` | `1234567890` | Reviewer's App Store id |
| `url` | `https://apps.apple.com/gb/app/id389801252?see-all=reviews` | The app's reviews page in that country |
| `scrapedAt` | `2026-11-05T17:51:11Z` | When the row was collected |

`source` (always `app_store`), `targetUrl`, `language`, `authorImageUrl`, `updatedAt`, `replyText`, `replyAt` and `aspectRatings` complete the shared Apifry reviews format: the same columns are used by our other review scrapers (for example Google Play), so one parser handles them all. Apple's public review feed has no language tag, avatars, developer replies or per-aspect ratings, so those are always `null` here.

#### App summary (key-value store, record `SUMMARY`)

One entry per app: `rating` (average) and `ratingsCount` in `ratingCountry` (the first of your countries where the app exists), `starsDistribution` (`{"1": …, "5": …}`), `reviewsScrapedThisRun`, `reviewsByCountry` (`{"US": 999, "GB": 989, …}`), `error` (why an app failed, if it did) and `note` (failed countries, why an app returned nothing, or when Apple's 500-review limit was reached). It is free.

### How much does it cost to scrape App Store reviews?

Pay per event: **$0.15 per 1,000 reviews** stored in the dataset on the Free plan, $0.135 on Starter, $0.12 on Scale and $0.105 on Business. There is no start fee and no charge for:

- reviews older than your *Only reviews newer than* date or your last run,
- reviews that don't match your star ratings or keywords,
- duplicates (the same review in the newest and the most-helpful list),
- apps that are not found, and countries with no reviews or that fail.

| Reviews | Price |
|---|---|
| 1,000 | $0.15 |
| 10,000 | $1.50 |
| 50,000 (e.g. 100 daily runs of 500) | $7.50 |

The Apify free plan's $5 monthly credit covers about 33,000 reviews. You can also cap any run with *Maximum cost per run* in the run options; the scraper stops cleanly at the cap and charges nothing beyond it.

### Review analytics add-ons (optional)

Three paid add-ons turn the reviews of a run into answers. All are **off by default**, rule-based (dictionaries in English, German, French, Spanish, Portuguese, Italian and Russian — **not AI**), and priced on the Pricing tab.

- **Tag every review** — each review gets `topics` (crashes & bugs, login & account, ads, price & subscription, updates, speed & battery, interface, customer support), `sentiment` (positive, neutral, negative or mixed — stars plus words, negations handled), `isBugReport` and `isFeatureRequest`. Tagged reviews are charged *Review with tags* instead of *Review*; a review in another language stays untagged (`topics: null`) at the plain review price.
- **Insights per app** — key-value record `INSIGHTS`: complaint topics with their share of 1–2 star reviews and 2–3 quotes linking to the review, frequent words and phrases in 1–2 star reviews (stopwords and the app's own name removed), feature requests with examples. One charge per app.
- **Trends per app** — key-value record `TRENDS`: average rating, number of reviews and 1–2 star share per day, week or month, change to the previous period, a spike flag, and the same by app version and by country. One charge per app.

What you will never pay for: an app with fewer than 30 reviews in the run, an app that failed, or a run that stopped at your maximum cost — the record is still written and says why it was free. Every record states how many reviews and which dates it is based on; the App Store rating itself stays in the free `SUMMARY`. Star or keyword filters make a sample unrepresentative, so records say so and trends then show counts only. For a true trend, use *Newest first* and one language or country, or a limit large enough for every list to reach back the same distance.

### How to scrape App Store reviews

1. Open the **Input** tab and add apps — the numeric id (`389801252`) or the app URL from your browser (`https://apps.apple.com/us/app/instagram/id389801252`).
2. Add **countries** (`us`, `gb`, `de` …) or switch on **All countries**.
3. Set **Max reviews per app per country** (100 for a quick look, 500–1,000 for everything Apple shows) and the **Order**: *Newest + most helpful* reads both of Apple's lists for up to ~1,000 reviews per country.
4. Optional: pick star ratings (1 and 2 stars for complaints), keywords, or a date.
5. Click **Start**. Reviews appear in the **Output** tab within seconds. Download as JSON, CSV, Excel or HTML, or read the dataset via the API.

#### ⬇️ Input example

```json
{
  "apps": ["389801252", "https://apps.apple.com/us/app/whatsapp-messenger/id310633997"],
  "countries": ["us", "gb", "de"],
  "maxReviewsPerCountry": 1000,
  "sort": "newestAndMostHelpful",
  "stars": ["1", "2"],
  "keywords": ["crash", "login"]
}
```

#### ⬆️ Output example

```json
{
  "source": "app_store",
  "targetId": "389801252",
  "targetName": "Instagram",
  "targetUrl": "https://apps.apple.com/gb/app/id389801252",
  "reviewId": "14700000001",
  "rating": 2,
  "title": "Keeps logging me out",
  "text": "Since the last update the app logs me out every day.",
  "language": null,
  "country": "GB",
  "authorName": "Ann B",
  "authorId": "1234567890",
  "authorImageUrl": null,
  "publishedAt": "2026-11-03T17:59:15Z",
  "updatedAt": null,
  "appVersion": "454.0.0",
  "replyText": null,
  "replyAt": null,
  "helpfulCount": 0,
  "url": "https://apps.apple.com/gb/app/id389801252?see-all=reviews",
  "aspectRatings": null,
  "scrapedAt": "2026-11-05T17:51:11Z"
}
```

### Monitor new App Store reviews every day

Turn on **Only new since the last run** and create a schedule (Apify Console → Schedules). The first run collects up to *Max reviews per app per country*; every next run keeps only reviews newer than the newest one the previous run saw in that country, then stops — so a daily run on an app with 50 new reviews costs less than $0.01. The mark is stored per app and country in the key-value store `apifry-app-store-reviews-state` in your own account; delete that store to start over.

The mark moves only after the run's reviews are saved. If a run is interrupted or stops at your max charge limit, the mark is not moved and the next run picks up the gap. If *Max reviews per app per country* ends the list first, the mark moves to the newest review and `SUMMARY.note` says so — use a cap of 500 for monitoring so no new review is skipped. Apple shows only the newest 500 reviews per country, so for very busy apps (hundreds of reviews a day in the US) schedule runs daily or more often; `SUMMARY.note` tells you when a gap was too long to reach.

For a one-off window use **Only reviews newer than** with a date (`2026-10-01`) or a period (`7 days`, `12 hours`, `2 weeks`).

### Use cases

- **Product and app teams** — read 1–2 star reviews after each release; `appVersion` shows which build they hit.
- **Localization and global launches** — compare what users say in each country; `reviewsByCountry` shows where reviews come from.
- **Competitor research** — compare complaints and praise across competing apps and markets.
- **ASO and marketing** — track the rating and the star distribution over time from `SUMMARY`; mine review titles for keywords.
- **Data teams and LLM apps** — feed fresh reviews into sentiment analysis, topic clustering or a support agent.

### Bulk export of App Store reviews

Switch on **All countries**, set *Max reviews per app per country* to 1,000 and the order to *Newest + most helpful*. Countries without reviews cost nothing. Requests are paced so Apple does not block the run; if Apple slows it down, the scraper pauses and continues, and any country that still fails is listed in `SUMMARY.note`. If Apple refuses the run's IP outright, the run stops within a few minutes with a clear message instead of retrying for an hour. Duplicates are removed inside a run; across runs, deduplicate on `targetId` + `reviewId`.

### Integrations

Run it from the Apify API, the Python or JavaScript client, n8n, Make, Zapier, Google Sheets or Slack, or let an AI agent call it through the Apify MCP server. Results can be pushed to a webhook when a run finishes.

### 🤖 For AI Agents & LLM Apps

**Purpose:** returns Apple App Store reviews as structured rows for one or many countries, filtered by date, stars and keywords; built for monitoring an app's new reviews and for multi-country exports.

**Minimal input:** `{"apps": ["389801252"]}` — returns the 100 newest reviews from the US App Store. Add `countries` (or `allCountries: true`) and raise `maxReviewsPerCountry` for more.

**Output fields (one row per review):** `source`, `targetId` (numeric app id), `targetName`, `targetUrl`, `reviewId`, `rating` (1–5), `title`, `text`, `language` (null), `country` (upper-case store code), `authorName`, `authorId`, `authorImageUrl` (null), `publishedAt` (ISO UTC), `updatedAt` (null), `appVersion`, `replyText` (null), `replyAt` (null), `helpfulCount`, `url` (the app's reviews page in that country), `aspectRatings` (null), `scrapedAt`. Per-app rating, rating count, star distribution and reviews per country are in the key-value store record `SUMMARY`, not in the dataset.

**Behaviour:** each country is read separately; `maxReviewsPerCountry` (default 100, max 1,000) caps rows per app per country, so the most rows per app = cap × countries. Apple serves at most 500 reviews per country for each order: `sort: "newest"` (default) or `"mostHelpful"` → up to 500; `"newestAndMostHelpful"` → up to ~1,000, duplicates removed. `onlyNewerThan` and `onlyNewSinceLastRun` force newest-first order and stop once older reviews are reached. `stars` and `keywords` (matched in title or text) filter rows; misses are free. Unknown country codes are skipped with a log warning (`uk` is read as `gb`). Apps not found in any of your countries, and countries that fail, are listed in `SUMMARY.error` / `SUMMARY.note`. The run fails only if no reviews were stored and the App Store itself failed; a mistyped app id or zero new reviews after a cut-off is a successful run.

**Limits:** no developer replies, review language or avatars (not in Apple's public feed). `publishedAt` is the latest edit date. Reviews are public text; the data does not prove the reviewer used the version shown.

**Billing:** only stored reviews are charged (event `review`); filtered, older, duplicate and failed items are free.

**Paid add-ons (off by default):** `includeTags` adds `topics`, `sentiment`, `isBugReport`, `isFeatureRequest` to each row (event `review-tagged` instead of `review`; untagged languages stay `review`). `includeInsights` writes key-value record `INSIGHTS` and `includeTrends` writes `TRENDS`, one list item per app with `charged`, `partial` and `notCharged` (the reason it was free); events `insights` and `trends`, one per app with 30+ reviews from a complete run. Rule-based, not AI.

### ❓ FAQ

#### Is it legal to scrape App Store reviews?

The scraper collects only publicly visible reviews, without logging in. Reviews include reviewers' public nicknames, which may be personal data under GDPR and similar laws. Use the data for legitimate purposes and consult a lawyer if unsure.

#### Do I need an Apple account or an API key?

No. Add the app id or URL and run.

#### How do I find an app's id?

Open the app on apps.apple.com; the id is the number after `id` at the end of the address (`…/instagram/id389801252` → `389801252`). You can paste the whole URL instead.

#### Why do I get at most 500 (or ~1,000) reviews per country?

That is how many reviews Apple publishes per country: the newest 500 and the 500 most helpful. To collect more, add countries — each has its own reviews — or monitor the app daily so new reviews are collected before they drop out of the newest 500.

#### Why are there fewer reviews than the app's rating count?

Most App Store ratings are star-only, without text. `ratingsCount` in `SUMMARY` counts all ratings; the dataset holds written reviews.

#### Can I get developer replies?

Not with this scraper: Apple's public review feed does not include them.

#### Can I get only negative reviews?

Yes: select 1 and 2 stars in *Star ratings*. You pay only for the reviews returned.

#### Does it need a proxy?

No. The App Store is reachable without one, and the scraper paces its requests. If you still see rate-limit errors, turn on *Use Apify Proxy (datacenter)*.

#### Can AI agents use it?

Yes. It runs through the Apify MCP server and the API; see the *For AI Agents* section above for the exact behaviour.

### Support

Open an issue on the **Issues** tab — we usually answer within a day. Tell us the app, the countries and what you expected to see.

### You might also like

- [Google Play Reviews Scraper](https://apify.com/apifry/google-play-reviews-scraper) — the same review format for Android apps, with developer replies.
- [Website Contact Scraper](https://apify.com/apifry/website-contact-extractor) — emails, phones and social profiles from company websites.

*Also known as: App Store review scraper, iOS app reviews API, Apple app reviews export, App Store reviews to CSV.*

# Actor input Schema

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

Add App Store apps as numeric ids (389801252) or app URLs (https://apps.apple.com/us/app/instagram/id389801252). One app per line.

## `countries` (type: `array`):

Add two-letter App Store country codes (us, gb, de, fr, jp …). Each country has its own reviews, so more countries = more reviews. Default: us.

## `allCountries` (type: `boolean`):

Turn on to read every App Store country (about 175) instead of the list above. Countries without reviews cost nothing.

## `maxReviewsPerCountry` (type: `integer`):

Enter the most reviews to keep per app in each country (3 countries x 100 = up to 300 per app). Apple serves up to 500 newest reviews per country, and up to ~1,000 with 'Newest + most helpful'. You pay only for reviews stored in the dataset.

## `sort` (type: `string`):

Choose which of Apple's review lists to read. 'Newest + most helpful' reads the most-helpful list only after the newest list, so it adds reviews only when Max reviews per country is above 500. Date filters below always use Newest first.

## `onlyNewerThan` (type: `string`):

Enter a date (2026-10-01) or a relative period (7 days, 12 hours, 2 weeks). Older reviews are skipped and not charged; the run stops once it reaches them.

## `onlyNewSinceLastRun` (type: `boolean`):

Turn on for scheduled monitoring: each run keeps only reviews newer than the newest one seen by your previous run (per app and country). The mark is kept in the key-value store 'apifry-app-store-reviews-state' in your account. Busy apps get 500 reviews within days, so schedule daily for them.

## `stars` (type: `array`):

Select the star ratings to keep, e.g. 1 and 2 for complaints. Other reviews are skipped and not charged. Leave empty for all ratings.

## `keywords` (type: `array`):

Add words or phrases; only reviews whose title or text contains at least one of them are kept (case-insensitive). Reviews without a match are not charged. Leave empty to keep all.

## `includeTags` (type: `boolean`):

Adds topics (crashes, login, ads, price, updates, speed, interface, support), sentiment, isBugReport and isFeatureRequest to each review. Tagged reviews are charged the 'Review with tags' price instead of 'Review'. Reviews in languages other than EN, DE, FR, ES, PT, IT, RU stay untagged at the plain review price. Rule-based, not AI.

## `includeInsights` (type: `boolean`):

Writes record INSIGHTS: complaint topics with shares and quotes, frequent words and phrases in 1–2 star reviews, feature requests, developer reply rate and time. Charged once per app with at least 30 reviews in this run; failed, incomplete or tiny samples are free. Based on the reviews this run collected — the store rating stays in SUMMARY.

## `includeTrends` (type: `boolean`):

Writes record TRENDS: average rating, review count and 1–2 star share per week or month with change to the previous period, a spike flag, and the same by app version and by country. Charged once per app with at least 30 reviews in this run. Use Newest first and no star or keyword filter for a true picture.

## `useApifyProxy` (type: `boolean`):

Turn on only if runs fail with rate-limit errors. The App Store is normally reachable without a proxy.

## Actor input object example

```json
{
  "apps": [
    "389801252"
  ],
  "countries": [
    "us"
  ],
  "allCountries": false,
  "maxReviewsPerCountry": 100,
  "sort": "newest",
  "onlyNewSinceLastRun": false,
  "includeTags": false,
  "includeInsights": false,
  "includeTrends": false,
  "useApifyProxy": false
}
```

# Actor output Schema

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

No description

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

No description

## `insights` (type: `string`):

No description

## `trends` (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": [
        "389801252"
    ],
    "countries": [
        "us"
    ],
    "maxReviewsPerCountry": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("apifry/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": ["389801252"],
    "countries": ["us"],
    "maxReviewsPerCountry": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("apifry/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": [
    "389801252"
  ],
  "countries": [
    "us"
  ],
  "maxReviewsPerCountry": 100
}' |
apify call apifry/app-store-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apifry/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/iJ6bGHanoB4Qj7kAa/builds/Gicf6hgrTizn2tFoI/openapi.json
