# App Reviews Scraper — Google Play & App Store in One (`datakiln/app-reviews-scraper`) Actor

Scrape app reviews from Google Play and the Apple App Store in one run with a unified output: rating, title, text, author, date, app version, helpful votes and developer replies. Filter by stars, date and country.

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

## Pricing

$0.30 / 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 Reviews Scraper — Google Play & App Store in one run

Scrape app reviews from **Google Play and the Apple App Store at the same time** — no login, no API key, no developer account. Paste Play links, package names or App Store links in one list and get every review in **one unified format**: star rating, title, review text, author, date, app version, helpful votes and the developer's reply. Filter by stars and date, scrape several countries at once, and get a ready-made **per-app rating summary** with every run.

**Pay only for what you get: $0.30 per 1,000 reviews**, both stores. No monthly rental, no start fees.

### Why this scraper?

- 📱 **Both stores, one run, one schema** — no need to run two different scrapers and merge two different column layouts. A Play review and an App Store review have exactly the same fields, with a `store` column to tell them apart.
- ⭐ **Star filters** — get only 1–2 star complaints, or only 5-star praise. On Google Play the filter is applied on Google's side, so you don't pay for (or wait on) reviews you don't want.
- 📅 **Only new reviews** — set *Reviews from date* and the scraper stops as soon as it reaches older reviews. Perfect for a daily or weekly schedule.
- 🌍 **Multi-country** — App Store reviews are different in every country storefront. Add `us`, `gb`, `de`, `in`… and each one is scraped.
- 📊 **Summary included** — reviews scraped, average rating of the scraped reviews, a 1–5 star histogram and the official store rating & ratings count for every app, saved as `SUMMARY` in the run's key-value store (free).

### What can you do with it?

- 🔍 **Competitor research** — compare what users love and hate about your app and your competitors' apps on both platforms.
- 🐞 **Bug and churn monitoring** — schedule a daily run with *Newest first*, 1–2 stars and a date filter to catch crashes and complaints right after a release (`appVersion` tells you which build).
- 🤖 **Sentiment analysis & AI pipelines** — feed clean review text into your LLM, BI tool or spreadsheet to find feature requests and pain points.
- 💬 **Customer support** — see which Play reviews already have a developer reply (`replyText`, `replyDate`) and which still need one.
- 📈 **Market and academic research** — collect thousands of public reviews across apps, stores and countries in a single dataset.

### How to use

1. Add apps in any mix:
   - Google Play: `com.spotify.music` or `https://play.google.com/store/apps/details?id=com.spotify.music`
   - App Store: `https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580`, `ios:324684580` or `324684580`
2. Choose how many reviews per app, the sort order, countries, and optional star / date filters.
3. Click **Start**. Download the results as JSON, CSV, Excel or HTML, or connect them to Make, Zapier, n8n, Google Sheets or your API.

### Input example

```json
{
  "apps": [
    "com.spotify.music",
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ],
  "maxReviewsPerApp": 300,
  "sortBy": "newest",
  "countries": ["us", "gb"],
  "language": "en",
  "minRating": 1,
  "maxRating": 2,
  "dateFrom": "2026-09-01"
}
```

### Output example

A Google Play review:

```json
{
  "store": "google_play",
  "appId": "com.spotify.music",
  "appName": "Spotify: Music and Podcasts",
  "developer": "Spotify AB",
  "country": "us",
  "language": "en",
  "reviewId": "9d28854a-697f-4c24-bee2-e9d0cc93e781",
  "rating": 2,
  "title": null,
  "text": "OCTOBER 2026 UPDATE MY DOWNLOADS JUST KEEP PENDING. SAYS A HAVE 70 DOWNLOADS PENDING AND I DONT. IVE CLEARED CACHE, UNINSTALLED, REINSTALLED…",
  "author": "Steve.",
  "authorImageUrl": "https://play-lh.googleusercontent.com/a-/ALV-UjX1zmaB80ls1jsGOQGXPwnpWor66lZKzO_6FUvUt37Dp4VEzGQq",
  "authorUrl": null,
  "date": "2026-10-08T15:54:32+00:00",
  "appVersion": null,
  "thumbsUpCount": 0,
  "voteCount": null,
  "replyText": "Hi. Thanks for sharing your experience. We suggest clean reinstalling the app as it's a step above basic reinstall and fixes many common issues…",
  "replyDate": "2026-10-08T16:18:12+00:00",
  "url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us",
  "scrapedAt": "2026-10-09T16:25:13+00:00"
}
```

