# App Store Reviews Scraper - iOS App Reviews $0.10 per 1K (`santhej/app-store-reviews-scraper`) Actor

Scrape Apple App Store reviews for any iOS app: star rating, title, review text, real timestamps, app version, reviewer name and helpful votes, plus an app-level summary with the store rating and total review count. Any storefront, bulk apps by ID or URL. $0.10 per 1,000 reviews.

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

## Pricing

Pay per event

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## App Store Reviews Scraper — $0.10 per 1,000 Reviews

**Pull Apple App Store reviews for any list of iOS apps — star rating, headline, full text, the exact timestamp down to the second, app version, reviewer name, reviewer profile link and helpful-vote counts — as clean JSON or CSV.**

App Store reviews are the rawest product feedback there is: what users love, what crashes, and why they churn — written the day it happened. They are also your competitor's roadmap in public. This Actor takes App Store IDs or URLs in bulk, scrapes reviews from any storefront, and returns one tidy row per review plus a rich summary row per app.

No API keys, no proxies, no setup — paste app IDs and run.

### What you get per review

| Field | What it tells you |
|---|---|
| `rating` | Star rating (1-5) the reviewer gave |
| `title` | The review headline — iOS reviews have real titles, and they are often the whole complaint |
| `text` | The review itself, in full |
| `date` | When it was posted — **strict ISO 8601 UTC with a real time of day** (`2026-08-24T01:28:09.000Z`), so pandas, BigQuery, Sheets and `datetime.fromisoformat` parse it with no clean-up step |
| `date_raw` | Apple's original timestamp, offset intact (`2026-08-23T18:28:09-07:00`) — the reviewer's local wall-clock time |
| `app_version` | Which release the reviewer was on — pin a complaint to a build |
| `author` | Reviewer's public nickname |
| `author_url` | Link to that reviewer's public profile — spot repeat reviewers and review rings |
| `review_url` | Apple's link back to the app's review page on the store |
| `helpful_votes` | Net helpful score — up-votes minus down-votes, so a divisive review can go negative |
| `helpful_count` | How many people voted on the review at all — the reach of that opinion |
| `review_id` | Stable id for deduping across scheduled runs |
| `country` / `language` | The storefront the review was read from |
| `scraped_at` | When this run collected the row |

### What makes this different

- **Real timestamps, not zeroed dates.** Every review carries the actual minute and second it was posted. A lot of App Store review tools hand you `00:00:00` on every single row, which quietly destroys any per-hour or per-release-window analysis.
- **Helpful votes, populated.** `helpful_votes` and `helpful_count` are numbers on every row, never null, so you can rank reviews by how much other users agreed instead of reading 500 of them in date order. (Reviews posted in the last few hours honestly start at `0` — nobody has voted on them yet. Set `sortBy` to `most_helpful` to surface the ones that have accumulated real vote counts.)
- **A genuinely useful `app_summary` row.** Most review scrapers return reviews and nothing else. Every run here also emits one summary row per app with the store rating, total ratings count, current-version rating, developer, seller, genre, current version, release and last-updated dates, content rating, price, size, supported languages, icon URL and release notes. One run gives you the reviews *and* the context to interpret them.
- **No dead columns.** Apple's public review data has no developer replies, so this Actor does not ship an always-empty `developer_reply` column pretending otherwise. Every field in the schema is a field Apple actually fills.
- **Sort by most helpful.** Switch `sortBy` to `most_helpful` to get the reviews the community voted up, not just the newest ones.

### Use cases

- **Review mining** — feed thousands of reviews to an LLM and extract feature requests, bugs and churn reasons.
- **Competitor analysis** — scrape rivals' newest reviews and read their roadmap in their 1-star complaints.
- **ASO monitoring** — track rating trends and review velocity per release, per storefront.
- **Release regression alerts** — a spike of 1-star reviews pinned to `app_version` is your earliest crash signal.
- **Reputation triage** — sort by `helpful_votes` and answer the complaints that most users actually saw.
- **Localization research** — compare what users praise in the US, German and Japanese storefronts before you translate.
- **Client reporting** — a dated, exportable record of app sentiment for agencies and studios.

### Pricing

