# Google Play Store App Search Scraper (`fetch_cat/google-play-store-app-search-scraper`) Actor

Export ranked public Google Play app search results by keyword, country, and language for ASO and competitor monitoring.

- **URL**: https://apify.com/fetch\_cat/google-play-store-app-search-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Marketing, Business, Developer tools
- **Stats:** 3 total users, 2 monthly users, 87.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 1,000 item processeds

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/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 App Search Scraper

Export ranked public Google Play app search results by keyword, country, and language for ASO research, competitor monitoring, and app-market analysis.

Enter up to 20 search terms and receive one dataset row per visible app result. The Actor works without a Google account, preserves the query and rank for every app, and can be scheduled or called through the Apify API and official Apify MCP server.

### What data can you export?

- Android package ID, app title, developer, icon, and canonical Google Play URL
- Search keyword and one-based result position
- Visible rating, rating/review count, price text, and free-download status
- Requested country and language plus the exact localized search URL
- Collection timestamp
- A `RUN_SUMMARY` with completed, empty, failed, and pending queries
- A `PENDING_WORK` checkpoint when a larger run reaches its safe runtime limit

Google Play search cards do not expose every app-detail field in every layout. `installRange`, `category`, and other unavailable values are returned as `null` rather than guessed.

### Input example

```json
{
  "searchQueries": ["meditation", "budget tracker"],
  "country": "US",
  "language": "en",
  "maxItemsPerQuery": 10
}
```

### Output example

```json
{
  "searchQuery": "meditation",
  "position": 1,
  "appId": "com.calm.android",
  "appTitle": "Calm - Sleep, Meditate, Relax",
  "developer": "Calm.com, Inc.",
  "rating": 4.4,
  "ratingCount": null,
  "installRange": null,
  "priceText": "In-app purchases",
  "isFree": true,
  "category": null,
  "detailUrl": "https://play.google.com/store/apps/details?id=com.calm.android",
  "iconUrl": "https://play-lh.googleusercontent.com/...",
  "country": "US",
  "language": "en",
  "sourceUrl": "https://play.google.com/store/search?q=meditation&c=apps&hl=en&gl=US",
  "scrapedAt": "2026-07-20T12:00:00.000Z"
}
```

### Input settings

| Setting | JSON key | Description |
|---|---|---|
| Search queries | `searchQueries` | Required list of 1-20 keyword strings. Each query can contain up to 200 characters. |
| Maximum apps per query | `maxItemsPerQuery` | Number of visible results to save per query, from 1 to 100. Default: `10`. |
| Country | `country` | Two-letter country code such as `US`, `GB`, `DE`, or `IN`. Default: `US`. |
| Language | `language` | Language code such as `en`, `es`, `de`, `fr`, or `pt-BR`. Default: `en`. |
| Safe runtime limit | `maxRuntimeSecs` | Runtime budget from 35 to 270 seconds. The default `240` leaves time to save progress before shutdown. |

Existing inputs that omit `maxRuntimeSecs` continue to use the default.

### Output fields

| Field | Description |
|---|---|
| `searchQuery` | Keyword that produced the result. |
| `position` | One-based position within the returned results for that query. |
| `appId` | Android package identifier. |
| `appTitle` | Public app name. |
| `developer` | Developer shown on the search card, or `null`. |
| `rating` | Visible average star rating, or `null`. |
| `ratingCount` | Visible compact rating/review count, or `null`. |
| `installRange` | Visible install/download range when present on the search card, otherwise `null`. |
| `priceText` | Visible price or purchase label, or `null`. |
| `isFree` | Whether the download is shown as free, or `null` when not determinable. In-app purchases do not make a free download paid. |
| `category` | Visible category when present on the search card, otherwise `null`. |
| `detailUrl` | Canonical public Google Play app URL. |
| `iconUrl` | Public app icon URL, or `null`. |
| `country` | Country code used for the search. |
| `language` | Language code used for the search. |
| `sourceUrl` | Localized public search URL used for the result. |
| `scrapedAt` | ISO 8601 collection timestamp. |

The default key-value store also exposes `RUN_SUMMARY`. A valid no-match search is listed in `emptyQueries` after the Actor verifies that Google Play's result layout is still healthy. If the safe runtime or maximum Actor charge interrupts a larger workload, `PENDING_WORK` records the exact query and apps already saved so an Apify run resurrection can continue without duplicating them.

