# Google Play Scraper — Apps, Reviews & ASO Data (Pay-Per-Event) (`prodiger/google-play-scraper`) Actor

Extract Google Play Store data with no API key: search apps by keyword, pull full listing details for any package ID, and harvest user reviews with developer replies. 50+ flat fields per app and 15 per review. Pay-per-event: $0.005/run + $2.30/1000 app details + $1.15/1000 reviews. No monthly fee.

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

## Pricing

Pay per event

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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 Scraper — Apps, Reviews & ASO Data (Pay-Per-Event)

Pull structured data straight out of the [Google Play Store](https://play.google.com/store) — **no API key, no Google account, no headless browser.** This is the **Pay-Per-Event** edition: there is no monthly rental and no minimum spend. **You pay per run plus per record you actually keep** — $0.005 to start a run, then $2.30 per 1,000 app details and $1.15 per 1,000 reviews on the Free tier.

Run it on the Apify platform for scheduling, REST API access, dataset exports (JSON, CSV, Excel, HTML), proxy rotation, monitoring, and native integrations with Make, Zapier, Google Sheets, Slack, and 5,000+ other tools.

### What does Google Play Scraper do?

This actor reads Google Play's **public** listing and review pages and hands you back clean, flat JSON. It runs in one of three modes:

- **🔍 Search** — hand it keywords (e.g. `fitness tracker`) and get back the matching apps: title, package ID, developer, price, rating, icon, and store URL. Ideal for discovering apps in a niche.
- **📱 Details** — hand it package IDs (e.g. `com.whatsapp`) and get the **full listing**: 50+ fields including install ranges, the ratings histogram, in-app-purchase price range, developer contact details, changelog, screenshots, and content rating.
- **⭐ Reviews** — hand it package IDs and get user reviews: star rating, headline, body, reviewer name, thumbs-up count, app version, and the **developer's public reply** to each review. Paginates automatically and filters by star rating.

Every field lands in a single flat row — no nested objects to flatten — so the output drops straight into a spreadsheet, a database, or an LLM prompt.

#### Where do I find an app's package ID?

It's the `id=` value in any Google Play URL:

````

https://play.google.com/store/apps/details?id=com.spotify.music
^^^^^^^^^^^^^^^^^^
package ID

````

You can paste the **whole URL** into `appIds` too — the actor extracts the package ID for you. Common IDs: WhatsApp → `com.whatsapp`, Spotify → `com.spotify.music`, Instagram → `com.instagram.android`, TikTok → `com.zhiliaoapp.musically`.

### Why use Google Play Scraper?

- **App Store Optimization (ASO)** — See which apps rank for a keyword and study their metadata to inform your own listing.
- **Competitive intelligence** — Track a competitor's rating drift, install-range jumps, changelog cadence, and review sentiment over time.
- **Market research** — Build datasets of an entire app category across countries and languages.
- **Voice-of-customer / support** — Pull 1-star reviews for your own app to triage complaints, and read how competitors reply to theirs.
- **Lead generation** — Extract developer email, website, and legal-entity contact details from listings.

### How to use Google Play Scraper

1. Click **Try for free** on this actor's page.
2. Pick a **Mode**: `search`, `details`, or `reviews`.
3. Fill in the matching input:
   - *Search* → one or more **Search terms**.
   - *Details* / *Reviews* → one or more **App IDs** (package names or full Play Store URLs).
4. Optionally set **Country** and **Language** for localized results, and **Max results** to cap cost.
5. In *reviews* mode, choose a **Review sort order** and, if you want, a **star-rating filter**.
6. Click **Save & Start**. Rows stream into the dataset as they're scraped.
7. **Export** as JSON, CSV, Excel, or HTML — or read it from the [Dataset API](https://docs.apify.com/api/v2#/reference/datasets).

### Input

| Parameter | Type | Required | Description |
|---|---|---|---|
| `mode` | string | No | `search`, `details`, or `reviews`. Default `search`. |
| `searchTerms` | array | In `search` | Keywords to search Google Play for. |
| `appIds` | array | In `details` / `reviews` | Package names (`com.whatsapp`) or full Play Store URLs. |
| `maxResults` | integer | No | Apps per search term, or reviews per app. Default `50`. |
| `country` | string | No | ISO 3166-1 alpha-2 storefront code. Default `us`. |
| `language` | string | No | ISO 639-1 language code. Default `en`. |
| `reviewSort` | string | No | `newest`, `rating`, or `relevant`. Default `newest`. |
| `reviewScore` | integer | No | Keep only reviews with this exact star rating (1–5); `0` = all. |
| `customMapFunction` | string | No | JS function body that transforms each row before it's saved. |
| `proxyConfiguration` | object | No | Apify Proxy. Default: Apify Proxy datacenter, AUTO rotation. |

#### Input examples

**Search two niches, 20 apps each:**

```json
{ "mode": "search", "searchTerms": ["fitness tracker", "workout app"], "maxResults": 20, "country": "us" }
````

**Full details for specific apps:**

```json
{ "mode": "details", "appIds": ["com.whatsapp", "com.telegram.messenger", "org.thoughtcrime.securesms"] }
```

**Only the 1-star reviews for one app:**

```json
{ "mode": "reviews", "appIds": ["com.spotify.music"], "maxResults": 100, "reviewSort": "newest", "reviewScore": 1 }
```

### Output

Results land in the run's default dataset — one row per **app** (search / details modes) or per **review** (reviews mode). Download as JSON, JSONL, CSV, Excel, or HTML.

#### Sample app record (details mode)

```json
{
    "appId": "com.whatsapp",
    "title": "WhatsApp Messenger",
    "summary": "Simple. Reliable. Private.",
    "developer": "WhatsApp LLC",
    "developerEmail": "android@support.whatsapp.com",
    "developerWebsite": "http://www.whatsapp.com/",
    "score": 4.64,
    "scoreText": "4.6",
    "ratings": 239669492,
    "histogram1star": 9773822,
    "histogram5star": 197121646,
    "installs": "10,000,000,000+",
    "minInstalls": 10000000000,
    "maxInstalls": 12152872767,
    "price": 0,
    "priceText": "Free",
    "free": true,
    "currency": "USD",
    "offersIAP": true,
    "IAPRange": "$0.40 - $199.99 per item",
    "containsAds": false,
    "genre": "Communication",
    "genreId": "COMMUNICATION",
    "released": "Oct 18, 2010",
    "updatedAt": "2026-07-25T02:25:41.000Z",
    "version": "VARY",
    "icon": "https://play-lh.googleusercontent.com/...",
    "screenshots": ["https://play-lh.googleusercontent.com/..."],
    "url": "https://play.google.com/store/apps/details?id=com.whatsapp&gl=us",
    "scrapedAt": "2026-07-26T00:00:00.000Z"
}
```

#### Sample review record (reviews mode)

```json
{
    "reviewId": "9d041cca-a76b-4e40-9d3f-2f1c3a55c0e1",
    "appId": "com.spotify.music",
    "userName": "Jane D.",
    "score": 4,
    "scoreText": "4",
    "text": "Great app but the ads are too frequent on the free tier",
    "date": "2026-07-24T21:32:49.558Z",
    "replyText": null,
    "replyDate": null,
    "thumbsUp": 7,
    "version": "9.1.62.1601",
    "scrapedAt": "2026-07-26T00:00:00.000Z"
}
```

#### Data table

| Field | Type | Description |
|---|---|---|
| `appId` | string | Package name / app ID |
| `title` | string | App name |
| `summary` | string | Short tagline |
| `description` | string | Full listing description |
| `developer` | string | Developer / publisher name |
| `developerId` | string | Developer page ID |
| `developerEmail` | string | Developer contact email |
| `developerWebsite` | string | Developer website |
| `score` | number | Average rating (1.0–5.0) |
| `ratings` | integer | Total rating count |
| `reviews` | integer | Total review count |
| `histogram1star`–`histogram5star` | integer | Rating distribution per star |
| `installs` | string | Human-readable install range (`10,000,000+`) |
| `minInstalls` / `maxInstalls` | integer | Numeric install bounds |
| `price` / `priceText` / `free` / `currency` | mixed | Pricing |
| `offersIAP` / `IAPRange` | mixed | In-app purchases and price range |
| `containsAds` | boolean | Whether the app shows ads |
| `genre` / `genreId` | string | Category |
| `released` / `updatedAt` / `version` | mixed | Release date, last update (ISO), version |
| `recentChanges` | string | Latest changelog |
| `icon` / `headerImage` / `screenshots` | mixed | Media URLs |
| `contentRating` | string | Age rating |
| `url` | string | Store URL |
| `searchTerm` | string | The keyword that surfaced the app (search mode) |
| `reviewId` | string | Unique review ID (reviews mode) |
| `userName` / `userImage` | string | Reviewer name and avatar |
| `text` / `title` | string | Review body and headline |
| `date` | datetime | Review timestamp (ISO) |
| `replyText` / `replyDate` | mixed | Developer's public reply |
| `thumbsUp` | integer | Helpful votes |
| `scrapedAt` | datetime | When this row was emitted (ISO) |

### Pricing / How much does it cost to scrape Google Play?

This actor uses **Pay-Per-Event** pricing — no monthly rental, no compute-unit surprises.

| Event | Fires when | Free tier |
|---|---|---|
| **Actor start** | Once per run | **$0.005** |
| **App detail** | Per app row (search or details mode) | **$2.30 / 1,000** ($0.0023) |
| **Review** | Per review row (reviews mode) | **$1.15 / 1,000** ($0.00115) |

Higher Apify subscription tiers get better per-record rates — see the **Pricing** tab on this actor's listing for the full table (Business Gold pays $1.20/1,000 app details and $0.60/1,000 reviews).

**Cost examples (Free tier):**

| Workload | Cost |
|---|---|
| Search 2 terms × 25 apps | $0.005 + 50 × $0.0023 = **$0.12** |
| Details for 20 apps | $0.005 + 20 × $0.0023 = **$0.051** |
| 200 reviews for 1 app | $0.005 + 200 × $0.00115 = **$0.235** |
| 100 apps + 50 reviews each | $0.005 + 100 × $0.0023 + 5,000 × $0.00115 = **$5.985** |

To enforce a hard ceiling, set **Maximum charge per run** before launching — the actor stops emitting new records once that limit is reached.

### Tips and advanced options

- **Start small.** Set `maxResults: 10` to preview the data shape before a large run.
- **Search → details.** Search results carry a smaller field subset. Feed the discovered `appId`s into *details* mode for the full 50+-field record.
- **Set country and language together** for accurate localization — `country: "de"`, `language: "de"` gives the German storefront.
- **Filter reviews by rating** with `reviewScore: 1` to collect only 1-star feedback for product research.
- **De-duplication is automatic** — overlapping search terms won't emit (or bill for) the same app twice; reviews are de-duplicated by review ID across pages.
- **`customMapFunction`** runs in the actor container and receives each row as `item`; return a transformed object. Errors fall back to the untouched row.

### Errors and partial failures

A bad app ID, an app that doesn't exist in the chosen country, or a transient network error on one item does **not** abort the run. Each failure is written to a sidecar key-value store record named `errors-YYYY-MM-DD.jsonl` — check the **Key-value stores** tab on your run.

### FAQ, disclaimers, and support

**Do I need a Google account or API key?** No. The actor reads publicly accessible Google Play pages.

**Why are some fields null in search results?** Google Play's search response carries fewer fields than a full listing. Use `details` mode with the package IDs to get everything.

**Reviews returned fewer than I asked for?** Google limits how many reviews are reachable on public pages, and a star-rating filter naturally reduces the yield. Try removing `reviewScore` or changing `reviewSort`.

**Is this legal?** Scraping publicly available data is broadly lawful (see *hiQ Labs v. LinkedIn* in the US), and Google Play listings are public. You remain responsible for complying with Google's Terms of Service, applicable copyright, and data-protection law (GDPR/CCPA) — especially when handling reviewer data. Don't collect personal data beyond what your use case needs.

**How do I report a bug?** Open an issue on this actor's **Issues** tab.

# Actor input Schema

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

What to scrape. `search` finds apps by keyword. `details` returns full listing metadata for specific app IDs. `reviews` returns user reviews for specific app IDs. Default: search.

## `searchTerms` (type: `array`):

Keywords to search Google Play for (used in `search` mode). Each term is scraped independently up to `Max results`.

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

Google Play app package IDs (used in `details` and `reviews` modes), e.g. `com.whatsapp`. Full Play Store URLs are also accepted — the package ID is extracted from the `id=` parameter automatically.

## `maxResults` (type: `integer`):

In `search` mode: max apps returned per search term. In `reviews` mode: max reviews returned per app. Ignored in `details` mode (one record per ID). Default: 50.

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

ISO 3166-1 alpha-2 country code for the Google Play storefront to query, e.g. `us`, `gb`, `de`, `in`. Default: us.

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

ISO 639-1 language code for localized text (title, description, reviews), e.g. `en`, `de`, `es`. Default: en.

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

Sort order for reviews (used in `reviews` mode). `newest` = most recent first, `rating` = by star rating, `relevant` = Google's most-relevant/helpful order. Default: newest.

## `reviewScore` (type: `integer`):

When set to 1–5, only reviews with that exact star rating are returned (used in `reviews` mode). 0 = all ratings. Default: 0 (all).

## `customMapFunction` (type: `string`):

Optional JavaScript function body that transforms each scraped item before it is pushed to the dataset. Receives the item as argument `item` and must return the modified item. Errors are logged and the unmodified item is emitted. Example: `return { id: item.appId, name: item.title };`

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

Apify Proxy configuration. Default: Apify Proxy with AUTO rotation (datacenter). Google Play rate-limits per IP, so proxy rotation is recommended for large runs. Switch to RESIDENTIAL groups if you see frequent blocks.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [
    "fitness tracker",
    "habit tracker"
  ],
  "appIds": [
    "com.whatsapp",
    "com.spotify.music"
  ],
  "maxResults": 50,
  "country": "us",
  "language": "en",
  "reviewSort": "newest",
  "reviewScore": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Scraped apps (search / details modes) or reviews (reviews mode).

# 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 = {
    "searchTerms": [
        "fitness tracker",
        "habit tracker"
    ],
    "appIds": [
        "com.whatsapp",
        "com.spotify.music"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("prodiger/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 = {
    "searchTerms": [
        "fitness tracker",
        "habit tracker",
    ],
    "appIds": [
        "com.whatsapp",
        "com.spotify.music",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("prodiger/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 '{
  "searchTerms": [
    "fitness tracker",
    "habit tracker"
  ],
  "appIds": [
    "com.whatsapp",
    "com.spotify.music"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call prodiger/google-play-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Play Scraper — Apps, Reviews & ASO Data (Pay-Per-Event)",
        "description": "Extract Google Play Store data with no API key: search apps by keyword, pull full listing details for any package ID, and harvest user reviews with developer replies. 50+ flat fields per app and 15 per review. Pay-per-event: $0.005/run + $2.30/1000 app details + $1.15/1000 reviews. No monthly fee.",
        "version": "0.1",
        "x-build-id": "oP0f1C9EAPdvVyPgO"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/prodiger~google-play-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-prodiger-google-play-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/prodiger~google-play-scraper/runs": {
            "post": {
                "operationId": "runs-sync-prodiger-google-play-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/prodiger~google-play-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-prodiger-google-play-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "search",
                            "details",
                            "reviews"
                        ],
                        "type": "string",
                        "description": "What to scrape. `search` finds apps by keyword. `details` returns full listing metadata for specific app IDs. `reviews` returns user reviews for specific app IDs. Default: search.",
                        "default": "search"
                    },
                    "searchTerms": {
                        "title": "Search terms",
                        "type": "array",
                        "description": "Keywords to search Google Play for (used in `search` mode). Each term is scraped independently up to `Max results`.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "appIds": {
                        "title": "App IDs (package names)",
                        "type": "array",
                        "description": "Google Play app package IDs (used in `details` and `reviews` modes), e.g. `com.whatsapp`. Full Play Store URLs are also accepted — the package ID is extracted from the `id=` parameter automatically.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxResults": {
                        "title": "Max results per term / app",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "In `search` mode: max apps returned per search term. In `reviews` mode: max reviews returned per app. Ignored in `details` mode (one record per ID). Default: 50.",
                        "default": 50
                    },
                    "country": {
                        "title": "Country",
                        "type": "string",
                        "description": "ISO 3166-1 alpha-2 country code for the Google Play storefront to query, e.g. `us`, `gb`, `de`, `in`. Default: us.",
                        "default": "us"
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "ISO 639-1 language code for localized text (title, description, reviews), e.g. `en`, `de`, `es`. Default: en.",
                        "default": "en"
                    },
                    "reviewSort": {
                        "title": "Review sort order",
                        "enum": [
                            "newest",
                            "rating",
                            "relevant"
                        ],
                        "type": "string",
                        "description": "Sort order for reviews (used in `reviews` mode). `newest` = most recent first, `rating` = by star rating, `relevant` = Google's most-relevant/helpful order. Default: newest.",
                        "default": "newest"
                    },
                    "reviewScore": {
                        "title": "Filter reviews by star rating",
                        "minimum": 0,
                        "maximum": 5,
                        "type": "integer",
                        "description": "When set to 1–5, only reviews with that exact star rating are returned (used in `reviews` mode). 0 = all ratings. Default: 0 (all).",
                        "default": 0
                    },
                    "customMapFunction": {
                        "title": "Custom map function",
                        "type": "string",
                        "description": "Optional JavaScript function body that transforms each scraped item before it is pushed to the dataset. Receives the item as argument `item` and must return the modified item. Errors are logged and the unmodified item is emitted. Example: `return { id: item.appId, name: item.title };`"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy configuration. Default: Apify Proxy with AUTO rotation (datacenter). Google Play rate-limits per IP, so proxy rotation is recommended for large runs. Switch to RESIDENTIAL groups if you see frequent blocks.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