Pay per result. No monthly fee, no setup fee, no minimum.

| Event | Price |
|---|---|
| Actor start | $0.001 per run |
| Review scraped | **$0.0001 — that is $0.10 per 1,000 reviews** |

Worked example: scraping 150 reviews each for 10 apps returns 1,500 reviews and costs **$0.001 + 1,500 × $0.0001 = $0.151**. Pulling the full 500-review ceiling for a single app costs **$0.051**. You are billed only for reviews actually returned — an app that fails, is not on that storefront, or returns nothing is not charged at all.

### Input example

```json
{
  "apps": [
    "310633997",
    "https://apps.apple.com/us/app/telegram-messenger/id686449807"
  ],
  "maxReviewsPerApp": 150,
  "sortBy": "most_recent",
  "countryCode": "us",
  "languageCode": "en"
}
```

### Output example

```json
{
  "record_type": "review",
  "app_id": "324684580",
  "review_id": "14464651610",
  "rating": 5,
  "title": "Sound selection is perfect.",
  "text": "I can listen to my favorite artist and songs. And the sound quality is on TOP.",
  "date": "2026-08-24T01:28:09.000Z",
  "date_raw": "2026-08-23T18:28:09-07:00",
  "app_version": "9.1.76",
  "author": "Stephen.I'm cool",
  "author_url": "https://itunes.apple.com/us/reviews/id1849973763",
  "review_url": "https://itunes.apple.com/us/review?id=324684580&type=Purple%20Software",
  "helpful_votes": 0,
  "helpful_count": 0,
  "country": "us",
  "language": "en",
  "scraped_at": "2026-08-25T06:10:00.000Z"
}
```

Plus one `app_summary` row per app:

```json
{
  "record_type": "app_summary",
  "app_id": "324684580",
  "app_title": "Spotify: Music and Podcasts",
  "app_url": "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
  "bundle_id": "com.spotify.client",
  "app_version": "9.1.76",
  "developer": "Spotify",
  "seller": "Spotify AB",
  "genre": "Music",
  "genres": ["Music", "Entertainment"],
  "app_rating": 4.775,
  "total_ratings_on_store": 41712246,
  "app_rating_current_version": 4.775,
  "total_ratings_current_version": 41712246,
  "released_at": "2011-07-14T20:31:24Z",
  "updated_at": "2026-08-18T13:24:11Z",
  "content_rating": "12+",
  "price": 0,
  "currency": "USD",
  "size_mb": 216.4,
  "supported_languages": ["EN", "DE", "FR", "JA"],
  "icon_url": "https://is1-ssl.mzstatic.com/image/thumb/.../512x512bb.jpg",
  "reviews_scraped": 150,
  "reviews_requested": 150,
  "pages_fetched": 3,
  "pages_unavailable": 0,
  "sort_by": "most_recent",
  "country": "us",
  "storefront": "United States",
  "language": "en",
  "scraped_at": "2026-08-25T06:10:00.000Z"
}
```

### FAQ

**Do I need an API key or proxies?** No. Everything is handled for you — no API keys, no accounts, no proxy setup. Paste app IDs and run.

**What can I put in the `apps` field?** Either a bare numeric App Store id (`310633997`) or any full App Store URL — the `id…` segment is parsed out automatically. Up to 100 apps per run.

**Why does it cap at 500 reviews per app?** Because that is Apple's own hard ceiling. The public review feed serves at most 10 pages of 50 reviews per app per storefront, then answers `page depth is limited to 10`. Nobody can return more than 500 for a single app on a single storefront in one pass — anyone claiming otherwise is either counting across storefronts or repeating a scheduled run. Two ways to get more: scrape the same app across several storefronts, or run on a schedule and dedupe on `review_id` to accumulate history over time.

**What format are the dates in?** `date` is strict ISO 8601 UTC — `2026-08-24T01:28:09.000Z` — with a real hour, minute and second, so `pd.to_datetime`, `datetime.fromisoformat`, BigQuery, Postgres and Google Sheets all read it directly. `date_raw` keeps Apple's original offset-bearing string if you want the reviewer's local time.