An App Store review has exactly the same fields:

```json
{
  "store": "app_store",
  "appId": "324684580",
  "appName": "Spotify: Music and Podcasts",
  "developer": "Spotify",
  "country": "gb",
  "language": null,
  "reviewId": "14639676181",
  "rating": 1,
  "title": "Complex to make playlist of albums",
  "text": "Gives suggestions for similar songs. I want the exact album not similar songs from other artists.",
  "author": "Sanj2495",
  "authorImageUrl": null,
  "authorUrl": "https://itunes.apple.com/gb/reviews/id129708873",
  "date": "2026-10-07T21:32:37+00:00",
  "appVersion": "9.1.88",
  "thumbsUpCount": 0,
  "voteCount": 0,
  "replyText": null,
  "replyDate": null,
  "url": "https://apps.apple.com/gb/app/spotify-music-and-podcasts/id324684580",
  "scrapedAt": "2026-10-09T16:17:36+00:00"
}
```

#### All fields

| Field | Description |
|---|---|
| `store` | `google_play` or `app_store` |
| `appId`, `appName`, `developer`, `url` | The app: package name or numeric App Store id, its name, developer and store page |
| `country`, `language` | Storefront country; language code for Google Play (`null` for the App Store, which has no language filter) |
| `reviewId` | Unique review ID within the store |
| `rating` | Stars, integer 1–5 |
| `title` | Review title (App Store only — Google Play reviews have no title, `null`) |
| `text` | Full review text |
| `author`, `authorImageUrl`, `authorUrl` | Reviewer name; profile picture (Google Play); reviewer profile link (App Store) |
| `date` | When the review was posted or last edited (ISO 8601, UTC) |
| `appVersion` | App version the review was written for (if the store shows it) |
| `thumbsUpCount` | "Helpful" votes: Google Play thumbs-up / App Store helpful votes |
| `voteCount` | App Store only: total helpful + not-helpful votes |
| `replyText`, `replyDate` | The developer's public reply (Google Play) |
| `scrapedAt` | When the review was collected (ISO 8601, UTC) |

#### The SUMMARY record

