# App Store Reviews Scraper — Multi-Country, Deep History (`tactful_anvil/app-store-reviews-scraper-multi-country-deep-history`) Actor

Scrape Apple App Store reviews from any country — recent feed + deep helpful-ranked history, deduplicated. Star, keyword and date filters, free rating histogram summary, appVersion per review. Pay per result: $0.08/1,000 reviews.

- **URL**: https://apify.com/tactful\_anvil/app-store-reviews-scraper-multi-country-deep-history.md
- **Developed by:** [Mr Zack](https://apify.com/tactful_anvil) (community)
- **Categories:** Developer tools, Automation, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.08 / 1,000 review 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?

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 — Multi-Country, Deep History, $0.08/1,000

Scrape **Apple App Store reviews** as clean structured data: rating, title, text, reviewer, date, app version, helpful votes — for **any app, across any storefront countries, in one run**.

Two public sources, merged and deduplicated automatically:

- **Chronological feed** — the newest reviews first (best for monitoring; includes the **app version** each review was written on and helpful-vote counts).
- **Deep history** — the App Store's own helpful-ranked review corpus, paginated far beyond the ~500-review limit of the chronological feed.

Duplicates across the two sources are detected by review ID and **never charged**. HTTP-only — no login, no API key, no browser, so runs finish in seconds and cost cents.

### Who is this for?

- **App developers & product teams** — monitor your own reviews daily, catch a review-bombing wave or a broken release (`starsFilter: "negative"` + `newerThanDays: 1` on a schedule).
- **ASO agencies** — complaint mining across a client's competitors: what do 1–2★ users say, which versions triggered the anger, how does the rating histogram compare per country.
- **Competitor & market research** — pull the review corpus of any app per storefront, with the all-time rating histogram free in every run.
- **AI agents (MCP)** — *"Get the last 30 days of negative reviews of app X in the US and Germany and summarize the top complaints"* becomes one tool call.

### Output (one item per review)

| Field | Example | Notes |
| --- | --- | --- |
| `appId` | `389801252` | numeric App Store ID |
| `appName` | `Instagram` | from free metadata lookup |
| `country` | `us` | storefront |
| `reviewId` | `14465707646` | stable — safe for dedupe across runs |
| `rating` | `2` | 1–5 |
| `title` | `Support never answers` | |
| `text` | `I wouldn't be writing this review if…` | full review body |
| `reviewedAt` | `2026-08-24T09:06:04.000Z` | ISO, normalized to UTC |
| `reviewAgeDays` | `1.4` | freshness at scrape time |
| `isNegative` | `true` | 1–2★ convenience flag |
| `appVersion` | `443.1.0` | version reviewed — feed rows only |
| `voteSum` / `voteCount` | `3` / `4` | helpful votes — feed rows only |
| `isEdited` | `false` | deep-history rows only |
| `userName` | `norge 2` | |
| `source` | `recent` | `recent` (feed) or `helpful` (deep history) |

Anything Apple doesn't publish for a given row comes back `null` — never a fabricated zero.

**Free with every run** (key-value store → `SUMMARY`, not charged): per app per country — the **all-time rating histogram** (1★…5★ counts), average rating, total rating count, **% negative all-time**, developer name, genre, plus window stats for what you scraped (average rating, oldest/newest, per-source counts, duplicates skipped).

### Input highlights

- `apps` — App Store URLs or numeric IDs, one or more.
- `countries` — e.g. `["us", "gb", "de", "jp"]`. Each app × each country in one run.
- `source` — `both` (default), `recent` (chronological only), `helpful` (deep history only).
- `starsFilter` — `all`, `1`–`5`, `negative` (1–2★), `positive` (4–5★). Skipped reviews are **not charged**.
- `newerThanDays` — with the chronological feed the run stops at the first older review: scheduled monitoring costs cents.
- `filterKeyword` — only keep reviews mentioning a word/phrase (checked in title + text). Skipped reviews are **not charged**.
- `maxReviewsPerApp` — hard cost cap per app per country.

#### Example: daily complaint monitor, two countries

```json
{
  "apps": ["https://apps.apple.com/us/app/instagram/id389801252"],
  "countries": ["us", "gb"],
  "source": "recent",
  "starsFilter": "negative",
  "newerThanDays": 1,
  "maxReviewsPerApp": 200
}
```

Every 1–2★ review from the last 24 hours in both storefronts — typically a few cents per day.

### How to schedule this Actor (recommended setup)

Reviews are a feed, not an archive: a bad release shows up in hours, and App Store replies work best within a day. A scheduled run is how you catch that window.

1. Run the Actor once with the input you want and check the results.
2. On the Actor page open the **⋯** menu and choose **Schedule Actor** (or go to [Schedules](https://console.apify.com/schedules) and click **Create new**).
3. Set the cron expression:
   - `0 7 * * *` — every morning. The right default for review monitoring.
   - `0 */6 * * *` — every 6 hours. Use during a rocky release week.
   - `0 7 * * 1` — weekly digest. Cheapest useful cadence for competitor tracking.
4. Attach the saved input. With `newerThanDays` set, each scheduled run only pays for what's actually new.
5. Add an integration so you don't have to check manually: **Integrations** → **Slack / Webhook / Google Sheets / Zapier / Make**, triggered on *Run succeeded*. Fresh reviews arrive on their own.

**Tracking Android too?** Pair this with our [Google Play Reviews Scraper](https://apify.com/tactful_anvil/google-play-reviews-scraper) — same $0.08/1,000 pricing, same input style, so one schedule pair covers both stores.

### Why this Actor

- **HTTP-only, no browser** — seconds, not minutes; no proxy surcharges.
- **Dual-source with free dedupe** — the chronological feed alone caps out around 500 reviews per storefront; the deep-history source alone can't give you "newest first". This Actor gives you both in one run and never charges a duplicate.
- **Free intel** — the all-time rating histogram and % negative per country would cost extra elsewhere; here they ride along in the `SUMMARY`.
- **Pay per event** — $0.01 per run start + $0.08 per 1,000 reviews. Filters run *before* charging: skipped, filtered and duplicate reviews are free.
- **Defensive parser** — missing fields degrade to `null`; storefront hiccups degrade to a smaller result, not a crashed run.

### FAQ

**Is this legal?** The Actor only reads public review data — the same content anyone sees on the App Store product page without logging in. No login, no private data, no bypassing access controls. Review Apple's terms for your specific use case.

**Why don't rows include developer replies?** Apple doesn't expose developer replies through any public web endpoint. Rather than fake it, we don't ship the field. (Our [Google Play Reviews Scraper](https://apify.com/tactful_anvil/google-play-reviews-scraper) does include replies plus reply-delay intel, because Google publishes them.)

**Why is `appVersion` null on some rows?** Apple only publishes the reviewed version in the chronological feed, not in deep history. Feed rows carry it; deep-history rows are `null`, honestly.

**How deep can deep history go?** Thousands of reviews per storefront for large apps. The run pages until your `maxReviewsPerApp` cap, the corpus ends, or a safety page-limit is hit.

**A run returned fewer reviews than the cap?** Small apps and small storefronts simply have fewer reviews. Check the `SUMMARY` — `storeRatingCount` tells you the size of the pool.

**Found a bug, or want another field?** Open a ticket on the **Issues** tab — parser bugs and field requests get fixed.

### Changelog

- **0.1** — Initial release: dual-source (chronological feed + deep helpful-ranked history) with cross-source dedupe, multi-country runs, star/keyword/date filters (filtered rows never charged), free per-app rating-histogram summary, typed output schema. HTTP-only, pay-per-event.

### Was this Actor useful?

If it saved you an afternoon of scrolling the App Store, a short review on the Store page helps other developers decide whether to try it. Reviews are the only signal buyers have before they spend anything.

If something is wrong instead, please open a ticket on the **Issues** tab rather than leaving it broken — it gets fixed.

### Related Actors

- **[Google Play Reviews Scraper](https://apify.com/tactful_anvil/google-play-reviews-scraper)** — the Android twin of this Actor. Schedule both to monitor iOS + Android reviews for the same app portfolio in one place.
- **[Chrome Web Store Intelligence Scraper](https://apify.com/tactful_anvil/chrome-web-store-intelligence-scraper)** — extension listings, ratings and permission-risk audits, if you also track browser extensions.

# Actor input Schema

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

App Store URLs (https://apps.apple.com/us/app/instagram/id389801252) or numeric app IDs like 389801252. One or more.

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

Two-letter storefront codes, e.g. us, gb, de, fr, jp, br, in, id. Each app is scraped once per country. Empty = country from the app URL, or us.

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

Hard cap per app per storefront — this caps your cost ($0.08 per 1,000 reviews). Up to 10,000.

## `source` (type: `string`):

recent = chronological feed (best for monitoring, ~500 most recent per storefront, includes app version + helpful votes); helpful = App Store's own ranking with deep history; both = recent first, then deep history to fill your cap, duplicates removed and never charged.

## `starsFilter` (type: `string`):

Only keep reviews with this rating. 'negative' = 1-2★ (complaint mining), 'positive' = 4-5★ (testimonial mining). Skipped reviews are not charged.

## `newerThanDays` (type: `integer`):

0 = off. With the chronological feed the run stops as soon as it hits older reviews — perfect for cheap scheduled monitoring.

## `filterKeyword` (type: `string`):

Only keep reviews mentioning this word/phrase (checked in title and text, case-insensitive). Skipped reviews are not charged.

## `includeAppMeta` (type: `boolean`):

Attach app name to each row and store the all-time rating histogram, average rating, developer and genre in the free run SUMMARY.

## `language` (type: `string`):

Response language override, e.g. en-US, de-DE, ja. Empty = the storefront's default (recommended).

## Actor input object example

```json
{
  "apps": [
    "https://apps.apple.com/us/app/instagram/id389801252"
  ],
  "countries": [
    "us"
  ],
  "maxReviewsPerApp": 200,
  "source": "both",
  "starsFilter": "all",
  "newerThanDays": 0,
  "filterKeyword": "",
  "includeAppMeta": true,
  "language": ""
}
```

# Actor output Schema

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

No description

# 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/instagram/id389801252"
    ],
    "countries": [
        "us"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tactful_anvil/app-store-reviews-scraper-multi-country-deep-history").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/instagram/id389801252"],
    "countries": ["us"],
}

# Run the Actor and wait for it to finish
run = client.actor("tactful_anvil/app-store-reviews-scraper-multi-country-deep-history").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/instagram/id389801252"
  ],
  "countries": [
    "us"
  ]
}' |
apify call tactful_anvil/app-store-reviews-scraper-multi-country-deep-history --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tactful_anvil/app-store-reviews-scraper-multi-country-deep-history"
        }
    }
}

```

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/x184J0wvThvOFYR7c/builds/oNhbyAo4mRgmY5fZM/openapi.json
