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

Every Google Play dataset behind one mode picker: the full app record for a package ID or link, ranked keyword search, a developer's public portfolio, or public reviews with developer replies. Each mode takes its own input and returns that dataset's fields.

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

## Pricing

from $0.06 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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 Scraper

One Actor for the whole Google Play surface. Pick a mode with `scraperType` and the run produces app records, ranked search results, a developer's portfolio, or public reviews — same dataset, same schema, one product to install.

| `scraperType` | What a row is | What you supply |
| --- | --- | --- |
| `appDetail` | One complete app listing | `package_ids` |
| `searchApps` | One ranked app card per result | `queries` |
| `developerApps` | One app from a publisher's portfolio | `developer_ids` |
| `reviews` | One public review | `package_ids` |

The form is grouped to match. Fill in the section for the mode you picked and leave the others alone; `language`, `country`, and `maxItems` apply to every mode.

### App details

```json
{
  "scraperType": "appDetail",
  "package_ids": [
    "com.spotify.music",
    "https://play.google.com/store/apps/details?id=com.duolingo"
  ],
  "language": "en_US",
  "country": "US",
  "maxItems": 0
}
```

Package IDs and Google Play links can be mixed in one list. Rows carry `package_id`, `title`, `description`, `summary`, `developer_name`, `developer_id`, `rating`, `ratings_count`, `installs`, `content_rating`, `category`, `released`, `updated`, `contains_ads`, `in_app_purchases`, `icon_url`, and `screenshots`.

A real US lookup for Spotify returned:

```json
{
  "package_id": "com.spotify.music",
  "title": "Spotify: Music and Podcasts",
  "developer_name": "Spotify AB",
  "developer_id": "6523013212965523194",
  "rating": 4.314022,
  "ratings_count": 34006997,
  "installs": "1,000,000,000+",
  "content_rating": "Teen",
  "released": "May 27, 2014",
  "updated": "Aug 18, 2026",
  "contains_ads": true,
  "in_app_purchases": "$6.99 - $203.88 per item"
}
```

### Keyword search

```json
{
  "scraperType": "searchApps",
  "queries": ["spotify", "weather radar"],
  "language": "en_US",
  "country": "US",
  "maxItems": 100
}
```

Each entry in `queries` is searched separately and every row keeps the `search_query` that produced it, so several searches can share one dataset. Search rows are the compact card: `package_id`, `title`, `developer_name`, `rating`, `installs`, `category`, `description`, and `icon_url`.

### Developer portfolio

```json
{
  "scraperType": "developerApps",
  "developer_ids": ["Spotify AB"],
  "language": "en_US",
  "country": "US",
  "maxItems": 100
}
```

The developer value can be the displayed name or the `developer_id` found on an app record. Rows are the same card shape as search, with `source_developer_id` recording which input produced each one.

### Reviews

```json
{
  "scraperType": "reviews",
  "package_ids": ["com.spotify.music"],
  "language": "en_US",
  "country": "US",
  "maxReviews": 100,
  "sort": "newest"
}
```

`maxReviews` applies to each app and accepts 1–1,000, so three apps at 100 can save up to 300 rows. `sort` accepts `newest`, `helpful`, or `rating`. A review row carries `review_id`, `author`, `avatar_url`, `score`, `text`, `timestamp`, `helpful_count`, `developer_reply`, `app_version`, and the `sort` used:

```json
{
  "package_id": "com.spotify.music",
  "review_id": "87d30857-a229-4cdb-bf58-d77c08c04768",
  "author": "Jacob Gaynor",
  "score": 3,
  "text": "laggy",
  "timestamp": 1787335892,
  "helpful_count": 0,
  "developer_reply": null,
  "app_version": "9.1.76.2055",
  "sort": "newest"
}
```

### Things worth knowing before the first run

**Why is `maxItems` 100 rather than 0?** The four modes disagree about the right default — reading a supplied list of package IDs wants no cap, while a keyword search wants one — so the combined form ships the shared default of 100. Set it to `0` when you are feeding a long `package_ids` or `developer_ids` list and want the whole thing.

**Does `maxItems` cap the reviews mode?** No. Reviews are bounded by `maxReviews`, which is a per-app limit rather than a run total.

**One mode per run, or several?** One. `scraperType` selects a single dataset, and the other sections are ignored for that run. Chain runs when you need to search first and read details second.

**What happens when a lookup fails?** A package that is unknown or unavailable in the chosen `language` and `country` is skipped and the rest of the batch continues. A developer with no apps in that storefront, or an app with no public reviews, finishes successfully with no rows rather than failing. Fields Google Play does not publish come back as null or an empty list.

**Does raising `maxItems` return deeper search results?** No. Google Play decides how many apps a ranked search page lists; the cap can only reduce what is saved, never manufacture results the store stopped listing.

Prefer a narrower form? Each mode also ships on its own: [Google Play App Scraper](https://apify.com/thenetaji/google-play-app-scraper), [Google Play Search Scraper](https://apify.com/thenetaji/google-play-search-scraper), [Google Play Developer Apps Scraper](https://apify.com/thenetaji/google-play-developer-apps-scraper), and [Google Play Reviews Scraper](https://apify.com/thenetaji/google-play-reviews-scraper).

# Actor input Schema

## `scraperType` (type: `string`):

Choose the dataset for this run, then fill in the section for that mode below.

## `package_ids` (type: `array`):

Android package IDs or Google Play app links. Add one per line; links and IDs can be mixed.

## `queries` (type: `array`):

Keywords or phrases to search for. Each query is searched separately.

## `developer_ids` (type: `array`):

Google Play developer names or IDs. Add one per line.

## `maxReviews` (type: `integer`):

Maximum reviews to save for each app, from 1 to 1,000.

## `sort` (type: `string`):

Choose how Google Play orders reviews.

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

Locale used for app text and reviews, such as en\_US or de\_DE.

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

Two-letter country code used for availability and review locale.

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

Maximum records to save across the run. Set 0 for no limit.

## Actor input object example

```json
{
  "scraperType": "appDetail",
  "package_ids": [
    "com.spotify.music",
    "https://play.google.com/store/apps/details?id=com.duolingo"
  ],
  "queries": [
    "weather radar",
    "photo editor"
  ],
  "developer_ids": [
    "Spotify AB"
  ],
  "maxReviews": 50,
  "sort": "newest",
  "language": "en_US",
  "country": "US",
  "maxItems": 20
}
```

# Actor output Schema

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

All records scraped by this run

# 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 = {
    "scraperType": "appDetail",
    "package_ids": [
        "com.spotify.music"
    ],
    "queries": [
        "weather radar"
    ],
    "developer_ids": [
        "Spotify AB"
    ],
    "maxReviews": 50,
    "language": "en_US",
    "country": "US",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("thenetaji/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 = {
    "scraperType": "appDetail",
    "package_ids": ["com.spotify.music"],
    "queries": ["weather radar"],
    "developer_ids": ["Spotify AB"],
    "maxReviews": 50,
    "language": "en_US",
    "country": "US",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("thenetaji/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 '{
  "scraperType": "appDetail",
  "package_ids": [
    "com.spotify.music"
  ],
  "queries": [
    "weather radar"
  ],
  "developer_ids": [
    "Spotify AB"
  ],
  "maxReviews": 50,
  "language": "en_US",
  "country": "US",
  "maxItems": 20
}' |
apify call thenetaji/google-play-scraper --silent --output-dataset

```

## MCP server setup

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