# App Store Reviews Scraper — Any App, Any Country | $0.25/1K (`steadyrow/appstore-reviews`) Actor

Scrape Apple App Store reviews for any app in any country storefront: ratings, titles, text, app versions and helpful votes. Filter by stars and date, sort newest or most helpful, and use monitor mode to get only new reviews. Official RSS feed, no proxy, no reviewer names.

- **URL**: https://apify.com/steadyrow/appstore-reviews.md
- **Developed by:** [Steadyrow](https://apify.com/steadyrow) (community)
- **Categories:** Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.25 / 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.

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 — Any App, Any Country | $0.25/1K

**Get Apple App Store reviews for any iPhone or iPad app, from any country storefront, as clean JSON. $0.25 per 1,000 reviews.**

Paste app IDs or `apps.apple.com` links, pick the countries, and get rating, review title, text, app version, helpful votes and date for every review. The Actor reads Apple's public customer-reviews feed — no login, no browser, no proxy — and has a **monitor mode** that returns only reviews you have not received yet.

**No reviewer names, profile links or avatars are collected.**

- ✅ **Any app, any storefront** — `us`, `gb`, `de`, `jp`, `br`… each country has its own reviews, fetched separately
- ✅ **Paste whatever you have** — `324684580`, `id324684580` or the full `apps.apple.com/…/id324684580` link
- ✅ **Filters** — star ratings, `since` / `until` (absolute dates or "7 days", "3 months"), newest or most helpful first
- ✅ **Monitor mode** — schedule it and get only new reviews (alerts, support dashboards, release checks)
- ✅ **App version on every review** — see whether a release caused a rating drop
- ✅ **Privacy by design** — optional anonymous `author_hash` only if you ask for it

> Need Google Play too, in one run? Use the combined [App Store & Google Play Reviews API](https://apify.com/steadyrow/app-reviews). This is the App Store-only version.

### What can I use it for?

- **Release monitoring** — watch the 1–2★ reviews after every version
- **Competitor benchmarking** — compare ratings and complaints across countries
- **Support and product tools** — push new negative reviews to Slack, Zendesk or Jira
- **AI pipelines** — sentiment analysis, topic clustering, LLM summaries over consistent JSON
- **ASO research** — what users in each country ask for

### Input

```json
{
    "apps": [
        "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
        "284882215"
    ],
    "countries": ["us", "gb", "de"],
    "ratings": ["1", "2"],
    "since": "30 days",
    "sort": "newest",
    "maxReviewsPerApp": 500
}
```

| Field | Description |
|---|---|
| `apps` | **Required.** App Store IDs or links, one per line. Apps from Google Play are skipped with a note in the log. |
| `countries` | Two-letter country codes. Default `us`. Every country is a separate request stream. |
| `sort` | `newest` (default) or `most_helpful`. Monitor mode always uses newest. |
| `ratings` | Star values to keep, e.g. `["1","2"]`. Empty = all. |
| `since` / `until` | `2026-10-01` or relative values such as `7 days`, `2 weeks`, `3 months`. |
| `maxReviewsPerApp` | Limit per app **per country** (max 500, Apple's feed depth). Default 200. |
| `monitorMode`, `monitorStateName` | Only return reviews not returned by an earlier run with the same name. |
| `includeAuthorHash` | Adds `author_hash`, a 12-character one-way hash of the reviewer account, to group reviews by the same author without any personal data. |
| `deduplicate` | Return each review once per run even if the app is listed twice (default on). |

### Output

```json
{
    "store": "app_store",
    "app_id": "324684580",
    "app_name": "Spotify: Music and Podcasts",
    "country": "us",
    "language": null,
    "review_id": "14685076517",
    "rating": 1,
    "title": "Freezing",
    "text": "The app always freezes and plays the same songs on dj mode",
    "app_version": "9.1.90",
    "review_date": "2026-10-19T11:19:04.000Z",
    "developer_reply": null,
    "reply_date": null,
    "thumbs_up": 0,
    "scraped_at": "2026-10-20T16:48:30.813Z"
}
```

App Store-specific notes:

- `title` is the headline the reviewer wrote (Google Play reviews have none).
- `thumbs_up` is the number of "helpful" votes.
- `developer_reply` and `reply_date` are always `null`: Apple's public feed does not include developer responses.
- `language` is `null` — App Store reviews belong to the country storefront.
- A run summary (reviews per app and country, errors) is saved to the key-value store under `OUTPUT`. An app that does not exist in a storefront is reported there and skipped; the rest still runs.

### Depth: up to ~500 reviews per country

Apple's public feed exposes about **500 reviews per country and sort order** (10 pages of 50). For more history, add more countries, or run both `newest` and `most_helpful`. In our tests 4 popular apps in 2 countries with ratings 1–2 and `most_helpful` returned 1,001 reviews, and a plain newest-first run returned 120 reviews per app and country as requested.

### Monitor mode

1. Turn on **Monitor mode** and run once: you get the latest reviews as a baseline.
2. Schedule the Actor (for example hourly or daily) with the same input.
3. Each later run returns **only new reviews**. With nothing new, the dataset is empty and you pay only the run start fee.

Each app × country is tracked separately in the key-value store `appstore-reviews-monitor` (change with `monitorStateName`). If more than `maxReviewsPerApp` reviews arrive between two runs, the oldest surplus is skipped — raise the limit or run more often for very popular apps. Tested: second run returned 0 reviews; after forgetting 6 reviews the third run returned exactly those 6.

### Pricing

| Event | Price |
|---|---|
| Review in the dataset | **$0.00025** ($0.25 per 1,000 reviews) |
| Actor start | $0.002 per run |

10,000 reviews ≈ $2.50. Reviews removed by your filters or already delivered in monitor mode are **not charged**. Set **Maximum cost per run** and the Actor stops cleanly when it is reached.

### FAQ

**Can I get reviews older than the latest 500?** Not from Apple's public feed. Combine countries and sort orders, and use monitor mode to keep a growing archive in your own storage.

**How fresh is the data?** Apple publishes reviews to the feed with a delay of up to about a day.

**Is it legal?** The Actor reads Apple's public review feed without logging in and does not collect reviewer names or profiles. You are responsible for using the data in line with Apple's terms and the laws that apply to you.

# Actor input Schema

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

App Store apps, one per line: a numeric ID (324684580), `id324684580`, or an apps.apple.com URL. Google Play packages are skipped (use the Google Play Reviews Scraper for those).

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

Two-letter country codes (us, gb, de, jp, ...). Every App Store country storefront has its own reviews, so each country is fetched separately. Default: us.

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

Newest first, or most helpful first. Monitor mode always uses newest.

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

Upper limit of reviews for each app in each country. Apple's public feed exposes at most ~500 reviews per country and sort order; to get more, add countries or run both sort orders.

## `ratings` (type: `array`):

Only return reviews with these star ratings. Leave empty for all.

## `since` (type: `string`):

Only reviews on or after this date. Absolute (2026-10-01) or relative (7 days, 2 weeks, 3 months).

## `until` (type: `string`):

Only reviews on or before this date. Absolute (2026-10-15) or relative (1 day).

## `monitorMode` (type: `boolean`):

Return only reviews that were not returned by a previous run with the same monitor name. The first run returns the latest reviews as a baseline. Ideal for scheduled runs, alerts and support dashboards.

## `monitorStateName` (type: `string`):

Name of the key-value store that remembers which reviews were already delivered. Use different names for independent monitors.

## `includeAuthorHash` (type: `boolean`):

Adds author_hash, a 12-character one-way hash of the reviewer's store account, so you can group reviews by the same author without any personal data. Reviewer names, profile links and avatars are never returned.

## `deduplicate` (type: `boolean`):

Return (and charge) each review only once per run, even if the same app is listed twice (e.g. as ID and URL).

## Actor input object example

```json
{
  "apps": [
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ],
  "countries": [
    "us"
  ],
  "sort": "newest",
  "maxReviewsPerApp": 100,
  "monitorMode": false,
  "monitorStateName": "appstore-reviews-monitor",
  "includeAuthorHash": false,
  "deduplicate": true
}
```

# Actor output Schema

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

All App Store reviews collected in this run, one row per review.

# 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"
    ],
    "countries": [
        "us"
    ],
    "maxReviewsPerApp": 100
};

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

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

```

## MCP server setup

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

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/O3d17VsmGyeXR38zm/builds/leZO4XBobkKWDpbCk/openapi.json
