# App Store Reviews Scraper & Google Play Reviews Monitor (`insanedev/app-store-google-play-reviews`) Actor

App Store and Google Play review scraper and monitor in one Actor: export to CSV, JSON or Excel, or schedule to get only new and low-star reviews. Rating and installs tracking. From $0.25 per 1,000 reviews.

- **URL**: https://apify.com/insanedev/app-store-google-play-reviews.md
- **Developed by:** [Insane Developer](https://apify.com/insanedev) (community)
- **Categories:** Developer tools, Marketing, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.25 / 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 Store & Google Play Reviews Scraper & Monitor** gets reviews from both stores in one run, from every App Store country and in any Google Play language. Put it on a schedule and each run returns only the reviews that are new since the last run, plus each app's rating, star histogram and exact Google Play installs with the change since the previous run.

You don't need a login or an API key. Get a clean dataset through the API, as JSON, CSV or Excel, or send it straight to Slack, Google Sheets, Make, n8n or Zapier. Pricing: $0.35 per 1,000 reviews on the Free plan ($0.25 on Gold) and $0.004 per app snapshot. Error rows and the digest are free.

### What does it do?

- App Store reviews: the newest reviews of any iPhone or iPad app from one country, several, or all 175 App Store countries, with stars, title, text, author, date, app version and helpful votes.
- Google Play reviews in any language, up to 100,000 per app and language, with developer replies and their dates, thumbs-up votes and the app version.
- A review monitor. In *Monitor* mode the first run saves a baseline and every later run delivers only the reviews that arrived since, so reviews you already have are not delivered or charged again and there is nothing to deduplicate (see the FAQ on edited reviews).
- App rating and installs tracking: one row per app and country with the rating, rating count, star histogram (1 to 5 stars), exact Google Play installs (7,795,778,219 for Instagram, where the store page says "5B+"), version, last update and release notes. Monitor runs add the change since the last run, ratings per day and installs per day.
- A digest for Slack or e-mail. Each monitor run adds one free row with a ready-to-send message: new reviews, new 1- and 2-star reviews with links, rating changes and installs per day.

### How to use it

#### One-off export

1. Click **Try for free** and paste App Store or Google Play links, App Store ids (`389801252`) or package names (`com.instagram.android`) into **Apps**. The store is detected automatically.
2. Choose countries (App Store) and languages (Google Play) and how many reviews you want per app.
3. Run it and export the dataset as CSV, Excel or JSON. Reviews and app rows share one dataset: filter on `type`, or turn off app rows for a reviews-only file.

#### Daily monitor

1. Set **Mode** to *Monitor: only new reviews since the last run* and save the input as a task.
2. Schedule the task daily. The stores publish reviews about a day late, so a daily run is the natural rhythm.
3. Add a Slack or e-mail integration to the task that sends the digest row's `message`, or read the dataset from your own code.

Each saved task monitors on its own. To share the memory between tasks, set the same **Monitor name** in each.

### Input

| Field               | Default  | What it does                                                                                                                          |
| ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `apps`              | required | App Store / Google Play links, App Store ids or package names (up to 100)                                                             |
| `mode`              | `export` | `export` returns the newest reviews; `monitor` returns only reviews new since the last run, plus changes in the app rows and a digest |
| `countries`         | `["us"]` | App Store: reviews and app rows per country. Google Play: app rows per country (rating, histogram and price differ by country)        |
| `allAppleCountries` | `false`  | App Store reviews from all 175 storefronts (about 90 s per app); app rows stay limited to `countries`                                 |
| `languages`         | `["en"]` | Google Play review languages (`en`, `de`, `pt-BR`, …)                                                                                 |
| `maxReviewsPerApp`  | `100`    | Per app and country (App Store, at most 500) or per app and language (Google Play, up to 100,000). `0` returns app rows only          |
| `reviewsSince`      | none     | Only reviews from this date on: `2026-10-01` or `7 days`                                                                              |
| `ratings`           | all      | Only these star ratings, e.g. `["1","2"]` for complaints                                                                              |
| `includeAppDetails` | `true`   | App rows with rating, histogram, installs and release notes                                                                           |
| `monitorName`       | none     | Monitor name, so several tasks can share one memory                                                                                   |
| `strictStatus`      | `false`  | Fail the run when an app could not be read, so Apify alerts you                                                                       |

### Output

Everything goes into one dataset, and the `type` field tells the rows apart (`review`, `app`, `digest`, `error`). The **Reviews**, **App rows**, **Monitor digest** and **Errors** tabs show the columns of each kind, but every tab lists all rows, so filter on `type` in your spreadsheet or code. A field one store doesn't have is `null`, so App Store and Google Play rows share the same columns.

#### Review row (App Store)

From a real run; the author's name is shortened for this page.

```json
{
    "type": "review",
    "store": "appStore",
    "appId": "389801252",
    "appName": "Instagram",
    "country": "us",
    "language": null,
    "reviewId": "14635551041",
    "rating": 3,
    "title": "No full screen in iPad",
    "text": "Last two updates made the search 🔍 section (fourth from the top) reels show only in small squares, reels there don’t open full screen anymore, whichever one chooses.",
    "author": "Seaotter…",
    "date": "2026-10-06T19:40:25.000Z",
    "appVersion": "450.1.0",
    "helpfulVotes": 3,
    "developerReply": null,
    "developerReplyDate": null,
    "url": "https://apps.apple.com/us/app/id389801252?see-all=reviews",
    "isNew": null,
    "scrapedAt": "2026-10-08T22:37:42.746Z"
}
```

#### Review row (Google Play)

```json
{
    "type": "review",
    "store": "googlePlay",
    "appId": "com.instagram.android",
    "appName": "Instagram",
    "country": null,
    "language": "en",
    "reviewId": "a3559f53-742b-480e-b80c-938b49322dca",
    "rating": 2,
    "title": null,
    "text": "why on earth on every update ,you find out to include more bugs?! this app has more bugs than a giant clony",
    "author": "Ali G…",
    "date": "2026-10-07T20:16:21.000Z",
    "appVersion": "450.0.0.50.77",
    "helpfulVotes": 0,
    "developerReply": null,
    "developerReplyDate": null,
    "url": "https://play.google.com/store/apps/details?id=com.instagram.android&reviewId=a3559f53-742b-480e-b80c-938b49322dca",
    "isNew": null,
    "scrapedAt": "2026-10-08T22:37:42.746Z"
}
```

#### App row (Google Play)

In monitor mode the last six fields before `checkedAt` hold the change since the previous run.

```json
{
    "type": "app",
    "store": "googlePlay",
    "appId": "com.instagram.android",
    "appName": "Instagram",
    "developer": "Instagram",
    "country": "us",
    "rating": 3.9898,
    "ratingCount": 169601742,
    "histogram": { "1": 31888663, "2": 5359169, "3": 7086783, "4": 13527028, "5": 111740059 },
    "installsExact": 7795778219,
    "installsRange": "5,000,000,000+",
    "version": null,
    "lastUpdated": "2026-10-05T12:58:25.000Z",
    "releaseNotes": null,
    "price": 0,
    "currency": "USD",
    "genre": "Social",
    "url": "https://play.google.com/store/apps/details?id=com.instagram.android",
    "previousCheckedAt": null,
    "ratingDelta": null,
    "ratingCountDelta": null,
    "installsDelta": null,
    "ratingsPerDay": null,
    "installsPerDay": null,
    "checkedAt": "2026-10-08T22:37:42.746Z"
}
```

The App Store app row has the same fields: its `histogram` comes from the App Store page (Instagram US: 25,365,304 five-star and 1,230,168 one-star ratings), `version` is filled in, and the install fields are `null` because Apple doesn't publish installs.

#### Digest row (monitor mode)

From a real run about ten hours after the first one; two of the five listed 1★ reviews shown:

```text
App reviews monitor, 2026-10-09
New reviews: 178 (App Store 78, Google Play 100)
1–2★ new reviews: 66
• 1★ Instagram (Google Play, en): Recent addition is not perfect.... We wanna old version Someone please like my… — https://play.google.com/store/apps/details?id=com.instagram.android&reviewId=f6dd9d85-28bc-4628-b1dc-f6dfcc2cbd4a
• 1★ Instagram (Google Play, en): I don't what you guys did but you need to fix it. What happened to the just wat… — https://play.google.com/store/apps/details?id=com.instagram.android&reviewId=8b208ae1-027d-4d2c-b250-12c038a75528
Installs per day (Google Play):
• Instagram: +118,057
• Loop Habit Tracker: +5,937
```

The first run of a monitor saves the existing reviews as its baseline and says so in the digest. Every later run lists the new reviews per store, up to five new 1- and 2-star reviews with links, rating changes of 0.05 or more and Google Play installs per day.

#### Error row (free)

```json
{
    "type": "error",
    "store": "googlePlay",
    "appId": "com.example.doesnotexist.zz9",
    "country": null,
    "language": null,
    "reason": "app_not_found",
    "message": "No Google Play app with the package name com.example.doesnotexist.zz9.",
    "scrapedAt": "…"
}
```

Reasons: `app_not_found`, `not_available_in_country`, `no_reviews`, `rate_limited`, `store_error`, `parse_failed`, `charge_limit_reached`. One app failing never stops the others.

### Compared with other Actors

We ran the same input (Instagram on both stores, US/English, the 100 newest reviews per store) through this Actor and the most used review Actors on Apify Store (one for the App Store, two for Google Play), in the same minute on 2026-10-08:

|                                                      | This Actor                                           | Leading App Store Actor | Leading Google Play Actors (2)                                                 |
| ---------------------------------------------------- | ---------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |
| Same reviews as this Actor                           | (reference)                                          | 100 of 100              | 96 of 100 each (Google served slightly different snapshots of its 24 h window) |
| Duplicates                                           | 0                                                    | 0                       | 0                                                                              |
| Run time                                             | 3.6 s for **both stores** (200 reviews + 2 app rows) | 38.6 s                  | 30.7 s and 1.9 s                                                               |
| Both stores in one run                               | ✅                                                   | ❌                      | ❌                                                                             |
| Only new reviews since the last run                  | ✅                                                   | ❌                      | ❌                                                                             |
| App rows: rating, histogram, exact installs, changes | ✅                                                   | ❌                      | ❌                                                                             |
| Helpful votes                                        | ✅ both stores                                       | ❌                      | ✅                                                                             |
| Developer replies (Google Play)                      | ✅                                                   | n/a                     | ✅ in one of the two                                                           |
| Price per 1,000 reviews (Free plan)                  | $0.35                                                | $0.10                   | $0.10 and $0.15                                                                |

A cheaper per-review Actor on a schedule either downloads (and bills) reviews you already have again, or makes you guess how many are new. In monitor mode you pay only for the new ones.

### How much does it cost?

Pay per event. Error rows and the digest are free, duplicates are never delivered, and there is no start fee of our own (Apify adds its standard $0.00005 per run).

| Event                                          | Free & Starter | Scale         | Business      |
| ---------------------------------------------- | -------------- | ------------- | ------------- |
| Review                                         | $0.35 / 1,000  | $0.30 / 1,000 | $0.25 / 1,000 |
| App row (rating, histogram, installs, changes) | $0.004         | $0.0035       | $0.003        |

Examples (Free plan):

- The test above, 100 reviews from each store plus 2 app rows, costs $0.078.
- An indie developer monitoring 3 apps on both stores in 3 countries (App Store) or 3 languages (Google Play), with about 20 new reviews a day per app, store and country or language, pays about $3.80 a month for reviews and $2.20 for daily app rows, about $6 in total.

Set a maximum cost per run and the Actor stops cleanly when it reaches it, leaving an error row that says so.

At the end of each run, the Actor sends its developer an anonymous summary: the event counts and prices, the run cost, your Apify plan level (free or paid) and your pricing tier. The summary contains no input, output or account identifiers.

### Limits and FAQ

#### Why at most 500 App Store reviews per country?

Apple's public review feed shows only the newest 500 reviews per app and country. For more history, add countries or use `allAppleCountries`. Daily monitoring is never affected: few apps get 500 reviews a day in one country.

#### Why are the newest reviews about a day old?

Both stores publish reviews late. Google Play shows them exactly 24 hours after they're written, and the App Store usually one to two days after. A daily schedule doesn't miss any, because each run also re-reads the last three days.

#### Why does Google Play ignore the country for reviews?

Google Play groups reviews by language, not by country. Use `languages` for reviews and `countries` for app data such as rating, histogram and price, which do differ by country.

#### What about edited reviews?

Google Play dates a review by its last edit, and an edited review moves back to the top. Monitor mode remembers review ids for 7 days, so an edit within a week isn't delivered again; a review edited later comes back once with its new text.

#### Developer replies?

Google Play shows them and they're in the review rows. Apple's public review feed doesn't include replies.

#### "A Google user" as the author?

Some people review anonymously, and Google shows them under that name.

#### Is it legal?

The Actor reads only pages and feeds that anyone can open without an account, at a gentle pace and with an honest user agent. It never logs in, never solves captchas, and of the reviewer it returns only the public name they chose. You are responsible for how you use the data.

#### Can I use it from AI agents?

Yes, through the Apify API and the Apify MCP server.

Found a problem or need a feature? Open an issue in the Issues tab.

# Changelog

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

# Actor input Schema

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

App Store or Google Play links, App Store ids (<code>389801252</code>, <code>id389801252</code>) or Google Play package names (<code>com.instagram.android</code>), one per line. The store is detected automatically. Up to 100 apps per run.

## `mode` (type: `string`):

<b>Export</b>: the newest reviews of every app (up to the limit below).<br><b>Monitor</b>: for scheduled runs. The first run saves a baseline and returns the newest reviews; every later run returns <b>only reviews that are new since the last run</b>, app rows with rating, rating-count and install changes, and one digest row you can forward to Slack or e-mail.

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

Two-letter country codes (<code>us</code>, <code>gb</code>, <code>de</code>). App Store: reviews and app data per country. Google Play: app data per country (rating, star histogram, price); Google Play reviews depend on the language, not the country.

## `allAppleCountries` (type: `boolean`):

Read App Store reviews from all 175 storefronts (countries without reviews are skipped quietly). App rows are still made only for the countries above. About 90 seconds per app.

## `languages` (type: `array`):

Language codes for Google Play reviews (<code>en</code>, <code>de</code>, <code>pt-BR</code>). Each language is a separate set of reviews.

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

Per app and country on the App Store (at most 500: the App Store only shows the newest 500) and per app and language on Google Play (up to 100,000). In monitor mode: the most new reviews per run. 0 = app data only.

## `reviewsSince` (type: `string`):

Only reviews from this date on: a date (<code>2026-10-01</code>) or a period (<code>7 days</code>, <code>2 weeks</code>). Google Play dates are the time of the last edit.

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

Only reviews with these star ratings, e.g. 1 and 2 for complaints. Empty = all.

## `includeAppDetails` (type: `boolean`):

One row per app and country: rating, rating count, star histogram, exact Google Play installs, version, last update and release notes. In monitor mode also the changes since the last run (rating, ratings per day, installs per day).

## `monitorName` (type: `string`):

Monitor mode only. Runs with the same name share their memory of reviews already delivered. Leave empty to use the saved task (each task monitors on its own) or, without a task, the list of apps.

## `strictStatus` (type: `boolean`):

Mark the run as failed when an app could not be read (not found, not available, rate limited or a store error), so Apify can alert you. Apps without reviews do not count.

## Actor input object example

```json
{
  "apps": [
    "https://apps.apple.com/us/app/instagram/id389801252",
    "com.instagram.android"
  ],
  "mode": "export",
  "countries": [
    "us"
  ],
  "allAppleCountries": false,
  "languages": [
    "en"
  ],
  "maxReviewsPerApp": 100,
  "includeAppDetails": true,
  "strictStatus": false
}
```

# Actor output Schema

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

No description

## `apps` (type: `string`):

No description

## `digest` (type: `string`):

No description

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

No description

## `summary` (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/instagram/id389801252",
        "com.instagram.android"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("insanedev/app-store-google-play-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/instagram/id389801252",
        "com.instagram.android",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("insanedev/app-store-google-play-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/instagram/id389801252",
    "com.instagram.android"
  ]
}' |
apify call insanedev/app-store-google-play-reviews --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,insanedev/app-store-google-play-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/l59oN5qzvBBprcdOn/builds/iJQUtnQEGQIoQ3v5e/openapi.json
