# App Store & Google Play Reviews Scraper (`cprussin/app-store-reviews`) Actor

Apple App Store and Google Play reviews in one schema: rating, text, author, date, app version, developer reply, helpful votes. Any country; newest-first delta mode.

- **URL**: https://apify.com/cprussin/app-store-reviews.md
- **Developed by:** [Connor Prussin](https://apify.com/cprussin) (community)
- **Categories:** Marketing, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 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

**App Store & Google Play Reviews Scraper** downloads user reviews from the **Apple App Store** and **Google Play** in one run and returns them in **one normalized schema**: star rating, title, review text, author, date, app version, developer reply (with its date), helpful votes, country, language and a link. Paste app URLs or IDs; the store is detected automatically.

- ✅ **Both stores, one schema.** Compare your iOS and Android reviews, or yours against a competitor's, without merging two formats.
- ✅ **Developer replies** and reply dates on both stores, so you can measure response rate and response time.
- ✅ **App version** on each review, so you can tie complaints to a release.
- ✅ **New-review alerts.** Turn on `onlyNew` and schedule the actor daily: each run returns (and bills) only reviews it hasn't returned before. Or set `sinceDate` (e.g. `"7 days"`) for a date cutoff.
- ✅ Filter by **star rating** (e.g. 1–2 stars for complaints only), **country** and **language**.
- ✅ Public store endpoints. No login, no API key and normally no proxy needed.
- ✅ Pay only per review returned.

### Who uses App Store and Google Play reviews?

- **Product managers and mobile teams** track bugs and feature requests after every release, per app version.
- **Customer support and community teams** find unanswered negative reviews and measure developer-reply coverage.
- **Competitive intelligence and market research**: see what users love and hate about competing apps, in every country.
- **ASO (App Store Optimization) specialists** mine review language for keywords and monitor rating trends.
- **Data scientists and AI teams** build sentiment-analysis, topic-modeling or LLM-summarization datasets.
- **Agencies** send clients weekly review digests via Apify integrations (Google Sheets, Slack, email, webhooks).

### How does the app review scraper work?

1. Add apps as URLs or IDs. Anything is accepted:
   - App Store: `https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580`, `id324684580` or `324684580`
   - Google Play: `https://play.google.com/store/apps/details?id=com.spotify.music` or `com.spotify.music`
   - iOS bundle ID: prefix it with `apple:`, e.g. `apple:com.spotify.client`
2. Pick a country, language, sort order and how many reviews you want per app.
3. The actor pages through each store's public review feed, retries rate limits and network errors with backoff, removes duplicates, applies your filters and writes one dataset item per review.
4. If an app doesn't exist in the chosen country, it is logged and skipped; the rest of the run continues.

### How do I choose which app reviews to scrape?

| Field                | Description                                                                                                         | Example                           |
| -------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `apps`               | App Store / Google Play URLs or IDs (store auto-detected)                                                           | `["id324684580", "com.whatsapp"]` |
| `country`            | Two-letter store country                                                                                            | `"us"`, `"gb"`, `"de"`            |
| `language`           | Review language (Google Play only; the App Store has no language filter)                                            | `"en"`                            |
| `sort`               | `newest` or `mostRelevant` (App Store "most helpful", Google Play "most relevant")                                  | `"newest"`                        |
| `maxReviewsPerApp`   | Stop after this many reviews per app                                                                                | `500`                             |
| `sinceDate`          | Only reviews on or after this date: `YYYY-MM-DD`, ISO timestamp, or relative (`"7 days"`, `"2 weeks"`, `"1 month"`) | `"7 days"`                        |
| `onlyNew`            | Monitoring: only reviews not returned by an earlier run with the same input (see Tips)                              | `true`                            |
| `minRating`          | Minimum stars (1–5)                                                                                                 | `4`                               |
| `maxRating`          | Maximum stars (1–5)                                                                                                 | `2`                               |
| `proxyConfiguration` | Optional Apify Proxy for very large runs                                                                            | `{ "useApifyProxy": true }`       |

Example: every 1–2 star review from the last week for two competing apps, on both stores.

```json
{
  "apps": [
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
    "com.spotify.music",
    "https://apps.apple.com/us/app/pandora-music-podcasts/id284035177",
    "com.pandora.android"
  ],
  "country": "us",
  "language": "en",
  "sort": "newest",
  "sinceDate": "7 days",
  "maxRating": 2,
  "maxReviewsPerApp": 1000
}
```

### What data does each app review include?

One dataset item per review. App Store example:

```json
{
  "store": "apple",
  "appId": "324684580",
  "appName": "Spotify: Music and Podcasts",
  "reviewId": "14603399497",
  "rating": 5,
  "title": "Always there",
  "text": "Thanks Spotify for keeping the music going offline out in the back woods!",
  "author": "zephyr322",
  "date": "2026-09-28T13:34:02.000Z",
  "appVersion": "9.1.86",
  "developerReply": null,
  "developerReplyDate": null,
  "helpfulCount": 0,
  "country": "us",
  "language": null,
  "url": "https://apps.apple.com/us/app/id324684580?see-all=reviews"
}
```

Google Play example:

```json
{
  "store": "google",
  "appId": "com.robinhood.android",
  "appName": "Robinhood: Trading & Investing",
  "reviewId": "b09bffa7-10fd-42bb-9200-65b89bc23e9b",
  "rating": 1,
  "title": null,
  "text": "…",
  "author": "…",
  "date": "2026-09-28T16:23:52.000Z",
  "appVersion": "2026.38.6",
  "developerReply": "Please reach out at reviews@robinhood.com. We’ll take a closer look and do our best to find a fix quickly.",
  "developerReplyDate": "2026-09-28T16:41:28.000Z",
  "helpfulCount": 0,
  "country": "us",
  "language": "en",
  "url": "https://play.google.com/store/apps/details?id=com.robinhood.android&hl=en&gl=us&reviewId=b09bffa7-10fd-42bb-9200-65b89bc23e9b"
}
```

(Shortened examples; real runs return the full text.)

**Field notes**

- `date` and `developerReplyDate` are ISO 8601 UTC timestamps.
- `title`: Google Play reviews have no title, so it is always `null` there.
- `helpfulCount`: "helpful" votes on the App Store, thumbs-up on Google Play.
- `appVersion`: on Google Play it comes with every review (when the reviewer's version is known). On the App Store it is available for roughly the **500 most recent reviews** per country; older App Store reviews have `null`.
- `language`: the language requested from Google Play. `null` for App Store reviews, which Apple doesn't filter by language (you get every review posted in that country's store).
- `url`: Google Play links to the individual review; the App Store has no per-review page, so it links to the app's reviews page.
- `author` is the public nickname shown in the store.

### How much does it cost to scrape app reviews?

Pay-per-event, only for what you get:

| Event                            | Price       |
| -------------------------------- | ----------- |
| Review (one item in the dataset) | **$0.0005** |

That's **$0.50 per 1,000 reviews**, for both stores combined. Filtered-out and duplicate reviews are not charged. If you set a **maximum cost per run**, the actor stops cleanly when it reaches it.

### Tips for scraping App Store and Google Play reviews

- **Daily new-review alerts:** schedule this actor daily (Apify Console, Schedules; or save a task and schedule it) with `"onlyNew": true`. The first run returns the latest reviews (up to `maxReviewsPerApp`) as a baseline; every later run returns only reviews not returned before and stops paging a few days before the newest one it has seen, so a quiet day costs almost nothing. Add a Slack, email or webhook integration to the task for alerts. State lives in your account in the key-value store `app-store-reviews-state`, one record per combination of apps, country, language and rating filter; changing any of these starts a new baseline.
- **Weekly review digest:** schedule the actor with `sinceDate: "7 days"` and sort = Newest, and pipe the dataset to Google Sheets, Slack or email with Apify integrations.
- **Complaint tracking:** `maxRating: 2` returns only 1–2 star reviews. Combine with `appVersion` to spot a bad release.
- **Multiple countries:** App Store reviews are separate per country. Run once per country (e.g. `us`, `gb`, `de`) to cover them.
- **Google Play language:** Google returns reviews in the requested `language`. For all reviews from Germany in German, use `country: "de"`, `language: "de"`.
- Very large pulls (hundreds of thousands of reviews) may hit store rate limits. The actor backs off automatically; add Apify Proxy if it keeps happening.

### App review scraper FAQ

**How many reviews can I get?** Google Play serves its full review history through pagination. The App Store feed also goes deep for popular apps, but Apple decides how much history it exposes, and this varies by app and country. `maxReviewsPerApp` caps each app.

**Does it need a login, API key or App Store Connect access?** No. It reads the same public review data anyone can see in the stores. It cannot read private feedback or reviews for apps you don't have listed publicly.

**Why do I get fewer reviews than the store's rating count?** Most ratings are stars only, without text. Stores only publish ratings that come with a written review.

**Why is `appName` localized?** The name comes from the store in the chosen country/language, e.g. a German title for `country: "de"`.

**Can I use it through the API or with AI agents?** Yes. Call it through the Apify API, the Apify MCP server or any Apify integration. Pricing is per event only, so agent payments work too.

**Is scraping app reviews legal?** The actor only collects publicly available reviews. Reviews contain user nicknames and free text, so you are responsible for how you store and use them (e.g. GDPR) and for complying with the stores' terms.

**Disclaimer:** This actor is not affiliated with, endorsed by or sponsored by Apple or Google. App Store is a trademark of Apple Inc.; Google Play is a trademark of Google LLC.

### Related actors

- [trustpilot-reviews](https://apify.com/cprussin/trustpilot-reviews): Trustpilot reviews, ratings and TrustScore for any company.
- [product-hunt-launches](https://apify.com/cprussin/product-hunt-launches): Product Hunt launches, leaderboards, upvotes and makers.
- [google-trends](https://apify.com/cprussin/google-trends): Google Trends interest over time, regions, related queries and trending searches.

# Actor input Schema

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

App Store or Google Play URLs, or IDs. The store is detected automatically: https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580, id324684580 or 324684580 = App Store; https://play.google.com/store/apps/details?id=com.spotify.music or com.spotify.music = Google Play. Prefix with apple: to use an iOS bundle ID (apple:com.spotify.client).

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

Two-letter country code of the store (us, gb, de, fr, jp, br, in, ...). App Store reviews are per country; Google Play reviews are filtered by it.

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

Two-letter language code (en, de, es, pt, ja, ...). Google Play returns reviews written in this language. The App Store has no language filter.

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

Newest first, or the store's "most relevant" / "most helpful" order.

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

Stop after this many reviews for each app. Each review is billed as one event.

## `sinceDate` (type: `string`):

Only reviews posted on or after this date: YYYY-MM-DD, or relative like "7 days" or "1 month". With sort = Newest, scraping stops as soon as older reviews are reached, so scheduled runs only pay for new reviews.

## `onlyNew` (type: `boolean`):

Return only reviews not returned by an earlier run with the same apps, country, language and rating filter. Schedule the actor daily for new-review alerts: the first run is a baseline, later runs output (and bill) only new reviews. Forces sort = Newest. State is kept in the key-value store "app-store-reviews-state" in your account.

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

Only reviews with at least this many stars (1-5).

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

Only reviews with at most this many stars (1-5). Set to 2 to collect complaints only.

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

Optional. Not needed for normal volumes; use Apify Proxy for very large runs if the stores start rate-limiting.

## Actor input object example

```json
{
  "apps": [
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
    "https://play.google.com/store/apps/details?id=com.spotify.music"
  ],
  "country": "us",
  "language": "en",
  "sort": "newest",
  "maxReviewsPerApp": 20,
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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/spotify-music-and-podcasts/id324684580",
        "https://play.google.com/store/apps/details?id=com.spotify.music"
    ],
    "country": "us",
    "language": "en",
    "maxReviewsPerApp": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cprussin/app-store-reviews").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/spotify-music-and-podcasts/id324684580",
        "https://play.google.com/store/apps/details?id=com.spotify.music",
    ],
    "country": "us",
    "language": "en",
    "maxReviewsPerApp": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("cprussin/app-store-reviews").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/spotify-music-and-podcasts/id324684580",
    "https://play.google.com/store/apps/details?id=com.spotify.music"
  ],
  "country": "us",
  "language": "en",
  "maxReviewsPerApp": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call cprussin/app-store-reviews --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cprussin/app-store-reviews"
        }
    }
}
```

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/bxfWqie7OryROJyzK/builds/9rB03fkbgTg0lES1o/openapi.json
