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

Apple publishes the app version on every review and nobody joins on it. This does: per-release rating distribution, so you can see exactly which update tanked your rating, plus conservative regression detection. Multi-country.

- **URL**: https://apify.com/datalayer/app-store-reviews.md
- **Developed by:** [Datalayer](https://apify.com/datalayer) (community)
- **Categories:** Social media, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 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

## App Store Review Scraper — with version tracking

Scrape **App Store reviews** and see which app version each review was written against. Get per-release rating breakdowns and automatic regression detection, so you can answer the question every mobile team actually asks: **did the release we just shipped make things worse?**

### Why this one is different

Every App Store review scraper hands you a flat list of reviews. That tells you people are unhappy. It does not tell you *when it started* or *what caused it*.

Apple publishes the app version on every review. Almost nobody uses it. This actor joins reviews to releases and gives you:

- **Rating per version** — the full 1-to-5 distribution for every release
- **Negative share** — the percentage of 1 and 2 star reviews per version, which is the number that moves first
- **Regression detection** — an automatic comparison of the newest release against the one before it

A drop from 4.6 to 4.1 across a release, with 1-star reviews tripling, is a shipped bug. In a flat review list that is invisible.

### What you get

**Review rows** — rating, headline, body, author, date, the app version it was written against, and whether that version is currently live.

**Version rows** — one per release: review count, average rating, full star distribution, negative share, and the date range those reviews cover.

**Delta rows** — newest release versus previous: rating change, negative-share change, sample sizes, and a `regression` flag.

The regression flag is deliberately conservative. It only fires when the rating dropped meaningfully **and** the share of 1-2 star reviews rose. A single angry reviewer will not trigger it.

### Input

```json
{
  "appIds": ["324684580"],
  "countries": ["us", "gb"],
  "maxPages": 3,
  "includeVersionSummary": true
}
```

**App IDs** — the digits after `/id` in an App Store URL. Paste the whole URL if easier; the ID gets extracted.

**Countries** — each country store holds its own reviews. A bug affecting one locale shows up in one store first.

**Pages** — 50 reviews each. Apple caps its public feed at 10 pages (500 reviews) per country, and the actor clamps to that rather than silently looping.

**Rating filters** — set `maxRating: 2` to pull only complaints, which is the fastest way to find what broke.

### Use cases

- **Release monitoring** — schedule daily and get alerted when a version regresses
- **Competitive teardown** — track a rival's ratings release by release
- **Support triage** — filter to 1-2 star reviews on the current version to see live problems
- **Pre-launch research** — read what users hate about the incumbent before you build

### Reliability

One app or country failing never fails the run. If you track twenty apps and one is unavailable in one store, you get the other nineteen plus a record of what failed and why. You are only charged for rows actually returned.

Wrong app IDs produce a clear message telling you where to find the right one, rather than an empty dataset.

Data comes from Apple's public review feed — no login, no browser automation. Note that Apple's feed exposes recent reviews only; it is not a complete historical archive, and this actor does not pretend otherwise.

### Notes

Unofficial and not affiliated with Apple. Review text remains the property of its authors — use it in line with applicable laws and terms.

# Actor input Schema

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

The digits after /id in an App Store URL. You can paste the full URL and the ID will be extracted.

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

Two-letter store codes, for example us, gb, au, de. Each country has its own reviews.

## `minRating` (type: `integer`):

Keep only reviews at or above this rating.

## `maxRating` (type: `integer`):

Keep only reviews at or below this rating. Set to 2 to see just the complaints.

## `includeVersionSummary` (type: `boolean`):

Adds one row per app version with its rating distribution, plus a regression check comparing the newest release against the one before it.

## `maxPages` (type: `integer`):

50 reviews per page. Apple caps its public feed at 10 pages (500 reviews) per country. Fewer than about 5 pages on a busy app often returns only the current version, which leaves nothing to compare against.

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

Optional. Apple's public review feed generally does not require a proxy.

## Actor input object example

```json
{
  "appIds": [
    "324684580",
    "544007664"
  ],
  "countries": [
    "us",
    "gb"
  ],
  "includeVersionSummary": true,
  "maxPages": 6,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `all` (type: `string`):

Reviews, version summaries and regression checks.

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

Individual reviews with the app version each was written against.

## `versions` (type: `string`):

Rating distribution per app version, newest first.

## `csv` (type: `string`):

Everything as a CSV download.

## `runSummary` (type: `string`):

Counts and any app that could not be reached.

# 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 = {
    "appIds": [
        "324684580",
        "544007664"
    ],
    "countries": [
        "us",
        "gb"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datalayer/app-store-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 = {
    "appIds": [
        "324684580",
        "544007664",
    ],
    "countries": [
        "us",
        "gb",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("datalayer/app-store-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 '{
  "appIds": [
    "324684580",
    "544007664"
  ],
  "countries": [
    "us",
    "gb"
  ]
}' |
apify call datalayer/app-store-reviews --silent --output-dataset

```

## MCP server setup

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