# App Store & Google Play Reviews Scraper with Review Themes (`tidydata-labs/app-reviews-scraper`) Actor

Scrape App Store and Google Play reviews (rating, title, text, date, app version, country, developer reply) and get an automatic report of top complaints and praise with counts and example quotes.

- **URL**: https://apify.com/tidydata-labs/app-reviews-scraper.md
- **Developed by:** [Tidy Data Labs](https://apify.com/tidydata-labs) (community)
- **Categories:** Marketing, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.09 / 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.

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 & Google Play Reviews Scraper with Review Themes

Scrape **App Store** and **Google Play** reviews for any app: rating, title, text, date, app version, country and the developer's reply. Then get an automatic **review themes report**: what users complain about and praise most, with counts, share of reviews, example quotes, frequent phrases and rating by app version.

**$0.09 per 1,000 reviews**, plus **$0.05 per app** for the themes report (optional).

### What can you use it for?

- **Product teams:** find the top bugs and feature requests after every release, and see whether a new version made ratings better or worse.
- **Competitor research:** see what users hate about competing apps and what they love.
- **App marketing and ASO:** learn the words users actually use and the reasons behind 1-star reviews.
- **Customer support:** track complaints by theme over time and see how often developers reply on Google Play.

It reads only public, logged-out data: Apple's public customer-reviews feed and Google Play's public app pages. It does **not** save reviewer names, usernames or profile pictures.

### What data does it extract?

Each review:

| Field | Example |
|---|---|
| `store` | `appStore` / `googlePlay` |
| `appId`, `appName` | 570060128, Duolingo: Language Lessons |
| `country` (App Store) / `language` (Google Play) | `us` / `en` |
| `rating` | 1–5 |
| `title`, `text` | "Love it", "Great way to practice every day…" |
| `date` | 2026-10-03T08:55:37Z |
| `appVersion` | 7.142.0 |
| `helpfulVotes`, `totalVotes` | 12, 15 |
| `developerReply`, `developerReplyDate` | Google Play only |
| `reviewUrl` | Google Play only |

The **themes report**, one per app, is saved to the run's key-value store as `THEMES` (all apps) and `THEMES-<store>-<appId>` (one app):

```json
{
    "appName": "Duolingo: Language Lessons",
    "store": "appStore",
    "reviewsAnalyzed": 300,
    "averageRatingInSample": 3.77,
    "ratingDistribution": { "1": 57, "2": 18, "3": 28, "4": 30, "5": 167 },
    "topComplaints": [
        {
            "theme": "Pricing & subscription",
            "reviewCount": 19,
            "sharePercent": 25.3,
            "averageRating": 1.2,
            "examples": [{ "rating": 1, "date": "2026-10-02T…", "quote": "I'm letting my subscription expire…" }]
        }
    ],
    "topPraise": [{ "theme": "Love it / great app", "reviewCount": 69, "sharePercent": 35 }],
    "complaintPhrases": [{ "phrase": "money grab", "reviewCount": 3 }],
    "ratingByVersion": [{ "version": "7.142.0", "reviewCount": 295, "averageRating": 3.78 }]
}
```

Complaint themes come from 1–2★ reviews and praise themes from 4–5★ reviews. The themes are: crashes & bugs, slow & performance, login & account, ads, pricing & subscription, updates & changes, customer support, notifications, sync & data loss, privacy & security, UI & design, feature requests, ease of use, useful & helpful, and love it / great app.

#### Optional AI summary with Claude

Turn on **Add AI summary with Claude** and enter your own Anthropic API key. You'll get a written overview, top complaint and praise themes in plain language with verbatim quotes, a list of feature requests and suggested fixes. Claude reads the 400 newest reviews of each app. With Claude Haiku this typically costs a few cents per app on your Anthropic bill, and nothing extra here.

### How to use it

1. Paste App Store URLs (`https://apps.apple.com/us/app/…/id123456789`) and/or Google Play URLs (`https://play.google.com/store/apps/details?id=…`). You can also enter just the IDs.
2. Choose countries, the max reviews per app and any filters (star range, posted after a date).
3. Click **Start**, then download the reviews as JSON, CSV or Excel and open the `THEMES` record in the run's key-value store.

#### Input example

```json
{
    "appStoreApps": ["https://apps.apple.com/us/app/duolingo-language-lessons/id570060128"],
    "googlePlayApps": ["com.duolingo"],
    "countries": ["us", "gb", "ca"],
    "maxReviewsPerApp": 1000,
    "maxRating": 2,
    "generateThemesReport": true
}
```

### How many reviews can I get?

- **App Store:** Apple's public feed serves the newest (or most helpful) **500 reviews per country**. Add more countries to get more: `us`, `gb`, `ca` and `au` give up to 2,000 English reviews.
- **Google Play:** thousands of reviews per app, in the language you choose.

### How much does it cost?

Pay per result, and platform usage is included:

- **$0.09 per 1,000 reviews**
- **$0.05 per app themes report.** Turn it off if you only need the raw reviews.

Example: 1,000 reviews each for 3 apps, with themes reports, costs $0.27 + $0.15 = **$0.42**.

### Tips

- To study what's going wrong, set **Maximum star rating** to 2 and collect only complaints.
- Use **Reviews posted after** with a weekly schedule to monitor new reviews after each release.
- Compare `ratingByVersion` to see whether a release improved or hurt ratings.

### Guides

#### Guide 1: Find out what users hate about your latest release

1. Paste your app's App Store and/or Google Play URLs.
2. Set **Reviews posted after** to your release date and **Maximum star rating** to `2`.
3. Click **Start** and open the `THEMES` record. The top complaint themes are listed with counts and real quotes, and the `appVersion` field shows which version each review is about.

```json
{
  "appStoreApps": ["https://apps.apple.com/us/app/duolingo-language-lessons/id570060128"],
  "googlePlayApps": ["https://play.google.com/store/apps/details?id=com.duolingo"],
  "reviewedAfter": "2026-09-01",
  "maxRating": 2,
  "maxReviewsPerApp": 500
}
```

#### Guide 2: Compare iPhone and Android users

Run the same app on both stores in one run. Every review has a `store` field, so you can split the dataset and compare ratings and complaint themes between App Store and Google Play users.

#### Guide 3: Check reviews in several countries

Add country codes to **Countries** (for example `us`, `gb`, `de`, `br`, `in`). App Store reviews are collected per country, so you can see whether complaints differ by market, such as pricing in one country or localization bugs in another.

#### Guide 4: Track competitors every week

Save a competitor list as a **task**, add a weekly **Schedule**, and connect it to Google Sheets or Slack from the **Integrations** tab. Each week you get fresh reviews and an updated themes report.

#### Run it from code (API)

Replace `YOUR_APIFY_TOKEN` with your token from **Console > Settings > API & Integrations**. This call runs the actor and returns the results in one request:

```bash
curl -X POST "https://api.apify.com/v2/acts/tidydata-labs~app-reviews-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"googlePlayApps":["com.duolingo"],"maxReviewsPerApp":200,"maxRating":2}'
```

You can do the same with the `apify-client` package for Python or JavaScript, or connect the actor to Make, Zapier, n8n, Google Sheets or a webhook from the **Integrations** tab.

### FAQ

**Do I need a developer account or API key for the stores?** No. The actor reads public reviews.

**Why do I get at most about 500 App Store reviews per country?** Apple's public review feed only goes back that far for each country. Add more countries to get more reviews.

**Does it collect reviewer names?** No.

### Is it legal to scrape app reviews?

The actor collects only public reviews that anyone can read without logging in, and it leaves out reviewer names and profile data. Review text can still contain personal details that users typed in, so make sure your use of the data complies with applicable laws such as GDPR, and with the stores' terms.

### Feedback

Missing a field, a theme or a store? Open an issue on the **Issues** tab. We usually reply within a day.

# Actor input Schema

## `appStoreApps` (type: `array`):

App Store app URLs (https://apps.apple.com/us/app/name/id123456789) or numeric app IDs.

## `googlePlayApps` (type: `array`):

Google Play app URLs (https://play.google.com/store/apps/details?id=com.example) or package names.

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

Two-letter country codes. App Store reviews are separate per country, so each country adds more reviews (up to 500 per country). Google Play uses only the first country.

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

Two-letter language code for Google Play reviews, e.g. en, es, de.

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

Maximum reviews to save per app (across all countries). You are charged per saved review. Apple's public feed serves up to 500 reviews per country.

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

Which reviews to collect first.

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

Only keep reviews with at least this many stars.

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

Only keep reviews with at most this many stars. Set to 2 to collect only complaints.

## `reviewedAfter` (type: `string`):

Only keep reviews posted on or after this date (YYYY-MM-DD). With 'Newest first' the run stops early once older reviews are reached.

## `generateThemesReport` (type: `boolean`):

Build a report per app with the top complaint and praise themes, counts, share of reviews, example quotes, frequent phrases and rating by app version. Saved to the key-value store as THEMES. Charged once per app.

## `useClaudeSummary` (type: `boolean`):

Also ask Claude to summarize themes, feature requests and suggested fixes. Requires your own Anthropic API key; typically costs a few cents per app on your Anthropic bill.

## `anthropicApiKey` (type: `string`):

Your Anthropic API key, used only for the AI summary. Stored encrypted.

## `claudeModel` (type: `string`):

Haiku is cheapest; Sonnet gives richer summaries.

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

Usually not needed. Enable Apify Proxy if Google Play starts refusing requests.

## Actor input object example

```json
{
  "appStoreApps": [
    "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128"
  ],
  "googlePlayApps": [
    "https://play.google.com/store/apps/details?id=com.duolingo"
  ],
  "countries": [
    "us"
  ],
  "language": "en",
  "maxReviewsPerApp": 200,
  "sortBy": "newest",
  "minRating": 1,
  "maxRating": 5,
  "generateThemesReport": true,
  "useClaudeSummary": false,
  "claudeModel": "claude-haiku-4-5",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `themes` (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 = {
    "appStoreApps": [
        "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128"
    ],
    "googlePlayApps": [
        "https://play.google.com/store/apps/details?id=com.duolingo"
    ],
    "countries": [
        "us"
    ],
    "maxReviewsPerApp": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidydata-labs/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 = {
    "appStoreApps": ["https://apps.apple.com/us/app/duolingo-language-lessons/id570060128"],
    "googlePlayApps": ["https://play.google.com/store/apps/details?id=com.duolingo"],
    "countries": ["us"],
    "maxReviewsPerApp": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("tidydata-labs/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 '{
  "appStoreApps": [
    "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128"
  ],
  "googlePlayApps": [
    "https://play.google.com/store/apps/details?id=com.duolingo"
  ],
  "countries": [
    "us"
  ],
  "maxReviewsPerApp": 200
}' |
apify call tidydata-labs/app-reviews-scraper --silent --output-dataset

```

## MCP server setup

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