**What is the difference between `helpful_votes` and `helpful_count`?** `helpful_count` is how many people voted on the review; `helpful_votes` is the net score after down-votes are subtracted, so it can be negative on a review people disagreed with. Sort by `helpful_votes` for consensus, by `helpful_count` for reach.

**Are developer replies included?** No — Apple does not publish developer responses in its public review data, so there is no such column here. Shipping a column that is null on 100% of rows just looks broken. (Our [Google Play sibling](https://apify.com/santhej/google-play-reviews-scraper) does return them, because Google does publish them.)

**Does `review_url` link to one specific review?** It links to the app's review page on the store. Apple does not mint a public per-review permalink for App Store reviews, so no tool can give you one — `author_url`, which does point at that specific reviewer's profile, is the per-row link that actually resolves.

**Which countries work?** All App Store storefronts — pass any two-letter country code (`us`, `gb`, `de`, `in`, `br`, `jp`, ...). Reviews are storefront-specific, so scrape each market you care about separately.

**What happens if one app fails?** It gets an `error` row explaining why, is not billed, and the rest of the run continues. One bad app id never kills the batch.

**Some runs return slightly fewer reviews than I asked for. Why?** Apple's public review feed occasionally serves a page with no data. The Actor retries each page several times on rotating IPs and reports exactly what happened in `pages_fetched` and `pages_unavailable` on the `app_summary` row. You are only ever billed for reviews you actually received.

**Can I export it?** Yes — JSON, CSV, Excel, or straight into n8n, Make or Zapier via the Apify API.

### Related actors

- [Google Play Reviews Scraper](https://apify.com/santhej/google-play-reviews-scraper) — the same output shape for Android apps; run both and diff sentiment across platforms.
- [ASO Rank Tracker](https://apify.com/santhej/aso-rank-tracker) — track where your app ranks for its keywords on both stores.

***

*Tags: app store reviews scraper, ios app reviews, apple app store scraper, app reviews api, app review export, review mining, aso tool, app store optimization, app feedback analysis, competitor app reviews, iphone app reviews, bulk review scraper*

# Actor input Schema

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

The App Store apps to scrape reviews for. Accepts a numeric app id (310633997) or a full App Store URL (https://apps.apple.com/us/app/whatsapp-messenger/id310633997). Up to 100 apps per run.

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

How many reviews to fetch for each app (10-500). 500 is Apple's own hard ceiling on the public review feed — it serves at most 10 pages of 50 reviews per app per storefront. You are billed only for reviews actually returned.

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

Most recent returns the newest reviews first — best for release monitoring and alerting. Most helpful returns the reviews other users voted up most — best for understanding what the loudest sentiment about an app actually is.

## `countryCode` (type: `string`):

Two-letter ISO 3166-1 country code of the App Store storefront to read reviews from, e.g. us, gb, de, in, br. All storefronts supported. Reviews are storefront-specific — scrape each market separately to compare them.

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

Two-letter language code (ISO 639-1) stamped onto every output row so multi-storefront runs stay easy to filter downstream. Apple's public review feed has no language filter — reviews come back in whatever language the reviewer wrote them in — so this is a label, not a filter.

## `proxyConfiguration` (type: `object`):

Apple rate-limits its public review feed per client, so requests are routed through Apify Proxy with a fresh IP per attempt. Leave the default unless you have a reason to change it.

## Actor input object example

```json
{
  "apps": [
    "310633997"
  ],
  "maxReviewsPerApp": 150,
  "sortBy": "most_recent",
  "countryCode": "us",
  "languageCode": "en",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per review, plus one app\_summary row per app.

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

Apps scraped, review counts, billing breakdown and net margin for the run.

# 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": [
        "310633997"
    ],
    "maxReviewsPerApp": 150,
    "sortBy": "most_recent",
    "countryCode": "us",
    "languageCode": "en",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("santhej/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": ["310633997"],
    "maxReviewsPerApp": 150,
    "sortBy": "most_recent",
    "countryCode": "us",
    "languageCode": "en",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("santhej/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": [
    "310633997"
  ],
  "maxReviewsPerApp": 150,
  "sortBy": "most_recent",
  "countryCode": "us",
  "languageCode": "en",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call santhej/app-store-reviews-scraper --silent --output-dataset

```

## MCP server setup

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