# Google Play Scraper — App Search, Rank & App Details (`northbell/google-play-scraper`) Actor

Google Play search results by country with rank, so you see where apps rank for a keyword. Run again to get rank changes and new entries since the last run. Rating, installs, price and category per app; optional details (rating count) or lookup by package name. No login.

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

## Pricing

from $1.20 / 1,000 apps

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?

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 — App Search, Rank & App Details

Give it search terms, in the country and language you choose, and get one clean row per app in **Google Play's order**: **rank, name, developer, exact rating, installs, category, price and icon**. Add package names or Play URLs to look apps up directly, and switch on details to get the **number of ratings** and the content rating. **$1.50 per 1,000 apps**, no login, no API key.

Run it again — or put it on a daily schedule — and every search row also tells you **what changed since the last run**: the previous rank, the **rank change**, and whether the app is **new in the results**. Google Play only shows today's order, so the history is the one thing you have to collect yourself; this does it for you.

### What you get

| Field | What it is |
|---|---|
| `type` | `search-result` (an app in a search), `app` (looked up by package name or URL) or `error` |
| `search`, `country`, `language`, `rank` | the search term, the store country, the page language, and the position among the apps (an app that appears twice counts once) |
| `previousRank`, `rankChange`, `isNewInSearch` | compared with your previous run of the same search, country and language (`null` on the first run; a positive `rankChange` means the app moved up) |
| `appId`, `name`, `developer`, `url`, `iconUrl` | the app (`appId` is the package name, e.g. `com.ticktick.task`) |
| `rating` | the average rating with its decimals (4.718944), not the rounded 4.7 on screen; empty for an app without ratings |
| `category` | on search rows: the category as Google Play shows it in your language ("Productivity"). `app` rows have `categoryId` instead |
| `installs`, `installsMin` | the download bracket: `installs` is "10M+", `installsMin` the number (10000000) |
| `price`, `currency` | 0 for a free app |
| `ratingCount`, `categoryId`, `contentRating` | from the app's own page: how many ratings, the language-independent category (`PRODUCTIVITY`) and the age rating. On every `app` row, and on search rows when **Include app details** is on |
| `detailsError` | only on a search row whose app page could not be read; the rest of the row is still complete |
| `input` | on `app` rows: what you typed (package name or URL) |
| `observedAt` | when the row was read |
| `message` | on `error` rows: what went wrong (and which `search` or `input` it was) |

### Use it for

- **App store optimisation (ASO)** — track where your app and your competitors' rank for the keywords that matter, per country, and see who moved
- **Competitor and market research** — who ranks for a niche, how many installs they have, what they charge, and who just entered the results
- **Lead lists and reports** — apps by keyword with developer, rating and installs, exported to Sheets or your BI tool

### Input

```json
{ "searches": ["habit tracker", "focus timer"], "country": "gb", "language": "en", "maxResultsPerSearch": 30, "includeDetails": false, "apps": ["com.ticktick.task"] }
```

Rankings are remembered per search, country and language in a named key-value store in your Apify account, so the second run of the same Actor already shows rank changes. Schedule it (Apify → Schedules) for a daily history. The comparison uses the whole results page, so asking for 5 apps today and 30 tomorrow does not mark the lower ones as new.

### Pricing

**$1.50 per 1,000 apps**, plus $0.01 per run. Every app row is one app, whether it is ranked in a search or looked up. Error rows (a search without results, an unknown package name) are free. The $0.01 run-start fee is the one charge every run pays, even one that returns nothing.

### Notes

- Public data only: what a signed-out visitor sees on Google Play in that country and language. No developer emails, phone numbers or addresses are read or returned.
- **One results page per search: usually 30 apps** (a few pages hold more), and 30 is the most this Actor returns per search. Google Play loads more through an internal call that this Actor does not use.
- When the search words are an app's name (a brand, a game), Google Play shows **fewer results, often 5 to 25**, and starts the page with a **featured card** for that app. The featured card is rank 1. Its `category` is empty, and its `price` is empty unless details are on.
- The **"Similar apps" strip** that Google Play adds under such results is not a search result. It is not ranked and not returned.
- Google Play's web search showed **no ad cards** in our checks (72 searches: 12 terms in 6 countries). If a card ever carries an "Ad" or "Sponsored" label, it is not counted in the ranks.
- `country` decides which store you see (ranking, price, currency), `language` the language of names and categories. Results are what a signed-out visitor gets, not personalised.
- `installs` is a bracket, not a count: "10M+" means at least 10,000,000 downloads.
- **Include app details** opens one extra page per app (about 30 apps in 10 seconds). Apps you list in `apps` always get details. `ratingCount` and `rating` stay empty for apps that have no ratings yet.
- Apps that dropped out of the results since your last run are not listed; compare the `appId`s of two runs, or look for rows with `isNewInSearch: true` for the ones that came in.

For **reviews and why a rating moved**, see [Google Play Rating Tracker](https://apify.com/northbell/google-play-rating-tracker). For the same on the Apple App Store, see [App Store Scraper](https://apify.com/northbell/app-store-scraper).

### For AI agents

`{"searches": ["habit tracker"], "maxResultsPerSearch": 10}` returns the top 10 apps with rank, rating, installs and price. `{"searches": [], "apps": ["com.ticktick.task"]}` returns one row for that app. Rows have `type`: `search-result`, `app` or `error`.

# Actor input Schema

## `searches` (type: `array`):

What you would type in the Google Play search box (apps only). Each search returns the apps in Google Play's order with their rank. Leave empty if you only use "Apps" below.

## `apps` (type: `array`):

Apps to look up directly: package names (com.example.app) or Google Play URLs (play.google.com/store/apps/details?id=…). Each one returns a row with rating, number of ratings, installs, price and category.

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

Two-letter store country, e.g. us, gb, jp, de, in. Rankings, app names and prices differ by country.

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

Language of the Google Play page, e.g. en, ja, de, pt-BR. It sets the language of app names and category names.

## `maxResultsPerSearch` (type: `integer`):

How many apps to return for each search, in Google Play's order. One results page holds about 30 apps, so 30 is the most.

## `includeDetails` (type: `boolean`):

Also open each app's page to add the number of ratings, content rating and category ID. Slower: one extra page per app. Apps you list in "Apps" always get details.

## Actor input object example

```json
{
  "searches": [
    "habit tracker"
  ],
  "country": "us",
  "language": "en",
  "maxResultsPerSearch": 30,
  "includeDetails": false
}
```

# Actor output Schema

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

Apps in Google Play's order with rank, rank change since the last run, rating, installs, price and category.

# 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 = {
    "searches": [
        "habit tracker"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/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 = { "searches": ["habit tracker"] }

# Run the Actor and wait for it to finish
run = client.actor("northbell/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 '{
  "searches": [
    "habit tracker"
  ]
}' |
apify call northbell/google-play-scraper --silent --output-dataset

```

## MCP server setup

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