### Who is it for?

- **ASO teams:** capture keyword rankings across countries and languages.
- **App publishers:** identify competing Android apps returned for product terms.
- **Agencies:** build recurring app-visibility reports for clients.
- **Market researchers:** create localized lists of app IDs, developers, ratings, and listing URLs.
- **Developers and data teams:** export results to CSV, Excel, JSON, API pipelines, warehouses, or agents.

### Input recipes

- **US meditation competitors:** `{"searchQueries":["meditation"],"country":"US","language":"en","maxItemsPerQuery":10}`
- **UK budgeting apps:** `{"searchQueries":["budget tracker"],"country":"GB","language":"en","maxItemsPerQuery":10}`
- **German fitness results:** `{"searchQueries":["fitness tracker"],"country":"DE","language":"de","maxItemsPerQuery":20}`
- **Multi-keyword snapshot:** add several related terms to `searchQueries`; each row retains its originating query.

### Pricing

This Actor uses pay-per-event pricing. A run charges the `start` event once, then the `item` event only for each app row successfully saved to the dataset. Resurrecting that same checkpointed run does not repeat the start charge. Empty searches, failed queries, warnings, `RUN_SUMMARY`, and `PENDING_WORK` are not charged as items.

Current event prices and account-tier discounts are shown in the [Actor's live Pricing tab](https://apify.com/fetch_cat/google-play-store-app-search-scraper/pricing). Apify platform usage for compute, storage, and data transfer may be billed separately; the live Pricing tab is authoritative.

### Tips for better results

- Start with one specific keyword and 5-10 results before scaling.
- Use matching country and language values when comparing localized rankings.
- Schedule separate tasks per market so country-specific snapshots remain easy to compare.
- Check `RUN_SUMMARY` when a run returns fewer rows than expected; it distinguishes verified no-match searches, query failures, spending-limit stops, and safe-runtime cutoff.
- Resurrect an interrupted run with the same input to continue from `PENDING_WORK`.

### Limits and practical notes

- The Actor covers the public Google Play `/store/search` surface only. It does not fetch app-detail pages, reviews, charts, collections, developer catalogs, or private data.
- It does not log in, accept cookies, solve CAPTCHAs, use private endpoints, or attempt stealth bypasses.
- Google Play can vary results by country, language, time, and user context, so ranks are snapshots rather than permanent positions.
- Search cards expose fewer fields than app-detail pages. Missing values remain `null`.
- Temporary rate limits and source error pages are retried within a bounded run budget. One failed query does not discard valid rows from other queries.
- A no-match query finishes as a verified empty result when a bounded control search confirms that Google Play's result layout is healthy. If that control search is also empty, the query is reported as source drift instead of a misleading successful-empty result.

### API usage

#### Node.js

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/google-play-store-app-search-scraper').call({
  searchQueries: ['meditation'],
  country: 'US',
  language: 'en',
  maxItemsPerQuery: 10,
});

console.log(run.defaultDatasetId);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/google-play-store-app-search-scraper').call(run_input={
    'searchQueries': ['meditation'],
    'country': 'US',
    'language': 'en',
    'maxItemsPerQuery': 10,
})

print(run['defaultDatasetId'])
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~google-play-store-app-search-scraper/runs?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"searchQueries":["meditation"],"country":"US","language":"en","maxItemsPerQuery":10}'
```

### MCP and AI agents

Use the official Apify MCP server. The general endpoint, `https://mcp.apify.com`, can search and run Actors. This focused endpoint exposes only this Actor:

```text
https://mcp.apify.com?tools=fetch_cat/google-play-store-app-search-scraper
```

Claude Code:

```bash
claude mcp add --transport http apify-google-play-search 'https://mcp.apify.com?tools=fetch_cat/google-play-store-app-search-scraper'
```

Claude Desktop, Cursor, or another MCP client:

```json
{
  "mcpServers": {
    "apify-google-play-search": {
      "url": "https://mcp.apify.com?tools=fetch_cat/google-play-store-app-search-scraper"
    }
  }
}
```

Example prompts:

