# Google Play Scraper: Apps, Search & Reviews (`rjmacarthy/google-play-scraper`) Actor

Scrape Google Play: full app details (rating histogram, installs, price, version, similar apps), search results and reviews with sort and star filters. Monitoring mode outputs only new reviews on each scheduled run. No login, no browser.

- **URL**: https://apify.com/rjmacarthy/google-play-scraper.md
- **Developed by:** [rj](https://apify.com/rjmacarthy) (community)
- **Categories:** Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.10 / 1,000 review scrapeds

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

## Google Play Scraper: Apps, Search & Reviews

**Google Play Scraper** gets app details, search results and reviews from the Google Play Store in one Actor and one run. Give it package names (`com.spotify.music`), Play URLs or search terms. It returns clean JSON: rating and 1–5★ histogram, installs, price, in-app purchases, ads, category, content rating, version, update date, description, screenshots and similar apps. For reviews you get the review text, stars, helpful votes, app version, date and the developer's reply. Most review scrapers re-download the same reviews every day. This one has a **monitoring mode**: schedule it, and each run outputs (and charges) **only the reviews posted since the last run**. When an app can't be scraped, you get a clear reason and the other apps continue, so one bad id never kills the run. No login, no browser, no proxy needed by default.

### What data can you get?

| App details (`type: "app"`) | Reviews (`type: "review"`) |
|---|---|
| Title, short description, full description (plain text) | Review id and link |
| Developer name, Play developer id, developer page, website | Reviewer's public display name |
| Average rating, number of ratings and written reviews | Stars (1–5) |
| Rating histogram (1★–5★ counts) | Review text |
| Installs ("1,000,000,000+"), minimum installs, Google's install figure | Helpful votes (thumbs up) |
| Price, currency, free flag, in-app purchase range, contains ads | App version the review was written for |
| Category, category id, tags | Review date (ISO 8601) |
| Content rating and descriptors | Developer reply text and date |
| Release date, last update, current version, required Android version | App id and title, country, language, sort order |
| What's new (release notes) | |
| Icon, feature graphic, screenshots, promo video | |
| Similar apps, more apps by the same developer (ids) | |
| Search query and rank (for apps found by search) | |

The developer's e-mail address, phone number and postal address are **not** collected. Neither are reviewers' avatars or account ids.

### Use cases

- **Review monitoring:** get new 1★ reviews in Slack every morning, track complaints after a release, and measure how fast support replies.
- **App store optimisation (ASO):** follow ratings, histograms, installs and release notes for your app and your competitors.
- **Competitor research:** search a keyword ("habit tracker", "budget app") and compare the top apps on price, rating, installs, monetisation and update frequency.
- **Sentiment analysis and AI:** feed thousands of reviews into an LLM or a BI dashboard, by language and country.
- **Market and investment research:** track install tiers and rating trends across a category.

### How to use it

1. Add apps to **Apps**: `com.spotify.music` or `https://play.google.com/store/apps/details?id=com.spotify.music`.
2. Choose how many reviews you want per app, the sort order (newest, most relevant, rating) and, if you like, a star filter.
3. Optionally add **Search queries** to find apps by keyword.
4. Set **Country** (`us`, `gb`, `de`...) and **Language** (`en`, `de`, `pt-BR`...).
5. Click **Start**, then download the results as JSON, CSV or Excel, or read them through the API.

#### Example: the 100 newest reviews and app details for two apps

```json
{
    "appIds": ["com.spotify.music", "https://play.google.com/store/apps/details?id=com.duolingo"],
    "includeAppDetails": true,
    "includeReviews": true,
    "maxReviewsPerApp": 100,
    "reviewsSort": "newest",
    "country": "us",
    "language": "en"
}
```

#### Example: daily monitor of new 1★ reviews (schedule it daily)

```json
{
    "appIds": ["com.yourcompany.app"],
    "includeAppDetails": false,
    "includeReviews": true,
    "onlyNewReviews": true,
    "reviewsStarFilter": "1",
    "maxReviewsPerApp": 500,
    "monitorKey": "support-1-star",
    "country": "us",
    "language": "en"
}
```

#### Example: the top 20 apps for a keyword, with full details

```json
{
    "searchQueries": ["habit tracker", "meditation"],
    "maxSearchResults": 20,
    "includeReviews": false,
    "country": "gb",
    "language": "en"
}
```

| Field | What it does |
|---|---|
| `appIds` | Package names or Google Play app URLs. |
| `includeAppDetails` | Output one app item per app (default on). Switch it off to get reviews only. |
| `includeReviews` | Scrape reviews of the listed apps (default on). |
| `maxReviewsPerApp` | Review limit per app (default 100). 0 = no limit. |
| `reviewsSort` | `newest`, `mostRelevant` or `rating`. |
| `reviewsStarFilter` | `all` or `1`–`5`. |
| `onlyNewReviews` | Monitoring mode: output only reviews not output by earlier runs of this monitor. |
| `monitorKey` | Name of the monitor, so you can run several independent monitors on the same apps. |
| `searchQueries` | Keywords to search on Google Play. |
| `maxSearchResults` | Apps per search query (default 10; 0 = all on the results page, about 20–30). |
| `searchResultsOnly` | Output search results straight from the results page, without opening each app (faster; some fields are null). |
| `reviewsForSearchResults` | Also scrape reviews of the apps found by search. |
| `country`, `language` | Google Play's `gl` and `hl`. Prices, availability and search results follow the country. Reviews follow the language. |
| `proxyConfiguration` | Off by default. Turn on Apify Proxy if Google rate-limits your runs. |

### Output example

Real output from the default input (`com.spotify.music`, 20 newest reviews, US English), shortened:

```json
[
    {
        "type": "app",
        "id": "gplay:app:com.spotify.music:us:en",
        "appId": "com.spotify.music",
        "url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us",
        "title": "Spotify: Music and Podcasts",
        "summary": "Listen to songs, play podcasts, create playlists and discover music you'll love",
        "description": "With the Spotify music and podcast app, you can play millions of songs, albums and original podcasts for free. We have even added audiobooks, so you can enjoy t…",
        "developer": "Spotify AB",
        "developerId": "Spotify AB",
        "developerUrl": "https://play.google.com/store/apps/developer?id=Spotify+AB",
        "developerWebsite": "https://www.spotify.com",
        "privacyPolicyUrl": "https://www.spotify.com/legal/privacy-policy/",
        "score": 4.3491,
        "scoreText": "4.3",
        "ratingsCount": 36580138,
        "reviewsCount": 1857960,
        "histogram": { "1": 3719222, "2": 1068443, "3": 1310623, "4": 3106149, "5": 27375685 },
        "installs": "1,000,000,000+",
        "minInstalls": 1000000000,
        "realInstalls": 3181010787,
        "price": 0,
        "currency": "USD",
        "priceText": "Free",
        "free": true,
        "offersIAP": true,
        "iapRange": "$4.99 - $203.88 per item",
        "containsAds": true,
        "genre": "Music & Audio",
        "genreId": "MUSIC_AND_AUDIO",
        "categories": [{ "name": "Music & Audio", "id": "MUSIC_AND_AUDIO" }],
        "contentRating": "Teen",
        "contentRatingDescription": null,
        "released": "2014-05-27T13:12:17.255Z",
        "updated": "2026-11-02T11:59:56.030Z",
        "version": "Varies with device",
        "androidVersion": "Varies with device",
        "recentChanges": "We’re always making changes and improvements to Spotify. To make sure you don’t miss a thing, just keep your Updates turned on.",
        "icon": "https://play-lh.googleusercontent.com/IzQgYCcnCFCD08GR-3bdtcT8xzOvrNkC84avGT5CwTX2VIqmTmKKJcP_Cd4JoBOdmCMlTndlOzV6hrthg2fOWA",
        "headerImage": "https://play-lh.googleusercontent.com/WdedaGD6EAXZgy88wZM97aIcenQ5Cqzu_IUWBMMalkZmVe2lhv_3YqIUh-6pFqLv27kZ44cQX3qxyZTXHH-S91Q",
        "screenshots": ["https://play-lh.googleusercontent.com/c1jnjL-9CIFlwlTMX3xNyeo8aEH39sNuC5zpTHhfW8keGxQE3TBMRX9Rm3VqM3E03Cyl9AqtnxuKvxJpcW0WCA", "…"],
        "video": null,
        "similarApps": ["com.pinterest", "com.google.android.apps.youtube.music", "com.snapchat.android", "com.netflix.mediaclient", "com.duolingo", "com.zhiliaoapp.musically"],
        "moreByDeveloper": ["com.spotify.tv.android", "com.spotify.s4a", "fm.anchor.android", "com.spotify.kids", "com.whosampled"],
        "fullDetails": true,
        "searchQuery": null,
        "searchRank": null,
        "country": "us",
        "language": "en",
        "scrapedAt": "2026-11-02T13:31:04.470Z"
    },
    {
        "type": "review",
        "id": "gplay:review:65362f66-c012-4d61-a56a-744f928f0f3a",
        "reviewId": "65362f66-c012-4d61-a56a-744f928f0f3a",
        "appId": "com.spotify.music",
        "appTitle": "Spotify: Music and Podcasts",
        "url": "https://play.google.com/store/apps/details?id=com.spotify.music&reviewId=65362f66-c012-4d61-a56a-744f928f0f3a",
        "userName": "Robert Murcott",
        "score": 1,
        "text": "app very laggy and slow.",
        "thumbsUp": 0,
        "appVersion": "9.1.94.1929",
        "date": "2026-11-01T12:58:51.064Z",
        "replyText": "Hi. Thanks for reporting. Have you tried a quick reinstall? If that doesn't help, we'd recommend reaching out to our Customer Service at support.spotify.com. Just search “Contact Us”, and they'll be happy to help.",
        "replyDate": "2026-02-22T15:30:54.841Z",
        "sort": "newest",
        "country": "us",
        "language": "en",
        "scrapedAt": "2026-11-02T13:31:05.763Z"
    }
]
```

The dataset has three views: **Reviews**, **Apps** and **App details** (histogram, monetisation, compatibility). A **RUN_SUMMARY** record in the key-value store lists the status of every app and search (ok, not found, no reviews, blocked), plus counts and request statistics.

### Pricing

Pay per event: you pay only for what you get. There is no subscription and no fee per start beyond Apify's standard tiny run-start charge.

| Event | Price | When it's charged |
|---|---|---|
| `review` | **$0.0001** per review ($0.10 per 1,000) | Each review saved to the dataset |
| `app` | **$0.002** per app ($2 per 1,000) | Each app saved to the dataset, with full details or as a search-result summary |

Worked examples:

- **1,000 reviews ≈ $0.10.** 100,000 reviews ≈ $10.
- **Default input** (1 app + 20 reviews) ≈ $0.004.
- **Daily monitoring of 10 apps** with about 30 new reviews per app per day ≈ 300 reviews ≈ $0.03 per day, about $0.90 per month. A day without new reviews costs nothing beyond the run start.
- **Top 20 apps for 5 keywords** with full details = 100 apps ≈ $0.20.

Set **Maximum cost per run** in the run options. The Actor stops cleanly when the budget is reached, without overshooting it.

### Monitoring new reviews

1. Turn on **Only new reviews**, set **Max reviews per app** high enough for a day's reviews (e.g. 500), and give the monitor a name.
2. Create a **Schedule** in Apify Console (e.g. daily at 08:00) for this input.
3. Connect the dataset to Slack, e-mail, Google Sheets or a webhook (see Integrations).

The first run outputs the newest reviews up to your limit and remembers them. After that, each run outputs only the reviews posted since. Memory is kept per monitor, app, country, language and star filter in the named key-value store `google-play-scraper-state`. Google Play publishes some reviews with a delay, so every run looks back up to 48 hours and skips reviews it has already output. A late review is still caught, and nothing is output twice. If more new reviews arrive than your limit, or a run is cut short, the next run picks up the rest, as long as they are within 48 hours of the newest review. If a reviewer edits a review, it gets a new date, and it is output once more with the new text.

### Tips and limits

- **Search depth:** Google Play's web search shows about 20–30 apps per query, so that's the maximum per query. Use several related keywords to cover more.
- **Reviews are per language:** `language: "de"` returns reviews written in German. Run the Actor once per language you need.
- **Country matters:** prices, availability and search results follow `country`. An app that isn't available there is reported as "not found", and the other apps continue.
- **Very large review exports:** popular apps have millions of reviews. Use `maxReviewsPerApp` and a maximum cost per run. Pages hold up to 200 reviews each, so 100,000 reviews take about 500 requests.
- **Review dates:** `date` is the date of the review or of its last edit. That's why a developer reply can be older than the review it answers.
- **No app size or permissions:** Google Play's web pages no longer show app size, and permissions are not scraped.
- **"Varies with device"** is returned for `version` / `androidVersion` when Google shows no single value.
- **Rate limits:** the default speed (3 apps in parallel) works without a proxy in our tests. If Google answers HTTP 429 or a CAPTCHA, the run stops with a clear message instead of hammering. Turn on Apify Proxy and run again.
- **Layout changes:** Google changes its page data from time to time. The Actor reads each field from several places and falls back to the page's schema.org data, so a change usually costs a few fields rather than the whole run. If something looks wrong, please open an issue.

### FAQ

**Is it legal to scrape Google Play?**
This Actor reads only publicly available data that anyone can see in a browser without logging in. It does not collect personal contact data. Developer e-mails, phone numbers and addresses are skipped, and so are reviewer avatars and account ids. Reviewer display names are public, but they are still personal data in some jurisdictions (e.g. GDPR). You are responsible for using the data lawfully, for example for aggregated analysis, and for complying with Google's terms and the laws that apply to you. If in doubt, ask a lawyer.

**Do I need a Google account, API key or proxy?**
No. A proxy is optional, for when Google rate-limits a run.

**How is this different from other Google Play scrapers?**
One Actor does app details, search and reviews, with sort and star filters. Monitoring mode charges only for new reviews. Failures are reported honestly: a missing app or a block gets a clear status per app in RUN_SUMMARY, and the rest of the run continues and succeeds.

**Can I get reviews for several countries or languages?**
Yes, with one run per country/language combination. Schedule several tasks if you need it regularly.

**Why did my monitoring run output nothing?**
Then no new reviews were published since the last run. The status message says "no new reviews since the last run", and you are not charged for reviews.

**What does `realInstalls` mean?**
It's the install count Google embeds in the page next to the public tier ("1,000,000,000+"). Google doesn't document it, so treat it as an estimate.

### Integrations

- **API:** start runs and fetch results with the [Apify API](https://docs.apify.com/api/v2) or the JavaScript and Python clients. Use `?view=reviews` or `?view=apps` to get one item type.
- **Make, Zapier, n8n:** use the Apify modules to run the Actor and send new reviews to Slack, Sheets, Airtable, HubSpot or e-mail.
- **Webhooks:** trigger your own endpoint when a run finishes.
- **MCP / AI agents:** the Actor works as a tool through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp), so Claude, ChatGPT and other agents can pull Google Play data on demand.

### Changelog

- **0.1 (November 2026):** First release: app details, search (full or results-only), reviews with sort, star filter and pagination, monitoring mode for new reviews, pay per event (`review`, `app`).

### More scrapers by the same developer

- [Telegram Channel Scraper](https://apify.com/rjmacarthy/telegram-channel-scraper)
- [ATS Jobs Scraper: Greenhouse, Lever, Ashby & Workday](https://apify.com/rjmacarthy/ats-jobs-scraper)
- [Workday Jobs Scraper](https://apify.com/rjmacarthy/workday-jobs-scraper)
- [Google Ads Transparency Scraper](https://apify.com/rjmacarthy/google-ads-transparency-scraper)
- [Substack Scraper](https://apify.com/rjmacarthy/substack-scraper)
- [Dice Jobs Scraper](https://apify.com/rjmacarthy/dice-jobs-scraper)

Browse all my Actors on [my Apify Store profile](https://apify.com/rjmacarthy).

# Actor input Schema

## `appIds` (type: `array`):

Google Play package names (e.g. com.spotify.music) or app URLs (https://play.google.com/store/apps/details?id=com.spotify.music). One per line.

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

Output one item per app with its full Google Play listing: rating and histogram, installs, price, in-app purchases, ads, category, content rating, version, update date, description, screenshots, similar apps and more. Charged per app. Switch off to output reviews only.

## `includeReviews` (type: `boolean`):

Output the reviews of each app in "Apps". Charged per review.

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

Stop after this many reviews per app. 0 = no limit (popular apps have millions of reviews - set a 'Maximum cost per run').

## `reviewsSort` (type: `string`):

Order in which Google Play returns reviews.

## `reviewsStarFilter` (type: `string`):

Only reviews with this star rating, e.g. 1 to watch for complaints.

## `onlyNewReviews` (type: `boolean`):

Output only reviews that earlier runs of this monitor have not output yet (per app, country and language). The first run outputs the newest reviews up to the limit and remembers them; schedule the Actor (e.g. daily) and each later run outputs - and charges - only the reviews posted since. Reviews are read newest first. A review the author edits is output once more with its new text.

## `monitorKey` (type: `string`):

Name of this monitor's memory of seen reviews. Use different names to run independent monitors on the same apps (e.g. 'support-team' and 'product-team').

## `stateStoreName` (type: `string`):

Named key-value store in your account that keeps the monitoring state. Leave as is unless you want to separate it.

## `searchQueries` (type: `array`):

Search Google Play for apps, e.g. 'habit tracker'. Each app found is output with full details (charged per app). Google Play's web search shows about 20-30 apps per query.

## `maxSearchResults` (type: `integer`):

How many apps to take from each search, in Google Play's order. 0 = all apps on the results page (about 20-30).

## `searchResultsOnly` (type: `boolean`):

Output search results straight from the results page (title, developer, rating, installs text, price, genre, description, icon, screenshots) without opening each app. Same price per app, one request per query instead of one per app. Fields only the app page has (histogram, update date, version, similar apps...) are null.

## `reviewsForSearchResults` (type: `boolean`):

Scrape reviews (with the settings above) for every app found by search too, not only for the apps you listed.

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

Two-letter country code (Google's gl parameter): us, gb, de, in, br... Sets the store country for prices, availability and search.

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

Language code (Google's hl parameter): en, de, es, fr, pt-BR, ja... Google Play returns reviews written in this language, and listing texts in it when the developer provides a translation.

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

How many apps are processed at the same time. Keep it low to stay under Google's rate limits.

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

Not needed normally. If Google Play rate-limits the run (HTTP 429 / CAPTCHA), enable Apify Proxy.

## Actor input object example

```json
{
  "appIds": [
    "com.spotify.music",
    "https://play.google.com/store/apps/details?id=com.duolingo"
  ],
  "includeAppDetails": true,
  "includeReviews": true,
  "maxReviewsPerApp": 20,
  "reviewsSort": "newest",
  "reviewsStarFilter": "all",
  "onlyNewReviews": false,
  "monitorKey": "default",
  "stateStoreName": "google-play-scraper-state",
  "searchQueries": [
    "habit tracker"
  ],
  "maxSearchResults": 10,
  "searchResultsOnly": false,
  "reviewsForSearchResults": false,
  "country": "us",
  "language": "en",
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per review: date, stars, reviewer name, text, helpful votes, app version and developer reply.

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

One row per app: title, developer, rating, ratings count, installs, price, category, last update and version.

## `all` (type: `string`):

Every field of every app and review item.

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

Per-app and per-search status, counts, request statistics and warnings.

# 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 = {
    "appIds": [
        "com.spotify.music"
    ],
    "maxReviewsPerApp": 20,
    "reviewsSort": "newest",
    "country": "us",
    "language": "en",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rjmacarthy/google-play-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 = {
    "appIds": ["com.spotify.music"],
    "maxReviewsPerApp": 20,
    "reviewsSort": "newest",
    "country": "us",
    "language": "en",
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("rjmacarthy/google-play-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 '{
  "appIds": [
    "com.spotify.music"
  ],
  "maxReviewsPerApp": 20,
  "reviewsSort": "newest",
  "country": "us",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call rjmacarthy/google-play-scraper --silent --output-dataset

```

## MCP server setup

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