# Apple App Store Reviews API – iOS Reviews & Ratings (`genial_candlestand/apple-app-store-reviews-api`) Actor

Extract public Apple App Store reviews as structured JSON across multiple apps and countries.

- **URL**: https://apify.com/genial\_candlestand/apple-app-store-reviews-api.md
- **Developed by:** [Flowo](https://apify.com/genial_candlestand) (community)
- **Categories:** Developer tools, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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?

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

## Apple App Store Reviews API

**Extract public App Store reviews from any iOS app as structured JSON.**

**Fast batch extraction — 1,000+ App Store reviews in seconds in typical workloads.**

✓ Ratings, titles, and review text\
✓ Authors, helpful votes, and optional reviewed-version enrichment\
✓ Multiple countries and multiple apps per run\
✓ Rating and date filters\
✓ API & MCP-friendly input/output\
✓ No Apple login or proxy required\
✓ Pay only for delivered reviews

Each review is a separate Dataset item, ready for JSON, CSV, Excel, XML, automations, and data pipelines.

Production verification on 128 MB runs delivered 1,200 reviews in 3.2–13.5 seconds. Actual runtime varies with Apple endpoint latency, storefront availability, filters, and optional version enrichment.

This is an independent, unofficial tool. It is not affiliated with, endorsed by, or sponsored by Apple Inc.

### Quick example

Input in Apify Console:

```json
{
  "apps": ["284882215"],
  "countries": ["us"],
  "maxReviews": 1000
}
```

Output item:

```json
{
  "reviewId": "1234567890",
  "appId": "284882215",
  "appName": "Facebook",
  "appUrl": "https://apps.apple.com/us/app/facebook/id284882215",
  "country": "us",
  "rating": 2,
  "title": "Needs improvement",
  "text": "The latest update keeps crashing...",
  "author": {
    "name": "John Doe",
    "id": "85038071"
  },
  "reviewedVersion": null,
  "date": "2026-08-31T17:22:00.000Z",
  "helpfulness": {
    "helpful": 5,
    "total": 7
  },
  "source": {
    "platform": "apple_app_store",
    "page": 1,
    "sort": "mostRecent"
  },
  "fetchedAt": "2026-09-04T07:15:32.000Z"
}
```

Unavailable optional Apple fields are returned as `null`; values are never invented.

### Input

Provide `apps`, `appNames`, or both. The two lists are combined and deduplicated.

The Console opens with Facebook (`284882215`), the US storefront, and 1,000 reviews per app–country pair prefilled. Replace or remove the sample App ID before running your own lookup; remove `us` if you want storefronts to be inferred from App Store URLs.

| Field | Type | Default | Description |
|---|---:|---:|---|
| `apps` | string\[] | — | Up to 20 numeric IDs, `id123` values, or full App Store URLs |
| `appNames` | string\[] | — | App names to resolve through Apple Search; each selected result is logged |
| `countries` | string\[] | `["us"]` | Up to 20 two-letter storefront codes; explicit values override URL storefronts |
| `maxReviews` | integer | `1000` | 1–10,000 reviews after filtering, per app × country |
| `sort` | string | `mostRecent` | `mostRecent` or `mostHelpful` |
| `ratings` | string\[] | all | Any combination of `"1"`–`"5"` |
| `since` | string | — | ISO 8601 date or timestamp; older reviews are excluded |
| `maxConcurrency` | integer | `5` | 1–20 concurrent app × country tasks |
| `includeReviewedVersion` | boolean | `false` | Enrich matching JSON reviews from RSS; increases Apple requests |

For example, two apps, three countries, and `maxReviews: 1000` can return up to 6,000 items. With `ratings: ["1"]`, the Actor keeps paging until it finds 1,000 one-star reviews per combination or reaches the end of Apple's feed.

The efficient default path uses Apple's JSON response only. Set `includeReviewedVersion: true` when the reviewed app version is important: the Actor then reads RSS lazily and joins versions by stable review ID. RSS enrichment is best-effort and never prevents an otherwise valid JSON review from being delivered.

IDs and URLs in `apps` are merged with Apple Search results from `appNames`, then deduplicated. A maximum of 20 app entries is accepted across both fields. Explicit `countries` always wins over storefronts inferred from URLs. Without explicit `countries`, all unique URL storefronts become the country set for the deduplicated apps; this is a cross-product, consistent with the app × country processing model.

When `appNames` is used, every resolution is explicit in the run log:

```text
Resolved appNames query -> "Spotify: Music and Podcasts" (324684580)
```

### JavaScript API example

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('<username>/apple-app-store-reviews-api').call({
    apps: ['284882215', '324684580'],
    countries: ['us', 'gb', 'de'],
    ratings: ['1', '2'],
    maxReviews: 1000,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Python API example

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("<username>/apple-app-store-reviews-api").call(run_input={
    "appNames": ["Spotify", "Netflix"],
    "countries": ["us", "gb"],
    "maxReviews": 1000,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### curl / REST API example

Start a run and wait for it to finish:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/<username>~apple-app-store-reviews-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"apps":["284882215"],"countries":["us","gb"],"maxReviews":1000}'
```

Dataset exports use Apify's native API. Add `format=csv`, `format=xlsx`, or `format=xml` to the Dataset items endpoint instead of maintaining a separate exporter.

### MCP and agent workflows

The descriptive input and output schemas make the Actor discoverable through Apify's MCP tooling. Agents can call it with direct fields such as `apps`, `countries`, `ratings`, and `since`; no opaque scraper-specific configuration is required. This is a normal finite Actor run, not a Standby MCP server.

### Pricing

The Actor uses Apify Pay Per Event with an Actor Start event and a `review` event.

**1 successfully delivered unique review = 1 billable event.**

The base pricing reference is **$0.00005 per Actor start** and **$1.00 per 1,000 reviews** ($0.001 per review). Paid-plan tier discounts may reduce the review price; the Pricing tab on the published Actor remains authoritative. `.actor/pay_per_event.json` mirrors the base Store configuration so repository readers do not mistake stale development pricing for production pricing. Failed requests, invalid apps, filtered reviews, duplicates, and apps with no reviews are not charged. A run-level maximum charge is respected; when it is reached, no additional item is written or billed.

Publication safety: configure the custom `review` event and remove/disable Apify's synthetic `apify-default-dataset-item` event. Enabling both would charge two events for the same Dataset item, so the Actor fails fast on Apify if it detects that configuration instead of processing reviews under ambiguous billing.

### Run summary

The `OUTPUT` record in the default Key-Value Store contains:

```json
{
  "appsRequested": 2,
  "countriesRequested": 3,
  "combinationsProcessed": 6,
  "reviewsFetched": 325,
  "reviewsOutput": 280,
  "duplicatesSkipped": 5,
  "filteredOut": 40,
  "noReviewCombinations": 0,
  "suspiciousEmptyFeeds": 0,
  "failedCombinations": 0,
  "durationMs": 2840,
  "chargeLimitReached": false
}
```

`reviewsFetched` counts parsed source reviews actually inspected before `maxReviews` or the charge limit stopped processing. Filtered and duplicate records are counted separately, and HTTP retries do not increment review counters.

### Use cases

- Feed public app feedback into product research, ASO, or competitor intelligence.
- Export recent low-rating reviews for manual triage.
- Prepare normalized review text for your own sentiment or RAG pipeline.
- Compare storefront feedback across countries.
- Use `since` in scheduled runs to limit work to a recent time window.

### Ready-made workflow catalog

The Actor includes 50 public Task configurations built around distinct user goals rather than aliases for individual input fields. Every Task has its own title, description, SEO metadata, editable input, example application, and `overview` Dataset view.

The public catalog covers exports, API access, rating filters, product research, monitoring, competitor analysis, country-specific extraction, sentiment analysis, RAG, and bulk datasets.

#### Export, API, and bulk extraction

1. **Export App Store Reviews to CSV**
2. **Export App Store Reviews to Excel**
3. **Get App Store Reviews as JSON**
4. **Get App Store Reviews via API**
5. **Scrape App Store Reviews by App URL**
6. **Scrape App Store Reviews by App ID**
7. **Download Latest App Store Reviews**
8. **Bulk Extract App Store Reviews**

CSV and Excel Tasks use Apify's native Dataset exports. They do not maintain a separate converter inside the Actor.

#### Rating, complaints, and product research

9. **Get 1-Star App Store Reviews**
10. **Get 2-Star App Store Reviews**
11. **Get Negative App Store Reviews (1–2 Stars)**
12. **Get 5-Star App Store Reviews**
13. **Get Positive App Store Reviews (4–5 Stars)**
14. **Get Most Helpful App Store Reviews**
15. **Find Customer Complaints in App Store Reviews**
16. **Collect App Reviews for Bug Analysis**
17. **Collect App Reviews for Feature Request Analysis**
18. **Collect App Reviews for Product Feedback Research**

Research Tasks collect structured source data. They do not classify complaints, bugs, feature requests, or sentiment themselves.

#### Monitoring and incremental collection

19. **Get Recent App Store Reviews Since a Date**
20. **Monitor New App Store Reviews**
21. **Track App Store Reviews After an App Update**
22. **Collect Reviews After a New App Release**
23. **Daily App Store Review Monitoring**
24. **Weekly App Store Review Monitoring**
25. **Build an Incremental App Store Review Feed**
26. **Sync Only New App Store Reviews**

For incremental operation, the caller stores the last successful timestamp and passes it back as `since` on the next run. Scheduling and checkpoint persistence remain explicit external workflow concerns.

#### Competitor intelligence

27. **Monitor Competitor App Store Reviews**
28. **Track Competitor 1-Star Reviews**
29. **Compare Reviews from Multiple iOS Apps**
30. **Bulk Scrape Competitor App Reviews**
31. **Build a Competitor App Review Dataset**
32. **Research Competitor Customer Complaints**
33. **Compare Customer Feedback Across Competing Apps**

#### Country and localization

34. **Get App Store Reviews by Country**
35. **Compare App Store Reviews Across Countries**
36. **Get US App Store Reviews**
37. **Get UK App Store Reviews**
38. **Get German App Store Reviews**
39. **Get French App Store Reviews**
40. **Get Japanese App Store Reviews**
41. **Get Canadian App Store Reviews**
42. **Get Australian App Store Reviews**
43. **Get Indian App Store Reviews**
44. **Get Brazilian App Store Reviews**
45. **Get Spanish App Store Reviews**
46. **Get Italian App Store Reviews**
47. **Get Ukrainian App Store Reviews**

Apple reviews are storefront-specific, so the country Tasks return genuinely different source datasets for the same application.

#### AI and data workflows

48. **Get App Store Reviews for Sentiment Analysis**
49. **Get App Store Reviews for RAG and LLM Analysis**
50. **Build an App Store Reviews Dataset for AI**

AI Tasks extract normalized text, ratings, dates, versions, and country metadata for downstream models. The Actor does not perform sentiment analysis, embeddings, RAG, or other AI processing.

### Limitations

- Apple does not offer an authenticated public reviews API for arbitrary third-party apps. The Actor uses Apple's iTunes WebObjects JSON response as its primary source and Customer Reviews RSS only as fallback or optional version enrichment. Neither reviews endpoint has a formal compatibility or availability guarantee.
- If both sources return zero items for an app whose storefront metadata reports many ratings, the combination is marked as a suspicious empty feed and failed instead of being reported as a trustworthy zero. It is counted in `OUTPUT.suspiciousEmptyFeeds` and is never charged.
- The primary JSON response does not expose the reviewed app version, so `reviewedVersion` is normally `null`. Enable `includeReviewedVersion` to populate it where RSS contains a matching review.
- Storefronts are independent. An app or its reviews may be available in one country and absent in another.
- Apple controls feed depth and page size; `maxReviews` is a ceiling, not a guarantee.
- Pagination has a hard safety cap of 100 JSON pages per app × country (up to 100 source reviews per page); RSS fallback has a 50-page cap. Rare rating filters can therefore return fewer selected reviews than `maxReviews` even when Apple has deeper history.
- Empty title or review-body strings returned by Apple are preserved as real empty strings. An unrecoverable malformed review is skipped when other valid reviews remain on the page; a page containing no valid review records is retried and then fails that combination.
- Rating filtering is local. `mostHelpful` follows Apple's feed order; no global `mostCritical` or `mostFavorable` order is claimed.
- `since` stops pagination early only with `mostRecent`; with `mostHelpful`, all available pages must be inspected.
- This MVP does not perform translation, sentiment analysis, summaries, alerts, monitoring state, or Google Play extraction.

### FAQ

#### Do I need an Apple developer account or App Store Connect token?

No. The Actor reads public storefront data and never accepts Apple credentials.

#### Do I need a proxy?

No. Requests go directly to Apple's public endpoints by default.

#### Does version enrichment triple the request count?

Only when you opt into it. The default path makes no RSS or App Store HTML requests: it uses one cached storefront lookup per country, application metadata lookup, and JSON pages of up to 100 reviews. With `includeReviewedVersion: true`, RSS adds up to roughly two 50-review requests for each full 100-review JSON page. Use enrichment only when per-review app versions are worth that extra traffic.

#### How are duplicates handled?

Within a run, `country + appId + reviewId` is unique. Duplicate feed entries are neither saved nor charged. A page containing only already-seen IDs terminates that pagination path.

#### What happens when one app or country fails?

Other app × country tasks continue. The failed combination is logged and counted in `OUTPUT.failedCombinations`.

#### Why did I receive fewer reviews than requested?

The storefront may have fewer exposed reviews, filters may exclude items, `since` may stop at the requested boundary, or the run charge limit may have been reached.

#### Can an empty Apple feed be mistaken for an app with no reviews?

The Actor does not trust a single empty response. It retries suspiciously empty JSON responses three times with backoff and then checks the independent RSS source. If both sources are still empty while metadata shows at least 10 ratings, the combination is reported as inconclusive in the run log and summary rather than silently returned as “no reviews.” Apps with fewer than 10 ratings can legitimately have no written reviews and are counted in `noReviewCombinations` when both sources are empty.

#### Are dates normalized?

Yes. Parseable Apple timestamps become ISO 8601 UTC strings. An unavailable or unparseable optional timestamp is `null`.

### Local development

Requires Node.js 22.12 or newer.

```bash
npm install
npm run typecheck
npm run lint
npm test
npm run build
```

Run locally with Apify CLI:

```bash
npx apify-cli run --input-file examples/input.json
```

Run live endpoint tests and the network benchmark explicitly:

```bash
npm run test:integration
npm run benchmark -- 100
```

Before publishing, choose **Pay per event** in Actor monetization settings, remove the automatically offered `apify-default-dataset-item` event, and configure Actor Start plus the custom `review` event from `.actor/pay_per_event.json`. This companion file mirrors the intended base prices, but the published Store pricing (including tier discounts) is configured in Apify Console and is authoritative. After every Store price change, update this file and its metadata test in the same change. Then deploy with `npx apify-cli push`.

### Data source and operational notes

Application metadata and name resolution use Apple's documented iTunes Search/Lookup API. Reviews use the iTunes WebObjects JSON response first because live checks show that Customer Reviews RSS can return an empty feed for storefronts that still have reviews; numeric storefront IDs are resolved dynamically and cached once per country. RSS is called after empty/failed JSON or when `includeReviewedVersion` explicitly enables best-effort enrichment. Both review endpoints are undocumented and may change. For an unfiltered request smaller than 100 reviews, the JSON page size is reduced to avoid downloading unused items. Filtered reviews are delivered to the Dataset and charged in page-sized batches rather than one SDK request per item; the global billing queue and SDK prefix trimming preserve run charge limits across concurrent app/storefront tasks. HTTP requests have a 15-second timeout, three attempts for transient failures (429, 5xx, timeouts, connection errors, and malformed HTTP 200 payloads), exponential backoff with jitter, and no browser dependency. Response bodies are capped at 1 MiB for Search/storefront metadata, 5 MiB for RSS, and 10 MiB for review JSON; oversized responses fail without retry.

# Actor input Schema

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

Add up to 20 numeric App Store IDs, id-prefixed IDs, or full apps.apple.com URLs. Replace the prefilled Facebook ID, or remove it to use only app-name search. URL storefronts are used when Storefront countries is empty; duplicate apps are removed automatically.

## `appNames` (type: `array`):

Add up to 20 app names. For each name, the first Apple software search result is used and logged. Results are combined with Apps and duplicates are removed.

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

Select common storefronts or enter any two-letter App Store country code. United States is prefilled; remove it to use storefronts found in Apps URLs.

## `maxReviews` (type: `integer`):

Maximum delivered reviews after filters for each app × country pair. For example, 2 apps × 3 countries × 1,000 can return up to 6,000 billable reviews.

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

Newest first is fastest with a date boundary. Most helpful follows Apple's helpfulness order and may need to scan more pages.

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

Select one or more ratings. Leave empty to include all ratings; the review limit is counted after filtering.

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

Choose the earliest review date. Leave empty for all available dates. Full ISO timestamps remain accepted in JSON and API input.

## `includeReviewedVersion` (type: `boolean`):

Also query Apple RSS to populate reviewedVersion where matching data exists. This increases Apple requests but never blocks delivery of otherwise valid reviews.

## `maxConcurrency` (type: `integer`):

Maximum number of app × country combinations processed at once.

## Actor input object example

```json
{
  "apps": [
    "284882215"
  ],
  "countries": [
    "us",
    "gb"
  ],
  "maxReviews": 1000,
  "sort": "mostRecent",
  "ratings": [
    "1",
    "2"
  ],
  "since": "2026-08-01",
  "includeReviewedVersion": false,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `reviews` (type: `string`):

One normalized App Store review per Dataset item.

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

Counts for requested apps, processed combinations, fetched/output/filtered reviews, duplicates, confirmed no-review combinations, suspicious empty feeds, and failures.

# 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": [
        "284882215"
    ],
    "countries": [
        "us"
    ],
    "maxReviews": 1000,
    "maxConcurrency": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("genial_candlestand/apple-app-store-reviews-api").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": ["284882215"],
    "countries": ["us"],
    "maxReviews": 1000,
    "maxConcurrency": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("genial_candlestand/apple-app-store-reviews-api").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": [
    "284882215"
  ],
  "countries": [
    "us"
  ],
  "maxReviews": 1000,
  "maxConcurrency": 5
}' |
apify call genial_candlestand/apple-app-store-reviews-api --silent --output-dataset

```

## MCP server setup

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

```

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/xEPijHGY6xtiBzzpB/builds/vdM9g0S2JMJpnZgBY/openapi.json
