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

Scrapes user reviews and ratings for any app on the Apple App Store or Google Play — from a single pasted link, in any country.

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

## Pricing

from $0.15 / 1,000 results

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

### What does App Store & Google Play Reviews Scraper do?

**App Store & Google Play Reviews Scraper** collects **user reviews and star ratings** for any mobile app on the [Apple App Store](https://apps.apple.com) and [Google Play](https://play.google.com/store/apps). Paste the app's link and get every review as a row: **rating, title, text, author, date, app version, helpful votes** and, on Google Play, the **developer's reply**. Each row also carries the app's own listing data, such as publisher, price, overall rating and category.

You can mix iPhone and Android apps in one run, and both land in the same table. Because it runs on the Apify platform, you also get API access, scheduled runs, integrations (Google Sheets, Slack, webhooks, Zapier and more) and run monitoring.

### Why scrape app reviews?

- **Find what users complain about most**, in their own words, and feed it to sentiment analysis or an LLM summary.
- **Catch a bad release early**: watch ratings and the reviewed app version after each update.
- **Benchmark competitors**: compare your app's reviews with a rival's on the same measures, across both stores.
- **Research a new market** by reading what users in a given country or language say before you launch there.
- **Check how developers respond**: Google Play rows include the developer's public reply and when it was posted.

### How to scrape App Store and Google Play reviews

1. Open the app's page on the App Store or Google Play and copy the address from your browser.
2. Paste it into **App links**. Add as many apps as you like, one per line, from either store.
3. Set **Max reviews per app** and, if you want, the **Countries** to read.
4. Click **Start** and wait for the run to finish.
5. Download the reviews from the **Output** tab, or fetch them through the API.

### Input

Everything is set on the **Input** tab. Only **App links** matters for a first run. A full Apple link (`https://apps.apple.com/us/app/whatsapp-messenger/id310633997`), a Google Play link (`https://play.google.com/store/apps/details?id=com.spotify.music`), a numeric Apple id or an Android package name all work.

```json
{
    "app_urls": [
        "310633997",
        "com.spotify.music"
    ],
    "max_reviews_per_app": 100,
    "countries": "us, gb, de",
    "sort_by": "newest",
    "star_rating": 1
}
```

- **Max reviews per app**: the limit for each app in each country.
- **Countries**: 2-letter codes, used for apps given as a bare Apple id or Android package name (as in the example above). A pasted link that already names a country (`/us/app/…` or `&gl=de`) uses only that one.
- **Sort reviews by**: newest, most relevant (most helpful on the App Store), or highest rating (Google Play only).
- **Only reviews with this many stars**: leave it empty for all ratings.

### Output

Each review is one item in the dataset. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Here is a shortened example; the review values are illustrative:

```json
{
    "store": "google_play",
    "app_id": "com.spotify.music",
    "country": "US",
    "app_url": "https://play.google.com/store/apps/details?id=com.spotify.music&gl=us",
    "app_name": "Spotify: Music and Podcasts",
    "app_publisher": "Spotify AB",
    "app_price": 0.0,
    "app_currency": "USD",
    "app_rating": 4.34,
    "app_rating_count": 36411746,
    "app_installs": "1,000,000,000+",
    "app_categories": ["Music & Audio"],
    "app_content_rating": "Teen",
    "app_updated_at": "2026-09-29T14:38:09+00:00",
    "review_id": "6f1c2a7e-3b9d-4c55-9e0a-2d7b8c1f4a90",
    "author": "Jane D.",
    "rating": 4,
    "title": null,
    "text": "Great playlists, but the app pauses now and then.",
    "review_version": "9.1.86.2432",
    "likes": 3,
    "posted_at": "2026-09-30T13:59:47+00:00",
    "developer_reply": "Thanks for the feedback! Please try reinstalling the app.",
    "developer_reply_at": "2026-09-30T18:02:11+00:00"
}
```

### Data fields

| Field | Description |
| --- | --- |
| `store` | `app_store` or `google_play` |
| `app_id` | Apple numeric id or Android package name |
| `country` | Country the reviews were read for (see the FAQ for how Google Play uses it) |
| `app_url` | Link to the app's store page |
| `app_name`, `app_publisher` | App name and publisher |
| `app_price`, `app_currency` | Price in that country's store |
| `app_rating`, `app_rating_count` | Overall star rating and number of ratings |
| `app_version` | Current version (on Google Play, only when one version serves every device) |
| `app_installs` | Install band, such as `1,000,000+` (Google Play only) |
| `app_categories`, `app_content_rating` | Store category and age rating |
| `app_released_at`, `app_updated_at` | First release and last update, in UTC |
| `review_id` | The store's id for the review |
| `author` | Reviewer's display name |
| `rating` | Stars given, 1–5 |
| `title` | Review title (App Store only; Google Play reviews have none) |
| `text` | Review text |
| `review_version` | App version the review was written about |
| `likes` | How many people marked the review helpful |
| `posted_at` | When the review was posted, in UTC |
| `developer_reply`, `developer_reply_at` | Developer's public reply and its date (Google Play only) |

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

The Actor uses pay-per-event pricing: **$0.00005 per run start and $0.00015 per review** saved. 1,000 reviews cost about **$0.15**, and platform usage is included. The $5 of monthly credit on Apify's free plan covers roughly 33,000 reviews. You pay only for reviews that are saved: apps that fail or have no reviews are not billed.

### Tips for scraping app reviews

- **Going deeper on the App Store**: Apple serves at most 500 reviews per app per country (10 pages of 50). To get more, give the app as its bare id (e.g. `310633997`) and add countries; each App Store country has its own reviews.
- **Google Play goes as deep as you ask.** Raise **Max reviews per app** to read further back.
- **Spend less**: keep **Max reviews per app** small and sort by newest for regular monitoring. Set a maximum cost per run, and the Actor stops cleanly when it is reached.
- **Only negative reviews**: set **Only reviews with this many stars** to 1. Google Play filters on its side. On the App Store the filter is applied to the up to 500 reviews each country offers, so you may get fewer.
- **Monitoring**: schedule the Actor daily with sort by newest and a small limit, then send new rows to Google Sheets or Slack.

### FAQ, disclaimers, and support

#### Is it legal to scrape App Store and Google Play reviews?

The Actor reads only reviews that the stores publish openly, without logging in. Reviews include **reviewers' display names, which are personal data** under rules such as the GDPR and CCPA. Only collect what you need, store it securely, and make sure you have a lawful reason to process it. Also check each store's terms of service for your use case. If you are unsure, ask a lawyer.

#### Why do Google Play countries return the same reviews?

Google Play groups reviews by **language, not country**. Each country you list reads reviews in its main language: `de` gives German reviews, `jp` Japanese, and most other countries English. A country whose language was already read for that app (for example `gb` after `us`) is skipped, so no review is saved or billed twice.

#### Why are developer replies missing for App Store reviews?

Apple's public review feed does not include developer replies, so `developer_reply` is always empty on App Store rows. Google Play rows include replies where the developer wrote one.

#### What happens to apps that could not be read?

Links that are not app links, apps that do not exist in a country, and apps with no reviews are listed in the **FAILED_INPUTS** record in the run's key-value store, with the reason. They never appear as dataset rows, so you are not charged for them. The run's status message summarises the outcome. A run is marked failed only when the stores failed to answer for every app it tried.

#### Support

Found a bug or need another field? Open an issue on the **Issues** tab and we will look into it. If you need a custom solution, such as another app store or a scheduled export into your own systems, get in touch through the Issues tab as well.

# Actor input Schema

## `app_urls` (type: `array`):

App links, one per line. Open the app's page on the App Store or Google Play and copy the address bar. Both stores work, and you can mix them in one run. If you already know the app id you can paste that instead — a number like 310633997 for Apple, or a package name like com.spotify.music for Google.

## `max_reviews_per_app` (type: `integer`):

Stops after this many reviews for each app, in each country. Google Play will keep going for as long as you ask; the App Store holds at most 500 per country.

## `countries` (type: `string`):

Comma-separated 2-letter codes, for example: us, gb, de, jp. On the App Store each country has its own reviews, so adding countries is how you get more of them. Google Play groups reviews by language instead: each country reads reviews in its main language (de → German, jp → Japanese, most others → English), and a country whose language is already covered is skipped. Ignored for any link that already names a country.

## `sort_by` (type: `string`):

The order reviews are read in, which decides which ones you get when there are more than the maximum. The App Store offers newest or most helpful; Google Play offers newest, most relevant or highest rating.

## `star_rating` (type: `integer`):

Leave empty for every rating. Google Play filters on its side, so you still get up to the maximum; on the App Store the filter is applied to the up-to-500 reviews each country offers.

## Actor input object example

```json
{
  "app_urls": [
    "https://apps.apple.com/us/app/whatsapp-messenger/id310633997",
    "https://play.google.com/store/apps/details?id=com.spotify.music"
  ],
  "max_reviews_per_app": 100,
  "countries": "us",
  "sort_by": "newest"
}
```

# Actor output Schema

## `dataset` (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 = {
    "app_urls": [
        "https://apps.apple.com/us/app/whatsapp-messenger/id310633997",
        "https://play.google.com/store/apps/details?id=com.spotify.music"
    ],
    "max_reviews_per_app": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("mina_safwat/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 = {
    "app_urls": [
        "https://apps.apple.com/us/app/whatsapp-messenger/id310633997",
        "https://play.google.com/store/apps/details?id=com.spotify.music",
    ],
    "max_reviews_per_app": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("mina_safwat/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 '{
  "app_urls": [
    "https://apps.apple.com/us/app/whatsapp-messenger/id310633997",
    "https://play.google.com/store/apps/details?id=com.spotify.music"
  ],
  "max_reviews_per_app": 100
}' |
apify call mina_safwat/app-reviews-scraper --silent --output-dataset

```

## MCP server setup

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