# Google Play Store Scraper - Apps, Reviews & ASO Ranks (`crawloop/google-play-scraper`) Actor

Scrape Google Play apps: metadata, reviews, keyword search, ASO keyword ranks, charts, similar apps, permissions, and Data safety. Multi-locale runs and monitor mode with webhooks. Fast HTTP — no browser.

- **URL**: https://apify.com/crawloop/google-play-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** Other, E-commerce, Developer 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 app / listing rows

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Play Store Scraper — Apps, Reviews, ASO Ranks & Monitor

> Unofficial tool for publicly accessible Google Play Store data. Google Play and related trademarks belong to Google LLC. Not affiliated with, sponsored by, or endorsed by Google LLC. Provided for informational use only; users must comply with applicable terms and laws.

**Google Play Store Scraper** ◄── you are here

| Actor | Platform |
| :--- | :--- |
| **Google Play Store Scraper** ◄── you are here | Android / Google Play |
| [Apple App Store Scraper](https://apify.com/crawloop/apple-app-store-scraper) | iOS / App Store |
| [App Stores Scraper — Apple & Google Play ASO](https://apify.com/crawloop/app-stores-scraper) | Apple + Google Play (combo) |

**Google Play scraper** for Apify — extract **Android app metadata**, **user reviews**, **keyword search**, **ASO keyword ranks**, **category / chart discovery**, **similar apps**, **permissions**, and **Data safety**. Optional **multi-locale** runs and **monitor** mode with webhook alerts for listing, version, price, rating, and new reviews. Lightweight HTTP (`curl_cffi` Chrome TLS fingerprint) — **no headless browser**.

Use it for competitor research, ASO rank tracking, review mining, compliance checks, and scheduled Play listing monitors. For iOS storefronts, use [Apple App Store Scraper](https://apify.com/crawloop/apple-app-store-scraper). For both stores in one run, use [App Stores Scraper — Apple App Store & Google Play ASO](https://apify.com/crawloop/app-stores-scraper).

### When to use this Actor

- ASO: track package rank for keywords across `hl` / `gl` locales
- Competitor cards: title, score histogram, installs, screenshots, what’s new
- Similar apps, permissions, and Data safety for market / compliance research
- Review intelligence (newest / helpful / rating sort, star filter, after-date)
- Category browse and top free / paid / grossing discovery
- Developer portfolio dumps (`developer_apps`)
- Cron monitors for version, price, rating, title/summary/icon, and negative reviews

### Modes

| Mode | What it does |
| :--- | :--- |
| `app_details` | Full metadata (+ optional similar / permissions / data safety) |
| `app_reviews` | Paginated reviews (sort, star filter, after-date) |
| `search_and_charts` | Keyword search, category browse, chart collections |
| `keyword_ranks` | SERP position of tracked apps × keywords × locales + KV history |
| `developer_apps` | Apps on a developer page (optional detail enrich) |
| `monitor` | Fingerprint deltas vs Key-Value Store + webhook |

### Key features

- **HTTP-only** — `curl_cffi` Chrome fingerprint; Residential proxy recommended for locales
- **ASO extras** — histogram, recent changes, similar apps, soft keyword hints in title/summary
- **Keyword ranks + history** — `keyword_rank` rows; optional named KV (`KEYWORD_RANK_HISTORY`)
- **Multi-locale** — `languages` × `countries` (cartesian, capped)
- **Monitor + webhooks** — version, price, rating, listing changes, negative reviews (Slack/Discord/custom)
- **Typed dataset rows** — `app`, `review`, `search_result`, `chart_result`, `similar_app`, `permission`, `data_safety`, `keyword_rank`, `change`

### Input parameters

| Parameter | Description |
|-----------|-------------|
| `mode` | See modes table above |
| `appIds` / `startUrls` | Package names or Play details URLs |
| `searchKeywords` | Keywords (`search_and_charts` / `keyword_ranks`; also ASO hints on details) |
| `trackAppIds` | Packages to locate in search (`keyword_ranks`) |
| `language` / `country` | Default `hl` / `gl` |
| `languages` / `countries` | Multi-locale matrix |
| `includeSimilarApps` / `includePermissions` / `includeDataSafety` | Detail enrichments |
| `enrichListings` / `maxSearchPages` | Full details for listings; search pagination |
| `chartType` / `category` | Charts / category browse |
| `developerId` / `developerUrl` / `enrichDeveloperApps` | Developer mode |
| `maxReviewsPerApp` / `reviewSort` / `reviewScoreFilter` / `reviewAfterDate` | Reviews |
| `rankHistoryStoreName` | KV for keyword rank snapshots |
| `monitorStoreName` / `monitorBaselineOnly` / `resetMonitorState` | Monitor state |
| `webhookUrl` / `notifyOn*` / `ratingDropThreshold` | Alerts |
| `maxItems` / `concurrency` | Caps and parallelism |
| `proxyConfiguration` | Apify Proxy (defaults to RESIDENTIAL when enabled) |

#### Example — app details + ASO extras

```json
{
  "mode": "app_details",
  "appIds": ["com.spotify.music", "com.whatsapp"],
  "includeSimilarApps": true,
  "includePermissions": true,
  "includeDataSafety": true,
  "searchKeywords": ["music streaming"],
  "language": "en",
  "country": "us"
}
```

#### Example — ASO keyword ranks (multi-country)

```json
{
  "mode": "keyword_ranks",
  "searchKeywords": ["music streaming", "podcasts", "spotify"],
  "trackAppIds": ["com.spotify.music"],
  "countries": ["us", "gb", "de"],
  "languages": ["en"],
  "rankHistoryStoreName": "google-play-rank-history",
  "maxItems": 100
}
```

#### Example — reviews

```json
{
  "mode": "app_reviews",
  "appIds": ["com.spotify.music"],
  "maxReviewsPerApp": 200,
  "reviewSort": "NEWEST",
  "language": "en",
  "country": "us"
}
```

#### Example — search + category charts

```json
{
  "mode": "search_and_charts",
  "searchKeywords": ["photo editor"],
  "category": "GAME_ACTION",
  "chartType": "topselling_free",
  "maxItems": 100,
  "language": "en",
  "country": "us"
}
```

#### Example — monitor + webhook

```json
{
  "mode": "monitor",
  "appIds": ["com.spotify.music", "com.instagram.android"],
  "monitorStoreName": "google-play-monitor-store",
  "monitorBaselineOnly": false,
  "monitorFetchReviews": true,
  "maxReviewsPerApp": 50,
  "webhookUrl": "https://hooks.example.com/google-play",
  "notifyOnNewVersion": true,
  "notifyOnRatingDrop": true,
  "notifyOnNegativeReviews": true,
  "notifyOnListingChange": true,
  "ratingDropThreshold": 0.2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

Run once with `"monitorBaselineOnly": true` to seed state without emitting deltas.

### Output

| Field | Description |
|-------|-------------|
| `recordType` | `app`, `review`, `search_result`, `chart_result`, `developer_app`, `similar_app`, `permission`, `data_safety`, `keyword_rank`, `change` |
| `appId` | Android package name |
| `title` / `summary` / `descriptionText` | Listing copy |
| `score` / `histogram` / `ratingsCount` | Ratings |
| `installs` / `minInstalls` / `realInstalls` | Install bands when present |
| `recentChanges` | What’s new text |
| `rank` / `found` / `searchQuery` | Search / chart / keyword rank |
| `permission` / `permissionType` | Permission rows |
| `sharedData` / `collectedData` / `securityPractices` | Data safety |
| `changeType` | `new_version`, `price_change`, `rating_drop`, `title_change`, `description_change`, `icon_change`, `new_review`, … |
| `language` / `country` | Locale of the scrape |
| `scrapedAt` | UTC collection time |

### Limitations

- Top **collection** charts via RPC can be sparse; **category** pages and `category/collection` HTML are more reliable.
- Search pagination depends on Play returning a continuation token (often first page only).
- Keyword ranks reflect the scraped SERP window; `found: false` if the package is not in returned results.
- Version may be missing (`Varies with device`); monitor prefers `updatedTimestamp` when present.
- Apify Proxy on some PPE plans may return **407** — the Actor falls back to direct egress and continues.

### Workflow tips

1. Seed ASO with `keyword_ranks` + a dedicated `rankHistoryStoreName`.
2. Schedule daily `keyword_ranks` (same store name) to build locale history.
3. Pair `monitor` + `notifyOnListingChange` for title / short description / icon moves.
4. Use `app_details` with similar + permissions + data safety for competitor packs.
5. Prefer Residential proxy for non-US `gl` / large review volumes; keep `concurrency` modest (default 4).

### Related Actors

| Actor | What it covers |
| :--- | :--- |
| **Google Play Store Scraper** ◄── you are here | Android apps, reviews, ASO ranks, monitor |
| [Apple App Store Scraper](https://apify.com/crawloop/apple-app-store-scraper) | iOS apps, games, reviews, ASO ranks, charts, monitor |
| [App Stores Scraper — Apple App Store & Google Play ASO](https://apify.com/crawloop/app-stores-scraper) | Both stores in one run (combo ASO) |

# Actor input Schema

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

What to scrape from Google Play Store.

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

Package names (e.g. com.spotify.music). Used by details, reviews, and monitor.

## `startUrls` (type: `array`):

Google Play app, search, developer, or category URLs. App IDs are extracted from details links.

## `searchKeywords` (type: `array`):

Keywords for search\_and\_charts / keyword\_ranks. Also used for soft ASO title/summary hints on app\_details.

## `trackAppIds` (type: `array`):

Package names to locate in search results (keyword\_ranks / search\_and\_charts). Emits keyword\_rank rows with position or found=false.

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

Optional hl codes. Combined with countries (cartesian, capped). Empty = use language.

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

Optional gl codes. Combined with languages (cartesian, capped). Empty = use country.

## `includeSimilarApps` (type: `boolean`):

In app\_details, also emit similar\_app rows from the details page cluster.

## `similarLimit` (type: `integer`):

Max similar\_app rows per source app.

## `includePermissions` (type: `boolean`):

In app\_details, fetch and emit permission rows.

## `includeDataSafety` (type: `boolean`):

In app\_details, fetch Data safety page and emit a data\_safety row.

## `enrichListings` (type: `boolean`):

Fetch full app details for each search/chart hit (like enrichDeveloperApps).

## `maxSearchPages` (type: `integer`):

Paginate search when Play returns a continuation token (1–10).

## `rankHistoryStoreName` (type: `string`):

Named Key-Value Store for keyword\_ranks snapshots. Default google-play-rank-history when mode is keyword\_ranks.

## `chartType` (type: `string`):

Top chart collection when no search keywords (or in addition to category).

## `category` (type: `string`):

Play category id for charts/category browse (e.g. GAME\_ACTION, MUSIC\_AND\_AUDIO).

## `developerId` (type: `string`):

Developer page id (e.g. Spotify+AB or Spotify AB). Used by developer\_apps.

## `developerUrl` (type: `string`):

Full developer page URL. Overrides developerId when set.

## `enrichDeveloperApps` (type: `boolean`):

When true, fetch full app details for each developer listing.

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

Play UI / content language code.

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

Store country code (affects prices, charts, availability).

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

Maximum reviews to fetch per app (reviews / monitor).

## `reviewSort` (type: `string`):

Sort order for reviews.

## `reviewScoreFilter` (type: `integer`):

0 = all scores; 1–5 = only that star rating.

## `reviewAfterDate` (type: `string`):

ISO date/time (e.g. 2026-01-01 or 2026-01-01T00:00:00Z). Skip older reviews when sorting NEWEST.

## `maxItems` (type: `integer`):

Hard cap on dataset rows pushed this run (0 = unlimited).

## `concurrency` (type: `integer`):

Parallel HTTP workers for multi-app fetches.

## `monitorStoreName` (type: `string`):

Named Apify Key-Value Store for monitor state. Use a distinct name per watchlist/schedule.

## `monitorBaselineOnly` (type: `boolean`):

First/seed monitor run: save state without emitting deltas or charging.

## `resetMonitorState` (type: `boolean`):

Clear MONITOR\_STATE in the named store before this run.

## `monitorFetchReviews` (type: `boolean`):

In monitor mode, also pull newest reviews and emit only new ones.

## `webhookUrl` (type: `string`):

Optional HTTPS endpoint (Slack/Discord Incoming Webhook or custom). Receives JSON POSTs on configured monitor events.

## `notifyOnNewVersion` (type: `boolean`):

Fire webhook when version or updated timestamp changes.

## `notifyOnRatingDrop` (type: `boolean`):

Fire webhook when score drops by ratingDropThreshold or more.

## `notifyOnPriceChange` (type: `boolean`):

Fire webhook when price or currency changes.

## `notifyOnNegativeReviews` (type: `boolean`):

Fire webhook for new reviews with score <= 2.

## `notifyOnListingChange` (type: `boolean`):

Fire webhook when title, short description (summary), or icon changes.

## `ratingDropThreshold` (type: `number`):

Minimum score drop to emit rating\_drop (e.g. 0.2).

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

Apify Proxy recommended. When enabled without groups, the Actor defaults to RESIDENTIAL. On proxy 407/auth failures it falls back to direct egress.

## Actor input object example

```json
{
  "mode": "app_details",
  "appIds": [
    "com.spotify.music",
    "com.whatsapp"
  ],
  "startUrls": [
    {
      "url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us"
    }
  ],
  "searchKeywords": [
    "photo editor"
  ],
  "trackAppIds": [
    "com.spotify.music"
  ],
  "includeSimilarApps": false,
  "similarLimit": 40,
  "includePermissions": false,
  "includeDataSafety": false,
  "enrichListings": false,
  "maxSearchPages": 3,
  "rankHistoryStoreName": "",
  "chartType": "",
  "category": "",
  "developerId": "",
  "developerUrl": "",
  "enrichDeveloperApps": false,
  "language": "en",
  "country": "us",
  "maxReviewsPerApp": 100,
  "reviewSort": "NEWEST",
  "reviewScoreFilter": 0,
  "reviewAfterDate": "",
  "maxItems": 0,
  "concurrency": 4,
  "monitorStoreName": "google-play-monitor-store",
  "monitorBaselineOnly": false,
  "resetMonitorState": false,
  "monitorFetchReviews": true,
  "webhookUrl": "",
  "notifyOnNewVersion": true,
  "notifyOnRatingDrop": true,
  "notifyOnPriceChange": true,
  "notifyOnNegativeReviews": true,
  "notifyOnListingChange": true,
  "ratingDropThreshold": 0.2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset items (apps, reviews, keyword ranks, similar/permissions/data safety, search/chart hits, monitor deltas).

# 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",
        "com.whatsapp"
    ],
    "startUrls": [
        {
            "url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us"
        }
    ],
    "searchKeywords": [
        "photo editor"
    ],
    "trackAppIds": [
        "com.spotify.music"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/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",
        "com.whatsapp",
    ],
    "startUrls": [{ "url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us" }],
    "searchKeywords": ["photo editor"],
    "trackAppIds": ["com.spotify.music"],
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/google-play-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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",
    "com.whatsapp"
  ],
  "startUrls": [
    {
      "url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us"
    }
  ],
  "searchKeywords": [
    "photo editor"
  ],
  "trackAppIds": [
    "com.spotify.music"
  ]
}' |
apify call crawloop/google-play-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawloop/google-play-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/1xxdBGhuOvu1bjqOm/builds/aHAc6YPOWdYfXQRd4/openapi.json
