# App Reviews Scraper (App Store + Google Play) (`serentity/app-reviews-scraper`) Actor

Reviews from the Apple App Store and Google Play in one actor: rating, title, text, author, app version, date, helpful votes and developer replies. Newest, most helpful or by rating, any country. No API key.

- **URL**: https://apify.com/serentity/app-reviews-scraper.md
- **Developed by:** [Tarik Cerkezovic](https://apify.com/serentity) (community)
- **Categories:** E-commerce, Business, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

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 Reviews Scraper (App Store + Google Play)

One actor for both app stores. Give it App Store URLs or IDs and Google Play URLs or package names, in any mix, and get every review as a clean item: star rating, title (App Store), text, author, app version, date, helpful votes and the developer's reply (Google Play). Newest first, most helpful, or by rating; any store country; optional single-star filter for pulling just the 1-star or 5-star reviews.

No API key, no login. Built for product teams, app-store optimisation, competitor monitoring, sentiment analysis and support triage.

### What you get

| Field | Description |
|---|---|
| `store`, `appId`, `appName`, `appUrl`, `developer`, `appRating`, `appRatingCount`, `country` | The app, repeated on every item |
| `reviewId`, `position` | Stable review ID and rank in the requested order |
| `rating`, `title`, `text` | The review. Titles exist on the App Store only |
| `author`, `authorUrl` | Reviewer display name, and profile URL on the App Store |
| `version`, `date`, `helpfulCount` | App version reviewed, ISO date, helpful votes |
| `developerReply`, `developerReplyDate` | Google Play developer response, when any |
| `error`, `errorMessage` | Only on app-level failures |

### Sample output

```json
{
  "store": "googleplay",
  "appId": "com.facebook.katana",
  "appName": "Facebook",
  "appUrl": "https://play.google.com/store/apps/details?id=com.facebook.katana&hl=en&gl=us",
  "developer": "Meta Platforms, Inc.",
  "appRating": 4.56,
  "appRatingCount": 187093848,
  "country": "us",
  "reviewId": "1f9ddd3d-6847-4398-9b72-160b4682437f",
  "position": 1,
  "author": "Char Cross",
  "rating": 1,
  "text": "Reported to Facebook three times that since they moved the marketplace...",
  "version": "578.0.0.40.75",
  "date": "2026-09-17T09:14:31.000Z",
  "helpfulCount": 16650,
  "input": "com.facebook.katana",
  "fetchedAt": "2026-11-05T17:00:00.000Z"
}
```

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `apps` | array of strings | required | App Store URLs or numeric IDs; Google Play URLs or package names. |
| `maxReviewsPerApp` | integer | `200` | Cap per app. `0` takes all. Apple's public feed stops at 500 per app and country; Google Play has no cap. |
| `sortBy` | `newest`, `most_helpful`, `rating` | `newest` | Order. `rating` is Google Play only; the App Store falls back to most helpful. |
| `country` | string | `us` | Store country. A country in the URL wins. |
| `language` | string | `en` | Google Play interface language. |
| `ratingFilter` | 1 to 5 | none | Keep only reviews with this rating. Google Play filters server-side; the App Store feed is filtered after download. |
| `maxConcurrency` | integer | `3` | Apps in parallel. |
| `proxyConfiguration` | object | Apify datacenter proxy | Proxy for all requests. |
| `residentialFallback` | boolean | `true` | Retry a blocked app through residential proxies, only on a detected block. |

Minimal input:

```json
{ "apps": ["id284882215", "com.facebook.katana"], "maxReviewsPerApp": 500 }
```

### Errors

| `error` | Meaning | Charged? |
|---|---|---|
| `INVALID_INPUT` | Not an App Store or Google Play app reference | no |
| `APP_NOT_FOUND` | No such app in that store and country | no |
| `NO_REVIEWS` | The app has no reviews there (or none with the chosen rating) | no |
| `BLOCKED` | The store refused every proxy tried | no |
| `FETCH_FAILED` | Network or parsing failure | no |

### Pricing

Pay per event: a small fixed amount per review item, plus Apify platform usage. Error items are free. Set a maximum total charge on the run to cap spend.

### Notes

- App Store reviews come from Apple's public customer-reviews feed, which returns the 500 most recent (or most helpful) reviews per country. For older reviews, run the actor regularly and deduplicate on `reviewId`.
- Google Play pages through its review list with a continuation token, so `0` really means all reviews, which can be hundreds of thousands for big apps. Use `maxReviewsPerApp` or a run charge limit.
- Dates are ISO 8601 in UTC. App Store versions and helpful votes are as reported by the feed.

### Using it from code

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('serentity/app-reviews-scraper').call({ apps: ['com.facebook.katana'], maxReviewsPerApp: 1000, ratingFilter: 1 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### Legal

Reviews are public content on the store pages. The actor collects the public display name a reviewer chose and nothing else about them. Use it in line with the stores' terms and applicable data protection law.

# Actor input Schema

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

App Store URLs (https://apps.apple.com/us/app/.../id284882215) or numeric IDs, and Google Play URLs (https://play.google.com/store/apps/details?id=com.facebook.katana) or package names. Mix both stores freely.

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

Stop after this many reviews per app. 0 means all. Apple's public feed serves at most 500 reviews per app and country; Google Play has no cap.

## `sortBy` (type: `string`):

newest = most recent first. most_helpful = the store's helpfulness ranking. rating = Google Play's rating order (App Store falls back to most helpful).

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

Two-letter store country, for example us, gb, de. A country in an App Store URL or a gl parameter in a Play URL overrides this.

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

Google Play interface language, for example en, de. Reviews come back in the language they were written in.

## `ratingFilter` (type: `integer`):

1 to 5 to keep only reviews with that rating. Leave empty for all ratings.

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

Apps processed in parallel.

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

Proxy used for the requests. Apify datacenter proxies are used by default.

## `residentialFallback` (type: `boolean`):

If a store blocks the datacenter proxy for an app, retry through Apify residential proxies. Only used on a detected block.

## Actor input object example

```json
{
  "apps": [
    "https://apps.apple.com/us/app/facebook/id284882215",
    "com.facebook.katana"
  ],
  "maxReviewsPerApp": 200,
  "sortBy": "newest",
  "country": "us",
  "language": "en",
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true
}
```

# Actor output Schema

## `results` (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/facebook/id284882215",
        "com.facebook.katana"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("serentity/app-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 = {
    "apps": [
        "https://apps.apple.com/us/app/facebook/id284882215",
        "com.facebook.katana",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("serentity/app-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 '{
  "apps": [
    "https://apps.apple.com/us/app/facebook/id284882215",
    "com.facebook.katana"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call serentity/app-reviews-scraper --silent --output-dataset

```

## MCP server setup

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