# App Store Reviews Scraper — $0.02/1K · Filters & Countries (`apivault_labs/app-store-reviews-scraper`) Actor

Collect available Apple App Store review rows across apps and storefronts. Filter stars, dates, versions and keywords; deduplicated CSV/JSON/API export. $0.02/1K useful reviews plus resources. Public RSS window, not full history.

- **URL**: https://apify.com/apivault_labs/app-store-reviews-scraper.md
- **Developed by:** [Apivault Labs](https://apify.com/apivault_labs) (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.02 / 1,000 useful app store review delivereds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

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 cover](https://raw.githubusercontent.com/apivault-labs/apivault-labs/b38195f051235a84784ba4d5ad4aa24a68f22b40/assets/app-store-reviews-scraper/readme-cover-generated-v1.png)

## App Store Reviews Scraper — $0.02/1K · Filters & Countries

Turn available iOS app reviews into a clean, filtered dataset: review text, stars, versions, source update dates and helpful votes. Track complaints after a release, compare feedback across storefronts and export one useful review per row to CSV, JSON, Excel or API. **$0.02 per 1000 delivered reviews, no startup event; platform resources extra.**

For product teams tracking complaints, ASO researchers comparing apps and analysts studying public feedback. No Apple login, external API key or browser setup. Running on Apify requires an Apify account.

### First useful run

```json
{"appInputs":["310633997"],"countries":["us"],"maxReviews":100}
```

Paste a numeric app ID or an `apps.apple.com` URL. The default source order is newest. The Actor returns matching review rows, free app context under `APPS`, and explicit `SUMMARY`, `COVERAGE` and `ERRORS` records in the run key-value store.

Apple's public RSS feed exposes up to 10 pages of 50 reviews per app, country and selected sort order. This Actor reads that window. **It does not promise a full historical archive or more than 500 exposed reviews for one app-country-sort.** Apple can return fewer reviews, delay updates or leave gaps.

### Why use it

- One useful review per Dataset row, ready for CSV and analysis.
- Stars, source update dates, exact versions and case-insensitive keywords filter before billing.
- Multiple apps and storefronts, canonical input deduplication and review-ID deduplication across the run.
- Batch writes, bounded concurrency, per-pair and total delivery caps, and an Apify charge cap.
- Useful app context and diagnostics outside the paid review Dataset.

### Choose your workflow

| Your question | Suggested settings | What to inspect |
|---|---|---|
| What are recent users saying? | newest,100reviews,onecountry | Review text and source updatedAt |
| What breaks for unhappy users? | ratings\[1,2],keywords\["crash","slow"] | Keyword leads, not verified defects |
| Did a release change complaints? | Exact versions plus an updated-date window | Sample coverage and version availability |
| Which feedback appears across storefronts? | countries\["us","gb","de"] | First-delivered storefront; dedup across countries |
| Which comments does Apple rank helpful? | sort="helpful" | Helpful source order and vote fields |

Five corresponding scenarios were exercised privately on the candidate. Their public publication is not promised while the account's known Task quota is constrained. Every scenario can be run by copying its input into the Actor.

### Output fields

| Field | Meaning |
|---|---|
| `appId`, `appTitle`, `developer` | App identity and available lookup context |
| `reviewId` | Source review ID; used with appId for run deduplication |
| `country` | Storefront where this review was first delivered; not reviewer nationality |
| `rating`, `title`, `text` | Source stars, title and review body |
| `version` | Source review's app version, when provided |
| `updatedAt` | Source `updated` timestamp, normalized to UTC; not verified original creation time |
| `helpfulVotes`, `voteCount` | Source helpful-vote sum and vote count, or null if unavailable |
| `appUrl`, `reviewUrl` | App and review-list links; reviewUrl is not a direct single-review permalink |
| `author` | Optional public display name; omitted unless includeAuthors=true |

Reviews without valid ID, stars, date or any title/body text are skipped without a result event. Missing app lookup context stays null and does not fabricate a developer or rating. No developer reply or reply-status field is promised by this RSS source.

### Filter low ratings and keywords

```json
{"appInputs":["310633997"],"countries":["us"],"ratings":[1,2],"keywords":["crash","slow"],"maxReviews":50}
```

Ratings and other filter groups combine with AND. Values within ratings, keywords or versions combine with OR. Keywords are case-insensitive substring matches over title and text; they do not perform sentiment analysis or understand negation. Selective filters may scan the full exposed window and return fewer rows, including zero.

### Dates and exact versions

```json
{"appInputs":["310633997"],"countries":["us"],"dateFrom":"2026-01-01","dateTo":"2026-12-31","maxReviews":100}
```

Dates filter the source update timestamp. ISO timestamps are accepted; a date-only end includes its complete UTC day. Add `versions: ["26.21.74"]` for an exact, case-sensitive version match. Version availability depends on what Apple returns; use an observed version from your source data rather than assuming the example exists today.

### Several apps and countries

```json
{"appInputs":["310633997","324684580"],"countries":["us","gb","de"],"maxReviews":500,"maxResults":3000,"maxConcurrency":4}
```

Theoretical exposed window here is at most 2 apps × 3 countries × 500 reviews. Actual useful unique output can be lower. A duplicate `(appId, reviewId)` is delivered once even if exposed by multiple storefronts. The retained country is the first delivered storefront; do not use per-country output counts as a complete independent source census.

Explicit `countries` overrides URL countries. Without countries, each URL's country is used; bare IDs use `country` (default us). Up to 100 app inputs and 20 storefronts are accepted. The total maxResults capacity bound is 100000; it is not a claim of proven 100000-row performance or that one app has that much available history.

### Most helpful source order

```json
{"appInputs":["https://apps.apple.com/us/app/id310633997"],"sort":"helpful","maxReviews":100,"includeAuthors":false}
```

`newest` and `helpful` are distinct Apple RSS source orders. They can overlap. The Actor does not reinterpret ratings as a helpfulness order or rank all historical reviews. Each run selects one order; deduplication does not persist across separate runs.

### Limits, status and resource controls

| Setting | Default | Bounds |
|---|---:|---|
| maxReviews per app/country | 100 | 1–500 matching delivered rows |
| maxResults across run | 5000 | 1–100000 |
| maxPages per app/country | 10 | 1–10 |
| maxConcurrency | 4 | 1–10 |
| maxRunSeconds | 900 | 10–3300, soft limit |

Requests share a small pacing interval and bounded retries. Empty pages are retried once, then later pages are still examined; `COVERAGE.emptyPages` records gaps. Repeated identical pages stop that pair. `FEED_WINDOW_SCANNED` means the configured window was scanned, not that all historical reviews were obtained.

SUMMARY distinguishes SUCCEEDED, EMPTY, PARTIAL_ERRORS, PARTIAL_TIME, PARTIAL_BUDGET and RESULT_LIMIT. Source failures appear in ERRORS; individual pair statuses live in COVERAGE. A fully failed input/source run fails without paid error rows. A legitimate empty filtered window can finish successfully with status EMPTY and zero review events. App context is best effort and is not a prerequisite for using a valid review.

The soft time cap is checked before later review pages; current requests, retries and app-context lookup may complete afterward. There is no continuation checkpoint or persistent monitoring state. Smaller limits and maxPages help bound expensive selective scans. Concurrent requests already in flight may add platform resources after a stop.

### Pricing

**$0.02 per 1000 useful delivered review rows on every plan**, plus user-paid Apify platform resources. No startup event, subscription or separate app-context fee.

Examples of review event fees: 100 reviews = $0.002; 500 = $0.01; 5000 = $0.10. These exclude platform resources and are arithmetic examples, not guarantees of source volume or final invoices. Failed lookups, errors, filtered rows, duplicates, retries, APPS and SUMMARY have no review result event. A zero-row run can still consume platform resources.

Delivery uses SDK-coupled Dataset writes and review billing. Set a maximum charge in Apify to constrain result fees; the platform and SDK can stop with a partial Dataset. No crash-time exactly-once or atomic billing guarantee is claimed.

### Measured bulk run and price context

On 22 October 2026 the previous runtime-identical candidate0.1.4 returned **7500 unique review rows** from 5 apps × 3 storefronts in **60.722 seconds**. API, SDK and CSV contained identical ordered review IDs. Review fees $0.15000 + platform usage $0.06227664 = **$0.21227664 total**, or **about $0.02830 per 1000 reviews** in that test. This is a measurement of that workload, not a promised price or speed for every input. Selective filters, empty feeds and retries can increase resources per delivered row. The 100000 capacity bound was not cloud-tested.

Our review event rate is $0.02/1000 on all plans. A same-day primary API comparison found review rates of $0.10/1000 at Steady Data and Siftwright, and$0.07–0.10/1000 across Stratumics tiers, with different start/context fees. This is a lower review event rate within those three checked listings, **not a claim of the lowest price across the market**. Some alternatives offer deeper history or developer replies; this RSS product has a smaller documented scope. Compare useful output and platform resources along with the displayed event rate.

### Export and API

After the run, use Apify Dataset export for JSON, CSV or Excel. App titles/developers depend on free context availability. Read SUMMARY and COVERAGE before interpreting counts.

Python with the official Apify client:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("apivault_labs/app-store-reviews-scraper").call(
    run_input={"appInputs": ["310633997"], "countries": ["us"], "maxReviews": 100},
    build="latest",
    max_total_charge_usd=0.01,
)
if run["status"] != "SUCCEEDED":
    raise RuntimeError(f"Run ended: {run['status']}")
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
summary = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("SUMMARY")["value"]
print(len(rows), summary["status"])
```

The example iterates every Dataset page rather than reading only the first API page. A process status of SUCCEEDED can still have a partial SUMMARY. Protect your Apify token. No actor-specific n8n node, Python package or verified n8n Cloud integration is claimed; official Apify API/SDK access works independently of such packages.

### Coverage FAQ

**Can I get every review ever written?** No. This implementation uses Apple's bounded public RSS window. Ratings without written text are not review records. Country differences, source delays, empty pages and the source window all affect coverage.

**Does this collect Google Play reviews?** This product focuses on Apple App Store. The separate [Google Play Reviews Scraper](https://apify.com/apivault_labs/google-play-reviews-scraper) handles Android reviews. [App Revenue Analyzer](https://apify.com/apivault_labs/app-revenue-analyzer) compares public app metrics and clearly labeled estimates.

**Are authors or replies included?** Public display names are opt-in. Developer replies are not supplied by this implementation. App/store dates and public text should not be mistaken for verified identity, geography or financial data.

### Python client and n8n workflow

Use the thin [Python client](https://github.com/apivault-labs/apivault-labs/tree/main/packages/apivault-app-store-reviews-scraper) or install it from [PyPI](https://pypi.org/project/apivault-app-store-reviews-scraper/):

```bash
pip install apivault-app-store-reviews-scraper==0.1.0
```

The client starts this hosted Actor through the Apify API and reads its dataset. An Apify account and your own API token are required. Actor result charges and infrastructure usage follow the current pricing. The client package has no subscription of its own. Set both Actor collection limits and run charge caps; the dataset download limit does not limit paid collection.

[n8n node source and manual workflow](https://github.com/apivault-labs/apivault-labs/tree/main/community-nodes/n8n-nodes-apivault-app-store-reviews-scraper) are available on GitHub. The workflow is inactive and has no embedded credentials. Its Run operation starts a paid Actor run; Read Existing Run reads a previous run without starting another. npm version0.1.0 currently awaits npm staged-release approval; do not install the placeholder0.0.0-stage as an operational node. npm publication, when approved, does not establish n8n verification or availability in n8n Cloud.

# Changelog

This Actor's version history is a separate document: https://apify.com/apivault_labs/app-store-reviews-scraper/changelog.md

# Actor input Schema

## `appInputs` (type: `array`):

Numeric App Store IDs or apps.apple.com URLs; up to100. URL storefront used if countries is empty.

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

Optional explicit storefronts, up to20. Overrides URL country. Storefront is not reviewer nationality.

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

Country when a numeric ID or country-less URL is used; defaults to us.

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

Delivered matching reviews per pair. Source exposes at most500 per selected sort, and may expose fewer.

## `maxResults` (type: `integer`):

Total unique delivered reviews. Capacity bound, not a claim that one app has this much exposed history.

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

Newest or most helpful RSS order. Dates refer to source updated timestamp.

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

Optional inclusive set of star ratings, applied before delivery/billing.

## `dateFrom` (type: `string`):

Inclusive ISO date/time filtering on the source review updated timestamp, not verified first publication.

## `dateTo` (type: `string`):

Inclusive ISO date/time; date-only includes the complete UTC day.

## `versions` (type: `array`):

Optional exact, case-sensitive source review versions, OR within list.

## `keywords` (type: `array`):

Optional case-insensitive substring OR match across review title and text.

## `includeAuthors` (type: `boolean`):

Off by default. Adds public source display name when available.

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

Up to10 public RSS pages; gaps retried once and later pages still scanned.

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

Source requests share pacing; high parallelism may increase throttling.

## `maxRunSeconds` (type: `integer`):

Stop before starting later pages. Current network request can finish after this time.

## Actor input object example

```json
{
  "appInputs": [
    "310633997"
  ],
  "country": "us",
  "maxReviews": 100,
  "maxResults": 5000,
  "sort": "newest",
  "includeAuthors": false,
  "maxPages": 10,
  "maxConcurrency": 4,
  "maxRunSeconds": 900
}
```

# Actor output Schema

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

No description

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

No description

## `errors` (type: `string`):

No description

## `coverage` (type: `string`):

No description

## `apps` (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 = {
    "appInputs": [
        "310633997"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("apivault_labs/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 = { "appInputs": ["310633997"] }

# Run the Actor and wait for it to finish
run = client.actor("apivault_labs/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 '{
  "appInputs": [
    "310633997"
  ]
}' |
apify call apivault_labs/app-store-reviews-scraper --silent --output-dataset

```

## MCP server setup

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