# App Store Reviews Scraper Pro (`goldenbios/my-actor-3`) Actor

Extract Apple App Store reviews with ratings, titles, full text, dates and helpfulness votes. Filter by date and rating, sort by most recent or most helpful, choose any storefront country, and get a per-app analytics summary with the full star distribution.

- **URL**: https://apify.com/goldenbios/my-actor-3.md
- **Developed by:** [Goldenbios](https://apify.com/goldenbios) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 results

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 Pro

Extract **App Store reviews** for any iOS app — author, star rating, headline, full text, date, helpful-vote count, and the app version reviewed. Any storefront country, newest-first or most-helpful order; filter by date range or rating range. Every app ends with a summary item that accounts honestly for what was fetched, emitted, and filtered, with the 1–5 star distribution of the result set.

The iOS twin of **Google Play Reviews Scraper Pro** — same inputs, same summary, same flat per-review pricing. Scrape both stores with one mental model.

Built for app developers doing ASO and review mining, support teams tracking complaints after a release, and market researchers comparing competitors' ratings over time.

### Why this actor?

|  | App Store Reviews Scraper Pro | The App Store reviews niche |
| --- | --- | --- |
| Price | **Flat per review** (see the Pricing tab) — no subscription | Mixed, mostly opaque per-run or subscription pricing |
| Small jobs | 2,000 reviews cost pocket change, once | Minimums and monthly plans punish one-off jobs |
| Date range filter | **Yes** — start and end date, with early stop on newest sort | Rare |
| Rating range filter | **Yes** — min and max stars | Rare |
| Storefronts | **Any country storefront** in one run's inputs | Often US-only or one storefront per run |
| Per-app summary | Fetched / emitted / filtered + average rating + 1–5 star distribution | Usually absent |
| Minimums / start fees | **None** | Common |

### What it extracts (per review)

| Field | Description |
| --- | --- |
| `authorName` | Review author's display name |
| `rating` | Star rating, 1–5 |
| `title` | The review's headline |
| `text` | Full review text (`null` when Apple carries no body) |
| `reviewDate` | When the review was posted, ISO 8601 UTC |
| `voteCount` | How many users found the review helpful |
| `appVersion` | The app version the review was written against, when Apple knows it |
| `reviewId` | Apple's unique id for the review |
| `appId` | The numeric App Store id the review belongs to |
| `country` | The storefront the review was fetched from |

### Inputs

| Input | Type | Default | Description |
| --- | --- | --- | --- |
| `appIds` | string list | — | Numeric App Store ids (`324684580`) and/or App Store URLs — the `/id` number is read from URLs |
| `country` | string | `us` | Storefront country (2 letters) — Apple serves each storefront's own review stream |
| `maxReviewsPerApp` | integer | 100 | Cap on reviews emitted per app, after filters (Apple's feed itself caps at ~500 per sort — see Honest limits) |
| `sortOrder` | select | `mostRecent` | `mostRecent` (newest first) or `mostHelpful` (helpful votes first) — the two orders Apple's public feed offers |
| `reviewsStartDate` / `reviewsEndDate` | date | — | Keep reviews inside this window (inclusive, UTC) |
| `minRating` / `maxRating` | number | — | Keep reviews inside this star range |
| `includeSummary` | boolean | true | Emit one summary item per app |
| `proxyConfiguration` | proxy | Apify Proxy | Standard Apify Proxy is normally enough; RESIDENTIAL is the fallback for repeated 403s |

### Outputs

Three item types share one dataset, told apart by the `type` field:

- **`review`** — one per review, fields as in the table above.
- **`summary`** — one per app: `fetchedCount`, `emittedCount`, `filteredOutCount`, `averageRating`, `ratingDistribution` (emitted reviews per star), and `stoppedReason` (`resultsExhausted`, `maxReviewsReached`, `dateRangePassed`, `fetchSafetyCapReached`, `appFailed`). The identity `fetched = emitted + filtered` always holds, so you can see exactly what your filters cost you.
- **`error`** — one per failed app, with the reason; if every app fails, the run itself is marked failed rather than returning an empty success.

### Recipes

**Release damage check.** App: your own id. `sortOrder: mostRecent`, `reviewsStartDate:` the release date, `maxRating: 2`. You get exactly the angry reviews since the update, and the summary's distribution shows the damage shape.

**Both stores, one spreadsheet.** Run this actor and Google Play Reviews Scraper Pro on the same app, same date window. Same field names, same summary shape — the two datasets merge directly.

**Local market pulse.** Same app id, one run per storefront (`country: fr`, then `de`, then `jp`). Ratings and complaints differ by market; the per-app summaries compare directly.

**Most helpful, not just newest.** `sortOrder: mostHelpful`, `maxReviewsPerApp: 100` — the reviews other users actually read, ranked by helpful votes.

### FAQ

**How much does a typical job cost?** Pricing is flat per review with no subscription and no start fee — see the Pricing tab. 10,000 reviews across 5 apps is one run, one per-review charge, nothing monthly.

**Can it get ALL reviews of a huge app?** No — and nobody can from Apple's public feed: it exposes at most ~500 reviews per app per sort order (the 500 newest and the 500 most helpful). The summary tells you exactly how many were fetched. See Honest limits.

**Why did my summary come back with 0 reviews?** Either the app has no reviews in that storefront, or the app id doesn't exist there — Apple's feed answers both cases identically (an empty feed), so double-check the id and the `country` input.

**Why is a review I see in the App Store missing?** Reviews live per storefront. A review written in the French storefront is not in the US feed. Match the `country` input to the storefront you are looking at, or run once per storefront.

**Does it need my Apple account?** No. Reviews are read from Apple's public customer reviews feed; there is no login and nothing to connect.

### Honest limits

- **~500 reviews per app per sort order, hard cap.** Apple's public feed serves pages 1–10 only (50 reviews per page), for `mostRecent` and for `mostHelpful`. That is a window onto the app's most visible reviews, not its full history. The summary's `fetchedCount` states plainly how far the window reached.
- **Per-storefront streams.** The feed serves one storefront's reviews at a time. Reviews are never mixed across countries by Apple; scrape each storefront separately if you need several markets.
- **No developer responses.** The public feed does not include the developer's response to a review, so no reply fields exist in the output (the Google Play sibling has them because Play's backend carries them).
- **Empty feed ambiguity.** An unknown app id and an app with zero reviews in a storefront return the same empty feed from Apple. The actor reports a zero-count summary rather than guessing which case it was.
- **`reviewDate` is the review's last-updated time** — Apple exposes one timestamp per review in this feed (posting or last edit); there is no separate edit history.
- Apple occasionally reshapes its feed; the parser reads the feed's `label` fields defensively and emits `null` rather than guessing when a field is absent.

# Actor input Schema

## `appIds` (type: `array`):

iOS apps to scrape reviews from: numeric App Store ids (e.g. 324684580) and/or App Store URLs (the /id number is read from the URL). Each app is processed in order.

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

2-letter App Store storefront country, e.g. us, fr, de, gb, jp. Apple serves each storefront's own review stream; reviews written in other countries are not mixed in.

## `includeSummary` (type: `boolean`):

Emit one summary item per app: reviews fetched, emitted, filtered out, average rating, the 1-5 star distribution, and why fetching stopped.

## `maxRating` (type: `number`):

Only reviews with at most this star rating (1-5).

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

Maximum reviews emitted per app, after filters. Note Apple's public feed itself caps at about 500 reviews per app per sort order (10 pages of 50).

## `minRating` (type: `number`):

Only reviews with at least this star rating (1-5).

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

Apple's reviews feed is a public web endpoint. Apify Proxy (standard) is the prepared default and is normally enough; switch to RESIDENTIAL only if you see repeated HTTP 403 errors. You pay only your own run's proxy usage; traffic is one small request per 50 reviews.

## `reviewsEndDate` (type: `string`):

Only reviews dated on or before this day (inclusive, UTC).

## `reviewsStartDate` (type: `string`):

Only reviews dated on or after this day (inclusive, UTC). With the mostRecent sort order, fetching stops as soon as the feed passes this date.

## `sortOrder` (type: `string`):

Review order served by Apple's feed: mostRecent (newest first) or mostHelpful (most helpful votes first). These are the only two orders the public feed offers.

## Actor input object example

```json
{
  "appIds": [],
  "country": "us",
  "includeSummary": true,
  "maxReviewsPerApp": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "sortOrder": "mostRecent"
}
```

# Actor output Schema

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

Default dataset containing review items and per-app summary items.

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("goldenbios/my-actor-3").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 = { "proxyConfiguration": { "useApifyProxy": True } }

# Run the Actor and wait for it to finish
run = client.actor("goldenbios/my-actor-3").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 '{
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call goldenbios/my-actor-3 --silent --output-dataset

```

## MCP server setup

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

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/9QddGGUv1PdDusV1b/builds/QRkG0Bwp94gQ7qnUa/openapi.json
