# Google Play Scraper: Apps, Ratings and Developer Contacts (`santamaria-automations/google-play-scraper`) Actor

Extract Google Play apps by search keyword or app ID. Returns title, developer with email, website and address, rating and histogram, install band, price, in-app purchase and ads flags, content rating, description, screenshots and similar apps. Pay per event.

- **URL**: https://apify.com/santamaria-automations/google-play-scraper.md
- **Developed by:** [NanoScrape](https://apify.com/santamaria-automations) (community)
- **Categories:** Lead generation, Other
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 app with details

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

Search [Google Play](https://play.google.com) apps by keyword, or look up apps by package name or app page URL. You get one record per app: title, developer with the contact details shown on the listing, rating and rating histogram, install band, price, in-app purchase and ads flags, content rating, release and update dates, description, screenshots and similar apps. Use it for app store research, competitor tracking, and lists of app publishers by niche with their public support email, website and address.

### What you get

One record per app. Fields that an app or a record type does not have are `null` (or an empty list).

There are two record types, shown in `record_type`:

- `detail`: the full record. Every field in the table below.
- `search`: only what the search list shows (the fields marked "search" below). Keyword results are returned as `detail` records by default (`includeDetails` on); a `search` record appears when you switch that option off, or as a fallback when an app's page could not be read.

| Field | Type | Records | Description |
|-------|------|---------|-------------|
| `record_type` | string | both | `detail` or `search` |
| `app_id` | string | both | Package name, for example `com.duolingo` |
| `title` | string | both | App title |
| `url` | string | both | Public app page |
| `summary` | string or null | detail | Short description |
| `developer` | string or null | both | Developer name |
| `developer_id` | string or null | detail | Developer ID |
| `developer_url` | string or null | detail | Developer page on Google Play |
| `developer_email` | string or null | detail | Support email shown on the listing |
| `developer_website` | string or null | detail | Developer website shown on the listing |
| `developer_address` | string or null | detail | Postal address shown on the listing |
| `developer_phone` | string or null | detail | Phone number shown on the listing, when given |
| `privacy_policy_url` | string or null | detail | Privacy policy link |
| `category` | string or null | both | Category name in the chosen language |
| `genre_id` | string or null | detail | Category ID, language independent, for example `EDUCATION` |
| `score` | number or null | both | Average rating, 1 to 5. `null` for apps without ratings |
| `ratings_count` | integer or null | detail | Number of ratings |
| `reviews_count` | integer or null | detail | Number of written reviews |
| `histogram` | object or null | detail | Ratings per star, keys `1` to `5` |
| `installs` | string or null | both | Install band as shown, for example `500,000,000+` |
| `installs_min` | integer or null | detail | Lower end of the install band |
| `installs_max` | integer or null | detail | Upper end of the band. Derived: the start of the next band minus one |
| `price` | number or null | both | Price in the store currency, `0` for free apps |
| `currency` | string or null | both | Currency code of the price |
| `free` | boolean or null | both | True when the price is 0 |
| `offers_iap` | boolean or null | detail | True when the app has in-app purchases |
| `iap_price_range` | string or null | detail | In-app purchase price range as shown on the listing |
| `contains_ads` | boolean or null | detail | True when the listing says the app contains ads |
| `content_rating` | string or null | both | Content rating label in the chosen language |
| `content_rating_descriptors` | string or null | detail | Content rating descriptors |
| `released` | string or null | detail | First release time (ISO 8601, UTC) |
| `released_text` | string or null | detail | First release date as shown in the chosen language |
| `updated` | string or null | detail | Last update time (ISO 8601, UTC) |
| `updated_text` | string or null | detail | Last update date as shown in the chosen language |
| `version` | string or null | detail | Always `null`: the app version is not on the listing page |
| `android_version` | string or null | detail | Always `null`: the minimum Android version is not on the listing page |
| `description` | string or null | both | Full description as plain text (search records: the short text of the search list) |
| `recent_changes` | string or null | detail | What's new text |
| `icon` | string or null | both | App icon |
| `header_image` | string or null | detail | Feature graphic |
| `screenshots` | array | both | Screenshot URLs |
| `video` | string or null | detail | Trailer URL when the listing has one |
| `similar_app_ids` | array | detail | App IDs of the similar apps shown on the listing |
| `permission_groups` | array | detail | Permission groups the app asks for |
| `top_chart_label` | string or null | detail | Top chart the app appears in, as shown on the listing |
| `top_chart_rank` | string or null | detail | Rank in that chart, for example `#1` |
| `country` | string | both | Store country used |
| `language` | string | both | Language used |
| `search_query` | string or null | both | Keyword that returned the app; `null` for app IDs |
| `scraped_at` | string | both | UTC timestamp, ISO 8601 |

Developer contact fields are exactly what the listing shows publicly. Many listings show an email and a website, fewer show an address or a phone number. Dates are given as ISO timestamps from the source's own time values, so they do not change with the language setting; the `_text` fields keep the localised wording.

Fill rates, measured in one local test series in October 2026 (US store, English, plus one run in the German store; 30 app page rows and 57 search rows over several runs, some apps appear more than once): on the 30 app pages every field above was present except `version` and `android_version` (always empty), `video` (2 of 30), `developer_phone` (19 of 30), `developer_website` (27 of 30), `iap_price_range` (27 of 30), `recent_changes` (27 of 30), `content_rating_descriptors` (15 of 30) and `top_chart_label` / `top_chart_rank` (5 of 30). On the search results title, developer, category, installs, price, content rating, description and icon were present on every row, and `score` on all but 2 apps without a rating. These figures describe this test series, not a general rate.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `searchQueries` | list of text | `["budget planner"]` when no keyword and no app is given | Keywords such as `habit tracker`. A comma or line separated text also works. |
| `appIds` | list of text | empty | Package names (`com.duolingo`) or app page URLs (`https://play.google.com/store/apps/details?id=com.duolingo`). Always returns the full record. |
| `country` | text | `us` | Two-letter store country: prices, ratings and availability follow it. |
| `language` | text | `en` | Language of titles, descriptions and labels, for example `de` or `pt-BR`. |
| `includeDetails` | boolean | `true` | Keyword results: open every app for the full record (billed as an app detail event). Off: search list fields only (billed as a search result event). |
| `maxResults` | integer | `50` | Maximum number of apps across all keywords and app IDs. `0` means no limit. The limit is shared equally between the entries; an unused share goes to the later ones. |
| `maxResultsPerQuery` | integer | `0` | Maximum number of apps for each keyword and each app ID. `0` means no separate limit. |
| `proxyConfiguration` | object | `{"useApifyProxy": true}` | Proxy settings. The default works for most runs. |

Numbers may be given as text (`"25"`). An empty input `{}` runs a small sample search (`budget planner`, up to 10 apps, with details) and the run status says so. If the input cannot be read, the actor runs that same sample and writes a warning to the log. The same keyword or app given twice is processed once, and an app that several searches find is delivered once. A pasted Google Play search URL is read as its keyword. Values that are neither a package name nor a Play URL are skipped and counted in the status message.

#### Example input

Search with full records:

```json
{
  "searchQueries": ["budget planner", "habit tracker"],
  "country": "us",
  "language": "en",
  "maxResults": 60
}
```

Look up apps:

```json
{
  "appIds": [
    "com.duolingo",
    "https://play.google.com/store/apps/details?id=com.spotify.music"
  ],
  "country": "de",
  "language": "de"
}
```

Search list fields only:

```json
{
  "searchQueries": ["chess"],
  "includeDetails": false,
  "maxResults": 30
}
```

#### Example output

A `detail` record (description shortened here; values taken from the saved sample):

```json
{
  "record_type": "detail",
  "app_id": "com.duolingo",
  "title": "Duolingo: Learn Languages",
  "url": "https://play.google.com/store/apps/details?id=com.duolingo",
  "summary": "Make language learning fun with Spanish, French, English, chess, math & music.",
  "developer": "Duolingo",
  "developer_id": "6957685454452609502",
  "developer_url": "https://play.google.com/store/apps/dev?id=6957685454452609502",
  "developer_email": "super-support@duolingo.com",
  "developer_website": "https://www.duolingo.com/help/support-request",
  "developer_address": "5900 Penn Ave\nPittsburgh, PA 15206\nUnited States",
  "developer_phone": "+1 412-567-6602",
  "privacy_policy_url": "https://www.duolingo.com/privacy",
  "category": "Education",
  "genre_id": "EDUCATION",
  "score": 4.746068,
  "ratings_count": 51342639,
  "reviews_count": 967244,
  "histogram": { "1": 946178, "2": 346561, "3": 1166036, "4": 5880965, "5": 43002849 },
  "installs": "500,000,000+",
  "installs_min": 500000000,
  "installs_max": 999999999,
  "price": 0,
  "currency": "USD",
  "free": true,
  "offers_iap": true,
  "iap_price_range": "$0.99 - $239.99 per item",
  "contains_ads": true,
  "content_rating": "Everyone",
  "content_rating_descriptors": "Users Interact, In-App Purchases",
  "released": "2013-05-29T12:18:00Z",
  "released_text": "May 29, 2013",
  "updated": "2026-10-26T19:44:49Z",
  "updated_text": "Oct 26, 2026",
  "version": null,
  "android_version": null,
  "description": "Learn a new language, chess, math & more with the world's most downloaded education app! ...",
  "recent_changes": "Our mascot owl, Duo, is trading in his usual diet of mice for bugs this week. ...",
  "icon": "https://play-lh.googleusercontent.com/tw_coGKgk1K_zO-Ypf9zBKV1s-KT3dYN1MIUxIqtnbfmON5x_YmuoAr31gE4oSfJHNtA-aStTd-qe9R8S6NVyA",
  "header_image": "https://play-lh.googleusercontent.com/Wwc5wGBb-gKpyD9oBTVwTQq2mhMLt1I5Ljdtv82tdILRMtAVGPINXcbMFZIiXraSfFOTw9_bBVipr--o1Vw0",
  "screenshots": ["https://play-lh.googleusercontent.com/twmCellsRXWs4bZsSXRv19x-3BIp19FzlQPdu_Va-zE10aL468HHFKJBvEOXo0g67Xsvl3nkIKnpjY7L62OOiA", "..."],
  "video": null,
  "similar_app_ids": ["com.zhiliaoapp.musically", "com.facebook.katana", "com.whatsapp", "com.spotify.music", "com.instagram.android"],
  "permission_groups": ["Identity", "Calendar", "Contacts", "Photos/Media/Files", "Storage", "Microphone", "Other"],
  "top_chart_label": "top free education",
  "top_chart_rank": "#1",
  "country": "us",
  "language": "en",
  "search_query": null,
  "scraped_at": "2026-10-27T12:00:00Z"
}
```

A `search` record (same fields, the ones the search list does not show are `null`):

```json
{
  "record_type": "search",
  "app_id": "com.droid4you.application.wallet",
  "title": "Wallet: Budget Expense Tracker",
  "url": "https://play.google.com/store/apps/details?id=com.droid4you.application.wallet",
  "developer": "BudgetBakers",
  "category": "Finance",
  "score": 4.61595,
  "installs": "10,000,000+",
  "price": 0,
  "currency": "USD",
  "free": true,
  "content_rating": "Everyone",
  "description": "Wallet is the all-in-one personal finance manager built to help you save money and plan for the future. ...",
  "developer_email": null,
  "ratings_count": null,
  "search_query": "budget planner"
}
```

(Other fields of the record are `null` or empty lists and left out of this example for space.)

### Pricing

Pay per result. The Pricing tab of this Actor shows the price of each event and the one-time start fee:

- `actor-start`: charged once per run, together with the first delivered app.
- `app-detail`: one per app delivered as a `detail` record. It is charged instead of, not on top of, `app-search-result`.
- `app-search-result`: one per app delivered as a `search` record.

You are charged only for apps that were delivered; a run that finds nothing costs nothing. If you set a maximum cost per run, the run stops at that limit and the status message says how many apps were delivered.

### Use with AI (MCP)

Add this actor as a tool in Claude or another MCP client:

```
https://mcp.apify.com?tools=santamaria-automations/google-play-scraper
```

Example prompts:

- "Find 30 budgeting apps in the US Play Store and list the developer email and website for each."
- "Get the rating, install band and last update date of com.duolingo and com.spotify.music."

### FAQ

**How many apps does one keyword return?** Up to 30: the first result page of the Google Play search. Further result pages are not read yet. For more volume, add keyword variants (for example `budget planner`, `budget app`, `expense tracker`) or use App IDs. When a keyword gives fewer apps than your limit allows, the status message says so.

**Why are `version` and `android_version` empty?** Google Play does not put them on the app page itself, so they are always `null`.

**Why is a developer email or address empty?** Only what the listing shows is returned. Not every developer publishes an email, website, address or phone number.

**Which store does `country` select?** The Google Play storefront of that country: prices, ratings, availability and the top chart label follow it. Use `language` for the text language.

**What is `installs_max`?** Google Play shows install bands such as `500,000,000+`. `installs_min` is the band start; `installs_max` is the start of the next band minus one, so it is a bound, not a measured number.

**Keyword results cost more with details. How do I keep the cost down?** Set `includeDetails` to `false` to get search list fields only, or use `maxResults` and a maximum cost per run.

**How do I find an app ID?** It is the `id=` part of the app page URL, for example `com.duolingo`. You can also paste the full URL.

### Limits

- Keyword searches read the first result page only (up to 30 apps per keyword).
- Top charts, category pages and developer pages are not supported yet.
- A search for a keyword in a small store can return few apps, or none; the run then ends normally with a message and no charge.
- Only public listing data is returned. Reviews are not included.

### Related actors

- [Contact Details Scraper](https://apify.com/santamaria-automations/contact-details-scraper) extracts emails, phones and social links from websites, for example the developer websites in this output.
- [Google Maps Scraper](https://apify.com/santamaria-automations/google-maps-scraper) returns business listings from Google Maps.
- [YellowPages Scraper](https://apify.com/santamaria-automations/yellow-pages-scraper) returns business listings from YellowPages.com.

### Data protection

This actor returns only data that is publicly visible on the source pages. Results can include personal data, such as names, email addresses, phone numbers and addresses of individual developers or sole traders. You are responsible for using the data lawfully, including the GDPR/DSGVO, national data-protection laws and unfair-competition rules (for example UWG) for marketing and outreach.

### Support

Questions or problems? Open a ticket in the Issues tab on the actor page or email contact@nanoscrape.com.

# Actor input Schema

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

Keywords to search Google Play apps for (for example budget planner, habit tracker, chess). Each keyword runs as a separate search and duplicate apps are removed. Leave empty together with App IDs to run the sample search.

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

Package names such as com.duolingo, or Google Play app page URLs such as https://play.google.com/store/apps/details?id=com.duolingo. Each one returns one app with full details. A Google Play search URL is read as a keyword.

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

Two-letter store country, for example us, de, gb, fr, br, in. Prices, ratings, availability and rankings follow this store.

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

Language of the texts, for example en, de, fr, pt-BR. Titles, descriptions, category names and content rating labels follow it. Dates and numbers in the output are language independent.

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

On (default): every app found by a keyword is opened to fill the full record (developer contacts, rating counts, release and update dates, screenshots, similar apps). It is billed as an app detail event instead of a search result event. Off: only the fields shown in the search list are returned, which is cheaper and faster. App IDs always return the full record.

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

Maximum number of apps to return across all keywords and App IDs. Set to 0 for no limit. When no keyword and no App ID is given, a sample of at most 10 apps is returned. Each keyword gives up to 30 apps (first result page).

## `maxResultsPerQuery` (type: `integer`):

Maximum number of apps for each keyword and each App ID. Leave at 0 to share Max Results equally.

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

Proxy settings for the run. The default works for most runs.

## Actor input object example

```json
{
  "searchQueries": [
    "budget planner"
  ],
  "country": "us",
  "language": "en",
  "includeDetails": true,
  "maxResults": 10,
  "maxResultsPerQuery": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `defaultDataset` (type: `string`):

Google Play apps with rating, installs, price, developer contacts, description and images.

# 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 = {
    "searchQueries": [
        "budget planner"
    ],
    "country": "us",
    "language": "en",
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("santamaria-automations/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 = {
    "searchQueries": ["budget planner"],
    "country": "us",
    "language": "en",
    "maxResults": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("santamaria-automations/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 '{
  "searchQueries": [
    "budget planner"
  ],
  "country": "us",
  "language": "en",
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call santamaria-automations/google-play-scraper --silent --output-dataset

```

## MCP server setup

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