- "Find the top 10 meditation apps in the US and return app IDs, rank, developer, and rating."
- "Run separate German and UK searches for fitness tracker apps and compare the top results."
- "Create a CSV-ready competitor list for budget tracker and expense manager keywords."

### Schedule Google Play keyword monitoring

Save one task per market, then use an Apify schedule to run it daily or weekly. Export each dataset to Google Sheets or a warehouse, or attach a webhook that notifies your workflow when the run finishes. Compare `appId` and `position` across snapshots to detect new competitors and ranking changes.

### Related Actors

- [Google Play Apps Scraper](https://apify.com/fetch_cat/google-play-apps-scraper) for search plus direct app-detail enrichment
- [Google Play Reviews Scraper](https://apify.com/fetch_cat/google-play-reviews-scraper) for public Android review analysis
- [Apple App Store Reviews Scraper](https://apify.com/fetch_cat/apple-app-store-reviews-scraper) for iOS reviews and ratings
- [Google Trends Scraper](https://apify.com/fetch_cat/google-trends-scraper) for broader search-demand monitoring
- [Google Ads Transparency Center Scraper](https://apify.com/fetch_cat/google-ads-transparency-scraper) for competitor advertising research

### FAQ

#### Is this a Google Play Search API alternative?

It provides a structured API workflow for public Google Play search results, but it is not an official Google API and does not provide private account data or every app-detail field.

#### Can I export results to CSV, Excel, or JSON?

Yes. Apify datasets support CSV, Excel, JSON, JSONL, XML, RSS, and HTML exports, plus API access.

#### Does it require a Google account, cookies, or a token?

No. It reads public search pages without Google login credentials or cookies. You still need an Apify token when calling the Actor through the API.

#### Can I search multiple keywords?

Yes. Add up to 20 strings to `searchQueries`. `maxItemsPerQuery` applies separately to each query.

#### Can I compare countries and languages in one run?

One run uses one country and language pair. Use separate runs or saved tasks for clean market comparisons.

#### Why are installs, category, or counts sometimes null?

The public search card does not consistently expose those fields. This search-only Actor returns `null` instead of opening app-detail pages or inventing values.

#### What happens if one keyword fails?

Valid results from other keywords remain in the dataset. `RUN_SUMMARY` records the failed query and cause. A legitimate no-match keyword is recorded in `emptyQueries` and is not treated as a failure. The run fails only when no output or verified-empty query succeeds.

#### Is collecting public app search data legal?

The Actor collects publicly visible search information. Your use of the data must comply with applicable laws, Google Play terms, privacy obligations, and your organization’s policies.

### Support

If a run fails, returns no data, or a field looks wrong, open an issue or report a bug from the Actor page. Include the Apify run ID or run URL, input JSON, expected output, actual output, and one reproducible public URL, such as the corresponding Google Play search URL. Small, public examples make localization or source-layout problems faster to diagnose.

# Actor input Schema

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

Keywords to search on Google Play.

## `maxItemsPerQuery` (type: `integer`):

Maximum number of app search results to save for each query.

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

Two-letter Google Play country code, for example US, GB, DE, or IN.

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

Google Play interface language, for example en, es, de, or fr.

## `maxRuntimeSecs` (type: `integer`):

Maximum run time in seconds. The Actor stops accepting new work early enough to save a resumable checkpoint. Leave empty to use 240 seconds.

## Actor input object example

```json
{
  "searchQueries": [
    "notion",
    "fitness tracker"
  ],
  "maxItemsPerQuery": 10,
  "country": "US",
  "language": "en"
}
```

# Actor output Schema

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

Ranked app result rows from the requested Google Play searches.

## `runSummary` (type: `string`):

Run status, completed, empty, failed, and pending queries, spending-limit state, and warnings.

## `pendingWork` (type: `string`):

Resumable progress saved when a safe runtime or spending limit interrupts a larger 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 = {
    "searchQueries": [
        "notion",
        "fitness tracker"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/google-play-store-app-search-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": [
        "notion",
        "fitness tracker",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/google-play-store-app-search-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 '{
  "searchQueries": [
    "notion",
    "fitness tracker"
  ]
}' |
apify call fetch_cat/google-play-store-app-search-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/nBJojsnCp1eGzH9a9/builds/rwxkwzHDQCUXH0OTQ/openapi.json