Every run also saves a `SUMMARY` record to its default key-value store (the *Per-app summary* link on the run's **Output** tab). It is not charged.

```json
{
  "totals": { "reviewsScraped": 544, "googlePlayReviews": 300, "appStoreReviews": 244, "appsSkipped": 0, "appsFailed": 0 },
  "apps": [
    {
      "store": "app_store", "appId": "324684580", "appName": "Spotify: Music and Podcasts", "country": "us",
      "reviewsScraped": 109, "avgRatingOfScraped": 1.275,
      "ratingHistogram": { "1": 79, "2": 30, "3": 0, "4": 0, "5": 0 },
      "storeRating": 4.772, "storeRatingsCount": 42474202
    }
  ],
  "skipped": []
}
```

Google Play entries also include `storeReviewsCount` and the store's own `storeRatingHistogram`. App Store entries are per country, because each storefront has its own rating.

### Pricing

Pay-per-result: **$0.0003 per review** ($0.30 per 1,000 reviews), the same price for Google Play and the App Store. Platform usage is included. Reviews removed by your star or date filters are not charged. Cap the cost of any run with *Max total charge* in the run options — the scraper stops cleanly when the cap is reached and still writes the summary.

### FAQ

**How many App Store reviews can I get?** Apple's public review feed returns at most **10 pages × 50 = about 500 of the most recent (or most helpful) reviews per app per country**. That is Apple's limit, not ours. To get more, add more countries: each country storefront has its own ~500 reviews, so `["us", "gb", "ca", "au", "in"]` gives up to ~2,500 English-language App Store reviews for a big app. Star filters are applied to those ~500, so a 1–2 star filter returns fewer.

**How many Google Play reviews can I get?** Many more — Google Play can go deep into an app's history (tens of thousands of reviews per app per language). Set *Max reviews per app* to `0` for everything, and use *Max total charge* to stay within budget.

**Why is Google Play scraped only once when I add several countries?** Google Play groups reviews by **language**, not by country: the English reviews you see in the US and the UK are practically the same. The scraper uses the first country with your *Language* and avoids paying twice for duplicates. To get e.g. German Play reviews, set *Language* to `de`.

**Do I need a login, API key or developer account?** No. Only public reviews that anyone can see in the store are collected.

**What if an app ID is wrong or the app isn't available in a country?** It is skipped with a clear warning in the log and listed under `skipped` in the summary. The rest of the run continues and you are not charged for it.

**Does "Reviews from date" work with "Most relevant"?** Yes, as a filter — but because relevance-sorted reviews aren't in date order, the scraper has to read further. For date-based monitoring use *Newest first*: it stops at the first older review.

**Are App Store developer responses included?** Apple's public review feed does not include developer responses, so `replyText` is filled for Google Play reviews only.

**Is it legal?** It collects only publicly available reviews. You are responsible for using the data in line with Google Play's and Apple's terms and the laws that apply to you, including data-protection rules such as GDPR when you process personal data like reviewer names.

### Related tools by DataKiln

- [Google Play App & Developer Contacts — apps with developer emails, websites & stats](https://apify.com/datakiln/google-play-developer-contacts)
- [YouTube Comments Scraper — comments, replies & likes](https://apify.com/datakiln/youtube-comments-scraper)

### Support

Found a bug or need a field that's missing? Open an issue on the **Issues** tab — we usually reply within 24 hours.

# Actor input Schema

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

Apps to scrape — mix both stores freely, the store is detected automatically. Google Play: a Play URL (https://play.google.com/store/apps/details?id=com.spotify.music) or a package name (com.spotify.music). App Store: an App Store URL (https://apps.apple.com/us/app/spotify/id324684580), 'ios:324684580' or the numeric id.

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

How many reviews to save per app (for the App Store: per app and per country). Set 0 to get all available reviews. Note: Apple's public feed returns at most ~500 reviews per country, Google Play can go much deeper.

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

'Newest first' returns the latest reviews (best for monitoring and with 'Reviews from date'). 'Most relevant' returns Google Play's most relevant and the App Store's most helpful reviews first.

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

Two-letter country codes (us, gb, de, fr, in, br…). App Store reviews are separate for every country storefront, so each country is scraped separately and multiplies the results. Google Play reviews depend on the language, not the country — Play apps are scraped once with the first country.

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

Two-letter language code for Google Play reviews (en, de, es, fr, pt, ar…). Play returns reviews written in this language. The App Store has no language filter — you get the reviews of each country storefront.

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

Only save reviews with at least this many stars (1–5). Combine with 'Maximum star rating' — e.g. 1 and 2 for negative reviews only. You are only charged for saved reviews.

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

Only save reviews with at most this many stars (1–5).

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

Only reviews posted on or after this date (YYYY-MM-DD). With 'Newest first' the scraper stops as soon as it reaches older reviews, so this is the cheapest way to fetch only recent reviews on a schedule.

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

How many apps / App Store countries to scrape at the same time.

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

Not required — both stores work without a proxy. If enabled, Apify Proxy is used for review requests (App Store feed and Google Play reviews).

## Actor input object example

```json
{
  "apps": [
    "com.spotify.music",
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ],
  "maxReviewsPerApp": 200,
  "sortBy": "newest",
  "countries": [
    "us"
  ],
  "language": "en",
  "maxConcurrency": 4
}
```

# Actor output Schema

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

All scraped reviews from both stores as structured JSON items.

## `reviewsTable` (type: `string`):

Reviews in the overview table view.

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

Reviews scraped, average rating, 1–5 star histogram and store rating per app and storefront.

# 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": [
        "com.spotify.music",
        "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
    ],
    "maxReviewsPerApp": 200,
    "countries": [
        "us"
    ],
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("datakiln/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": [
        "com.spotify.music",
        "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
    ],
    "maxReviewsPerApp": 200,
    "countries": ["us"],
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("datakiln/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": [
    "com.spotify.music",
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ],
  "maxReviewsPerApp": 200,
  "countries": [
    "us"
  ],
  "language": "en"
}' |
apify call datakiln/app-reviews-scraper --silent --output-dataset

```

## MCP server setup

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