# Google Play Keywords Discovery Tool (`googleapi/google-play-keyword-discovery-scraper`) Actor

Discover Google Play autocomplete suggestions and optionally enrich them with bounded public app profiles.

- **URL**: https://apify.com/googleapi/google-play-keyword-discovery-scraper.md
- **Developed by:** [Google API](https://apify.com/googleapi) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

Discover public Google Play autocomplete suggestions and, optionally, the app cards and app profiles behind those suggestions. It is an API-based alternative to manually comparing [Google Play search results](https://play.google.com/store/search?q=fitness%20apps\&c=apps). App enrichment is opt-in, bounded, and limited to Google Play search/detail pages; the Actor does not claim keyword volume, trend, difficulty, conversion, or rank metrics.

### What it does

For each seed phrase, the Actor returns Google Play autocomplete suggestions. When `includeAppResults` is enabled, it can also return matching app cards and selected public app-profile details.

Google Play search cards may provide an app name, developer, rating, icon, promotional image, and app link. Public app listings can also include descriptions, update and release information, price, category, compatibility, content rating, data-safety details, screenshots, related apps, events, and support contacts. Descriptions are returned in full when available, with a safe HTML version. Missing values are omitted; rounded download labels remain text, and unknown facts are not treated as negative.

Autocomplete suggestions are the primary results. `appResults` is an optional list of matching Google Play apps. The Actor does not follow app, event, editorial, developer, support, or privacy-policy links. It does not collect account-specific device compatibility information or claim search-volume and ranking metrics.

### Input

Parent fields:

| Field | Meaning |
| --- | --- |
| `keyword` | Exact visible autocomplete phrase. |
| `googlePlaySearchUrl` | Google Play search destination for the phrase. |
| `appResults` | Optional bounded list of matching Google Play app records; omitted if enrichment is disabled or that suggestion could not be opened. |

Each `appResults` item can include the following app-profile fields. Google Play may not expose every value for every listing:

| Group | Fields |
| --- | --- |
| App identity | `appId`, `appName`, `appUrl`, `developerName`, `developerUrl`, `developerAddress` |
| Artwork and rating | `appIconUrl`, `searchResultImageUrl`, `rating`, `ratingText`, `ratingCount`, `ratingCountText`, `ratingBreakdown`, `screenshotUrls`, `screenshotCount` |
| Listing content | `shortDescription`, `fullDescription`, `fullDescriptionHtml`, `recentChanges`, `updatedOnText`, `versionText`, `releasedOnText`, `appSizeText`, `appCategory`, `appCategoryCode`, `appCategoryUrl`, `operatingSystem` |
| Requirements and offers | `contentRating`, `androidRequirement`, `interactiveElements`, `containsAds`, `inAppPurchases`, `inAppPurchasePriceText`, `priceAmount`, `priceCurrency`, `offerAvailability`, `downloadsText` |
| Safety and related apps | `dataSafety`, `moreByDeveloperName`, `moreByDeveloperApps`, `featuredApps`, `similarApps` |
| In-page promotions | `eventsAndOffers[]`, `editorialFeatures[]` | Current titles, card labels/copy, Google Play destination IDs, and Google-hosted images where shown; destination pages are not fetched |
| Public app support | `privacyPolicyUrl`, `supportWebsite`, `supportEmail`, `supportPhone` |

`dataSafety` contains `sharingStatement`, `dataSharedWithThirdParties`, `dataCollectionSummary`, `encryptedInTransit`, `deletionRequestAvailable`, `independentSecurityReview`, `disclosureNotice`, and `detailsUrl`. The booleans are populated only when the visible source makes an explicit declaration. `ratingCount` comes from the app's structured aggregate rating when present; `downloadsText` preserves the public tier label instead of converting a rounded `10B+` label into an asserted exact count.

### Input

`keywords` takes precedence over the single-keyword compatibility alias `keyword`. `maxItems` is the global unique parent-row limit. `page` and `maxPages` remain fixed at `1`: autocomplete has no numbered pages, and only the first linked Google Play result page is read for each enriched suggestion.

| Input | Type and default | Bounds and behavior |
| --- | --- | --- |
| `keywords` | string array; no default | 1–20 unique seed phrases, 1–100 characters each. |
| `keyword` | string; no default | Legacy single seed, used only if `keywords` is omitted. |
| `country` | string; `us` | Two-letter country code for Google requests. |
| `language` | string; `en` | Lowercase language code, optionally with an uppercase region (e.g. `en-US`). |
| `expandAlphabet` | boolean; `true` | Generate character-suffixed suggestion requests. |
| `expansionChars` | string; `abcdefghijklmnopqrstuvwxyz0123456789` | Up to 40 letters/digits appended to seeds. |
| `customSuffixes` | string array; `[]` | Up to 50 suffixes, each at most 40 characters. |
| `maxQueries` | integer; `100` | Maximum autocomplete variations to generate (1–250). Choose a value large enough to cover all seed phrases. |
| `maxItems` | integer; `200` | 1–2,000 unique parent suggestion rows. |
| `includeAppResults` | boolean; `false` | Include matching apps from Google Play search. |
| `maxAppSearches` | integer; `5` | Maximum number of suggestion searches to expand (1–25). Applies only when app results are enabled. |
| `maxAppResults` | integer; `5` | 1–10 app cards retained per enriched suggestion. |
| `maxAppDetailPages` | integer; `10` | Maximum number of app listings to enrich (0–50); `0` keeps search-card data only. |
| `proxyConfiguration` | object; omitted | Optional active Apify Proxy configuration for Google requests. It is not an access-control bypass. |

#### Example inputs

Suggestion-only example:

```json
{"keywords":["fitness"],"country":"us","language":"en","expandAlphabet":false,"maxQueries":1,"maxItems":25}
```

Multiple seed phrases:

```json
{"keywords":["fitness","home workout"],"expandAlphabet":false,"maxQueries":2,"maxItems":50}
```

Character and phrase expansion:

```json
{"keywords":["fitness"],"expansionChars":"ab12","customSuffixes":["free","at home"],"maxQueries":8,"maxItems":100}
```

Market and language controls:

```json
{"keyword":"maps","country":"in","language":"en","expandAlphabet":false,"maxQueries":1,"maxItems":30}
```

Bounded linked app and detail enrichment:

```json
{"keywords":["maps"],"expandAlphabet":false,"maxQueries":1,"maxItems":10,"includeAppResults":true,"maxAppSearches":1,"maxAppResults":3,"maxAppDetailPages":2}
```

Search-card results without app detail fetches:

```json
{"keywords":["photo editor"],"expandAlphabet":false,"maxQueries":1,"includeAppResults":true,"maxAppSearches":1,"maxAppResults":5,"maxAppDetailPages":0}
```

Fixed source pagination controls:

```json
{"keywords":["navigation"],"expandAlphabet":false,"maxQueries":1,"maxItems":5,"page":1,"maxPages":1}
```

Optional Apify Proxy:

```json
{"keywords":["fitness"],"expandAlphabet":false,"maxQueries":1,"maxItems":20,"proxyConfiguration":{"useApifyProxy":true,"apifyProxyGroups":["RESIDENTIAL"]}}
```

### Output

Rows stay suggestion-first. `appResults` is absent by default; when an app listing is unavailable, the suggestion can still be returned on its own.

Illustrative rich output shape (values are examples, not a claim about a current listing):

```json
{
  "keyword": "fitness apps",
  "googlePlaySearchUrl": "https://play.google.com/store/search?q=fitness+apps&c=apps",
  "appResults": [
    {
      "appId": "com.example.fitnesstracker",
      "appName": "Fitness Tracker",
      "appUrl": "https://play.google.com/store/apps/details?id=com.example.fitnesstracker",
      "developerName": "Example Studio",
      "developerUrl": "https://example-studio.invalid/",
      "developerAddress": "123 Example Street, Example City, CA 94000, US",
      "appIconUrl": "https://play-lh.googleusercontent.com/example-icon=s128-rw",
      "searchResultImageUrl": "https://play-lh.googleusercontent.com/example-promo=w416-h235-rw",
      "rating": 4.6,
      "ratingText": "Rated 4.6 stars out of five stars",
      "ratingCount": 125000,
      "ratingCountText": "125K reviews",
      "downloadsText": "1M+ downloads",
      "shortDescription": "Track workouts and daily activity.",
      "fullDescription": "Track workouts and daily activity.\n\n• Review weekly progress",
      "fullDescriptionHtml": "<p>Track workouts and daily activity.</p><p>• Review weekly progress</p>",
      "recentChanges": "Bug fixes and performance improvements.",
      "updatedOnText": "Sep 25, 2026",
      "versionText": "Version 1.7.8",
      "releasedOnText": "Released on Nov 8, 2017",
      "appSizeText": "69 MB",
      "appCategory": "Health & Fitness",
      "appCategoryCode": "HEALTH_AND_FITNESS",
      "appCategoryUrl": "https://play.google.com/store/apps/category/HEALTH_AND_FITNESS",
      "operatingSystem": "ANDROID",
      "contentRating": "Rated for 3+",
      "androidRequirement": "Android 9 and up",
      "interactiveElements": ["Users Interact"],
      "containsAds": true,
      "inAppPurchases": true,
      "inAppPurchasePriceText": "₹180.00 - ₹7,300.00 per item",
      "priceAmount": 0,
      "priceCurrency": "USD",
      "offerAvailability": "https://schema.org/InStock",
      "dataSafety": {
        "sharingStatement": "No data shared with third parties",
        "dataSharedWithThirdParties": false,
        "dataCollectionSummary": "Location, Personal info and 10 others",
        "encryptedInTransit": true,
        "deletionRequestAvailable": true,
        "independentSecurityReview": true,
        "disclosureNotice": "Data privacy and security practices may vary based on your use, region, and age.",
        "detailsUrl": "https://play.google.com/store/apps/datasafety?id=com.example.fitnesstracker"
      },
      "screenshotUrls": ["https://play-lh.googleusercontent.com/example-screenshot=w526-h296-rw"],
      "screenshotCount": 8,
      "ratingBreakdown": [{"rating":5,"reviewCount":90000},{"rating":4,"reviewCount":20000}],
      "moreByDeveloperName": "Example Studio",
      "moreByDeveloperApps": [{"appId":"com.example.sleeptracker","appName":"Sleep Tracker","appUrl":"https://play.google.com/store/apps/details?id=com.example.sleeptracker","developerName":"Example Studio","rating":4.4,"appIconUrl":"https://play-lh.googleusercontent.com/sleep-icon=s64-rw"}],
      "featuredApps": [{"appId":"com.example.featured","appName":"Featured Planner","appUrl":"https://play.google.com/store/apps/details?id=com.example.featured","rating":4.5}],
      "similarApps": [{"appId":"com.example.stepcounter","appName":"Step Counter","appUrl":"https://play.google.com/store/apps/details?id=com.example.stepcounter"}],
      "eventsAndOffers": [{"eventId":"4828222813609051659","eventUrl":"https://play.google.com/store/apps/eventdetails/4828222813609051659","eventLabel":"Update available","eventTitle":"New! Plan more activities this week","imageUrl":"https://play-lh.googleusercontent.com/event-card=w648-h364-rw"}],
      "editorialFeatures": [{"featureId":"mc_apps_category_essentials_fitness","featureUrl":"https://play.google.com/store/apps/editorial?id=mc_apps_category_essentials_fitness","label":"Essentials","title":"Build a daily routine","summary":"Find apps for movement and sleep"}],
      "privacyPolicyUrl": "https://example.invalid/privacy-policy",
      "supportWebsite": "https://support.example.invalid/app",
      "supportEmail": "support@example.invalid",
      "supportPhone": "+1-555-0100"
    }
  ]
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Results and cost

`maxQueries` bounds autocomplete coverage. With `includeAppResults: true`, `maxAppSearches` limits Google Play result pages and `maxAppResults` caps cards per search. `maxAppDetailPages` limits optional app-page lookups. Related apps appear as linked cards and are not followed recursively. To keep a run small, reduce these limits or leave app-result enrichment off.

The Actor uses public Google Play search and app listings. It does not fetch external developer or support links; those are returned as listing data when available.

### Troubleshooting and responsible use

- If `appResults` is missing, confirm `includeAppResults` is `true` and the suggestion is within the global `maxAppSearches` limit.
- If app cards contain fewer details, increase `maxAppDetailPages`. Google Play listings vary by app, country, and language; missing details are not filled in.
- Google may limit available public results. This Actor does not sign in or bypass access controls.
- Use the API tab for automation and include the run ID and a short reproduction in the Actor's Issues tab when requesting support.

Google Play access and public content are subject to Google's terms, rate limits, privacy rules, and applicable law. The Actor is not affiliated with Google. Users are responsible for reviewing and lawfully using collected public app listing information.

# Changelog

This Actor's version history is a separate document: https://apify.com/googleapi/google-play-keyword-discovery-scraper/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

One to twenty phrases to expand using Google Play autocomplete.

## `keyword` (type: `string`):

Compatibility alias used only when keywords is omitted.

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

Two-letter country code sent as Google's gl parameter.

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

Google suggestion language code sent as hl.

## `expandAlphabet` (type: `boolean`):

Request each seed followed by the configured expansion characters.

## `expansionChars` (type: `string`):

At most 40 letters or digits appended after each seed.

## `customSuffixes` (type: `array`):

Optional words or short phrases appended to each seed.

## `maxQueries` (type: `integer`):

Maximum generated seed and expansion requests; this is the source request budget, not page pagination.

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

Maximum number of unique suggestion records to save. Defaults to 200.

## `includeAppResults` (type: `boolean`):

When enabled, open each selected suggestion's Google Play search page and fetch bounded public app detail pages. Disabled by default; this adds requests and run time.

## `maxAppSearches` (type: `integer`):

Global cap on Google Play search pages opened for suggestion records when app-result enrichment is enabled.

## `maxAppResults` (type: `integer`):

Maximum number of public app cards retained under each enriched suggestion. App cards beyond this cap are ignored.

## `maxAppDetailPages` (type: `integer`):

Global cap on Google Play app detail pages fetched across the run. Set to 0 to keep search-card fields only.

## `page` (type: `integer`):

Fixed at 1 because Google Play returns one autocomplete response per generated term rather than numbered pages.

## `maxPages` (type: `integer`):

Fixed at 1; this source has no paginated result pages. Use maxQueries to bound autocomplete requests.

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

Optional active Apify Proxy configuration for Google suggestion requests.

## `requestDelayMs` (type: `integer`):

Pause between generated suggestion requests. Use 0 only for small runs.

## `maxRequestRetries` (type: `integer`):

Finite retries for timeouts, rate limits, and server/network failures.

## `requestTimeoutSecs` (type: `integer`):

Maximum time allowed for each suggestion request attempt.

## Actor input object example

```json
{
  "country": "us",
  "language": "en",
  "expandAlphabet": true,
  "expansionChars": "abcdefghijklmnopqrstuvwxyz0123456789",
  "customSuffixes": [],
  "maxQueries": 100,
  "maxItems": 200,
  "includeAppResults": false,
  "maxAppSearches": 5,
  "maxAppResults": 5,
  "maxAppDetailPages": 10,
  "page": 1,
  "maxPages": 1,
  "requestDelayMs": 250,
  "maxRequestRetries": 2,
  "requestTimeoutSecs": 20
}
```

# Actor output Schema

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

No description

## `output` (type: `string`):

No description

## `runHealth` (type: `string`):

No description

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

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("googleapi/google-play-keyword-discovery-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("googleapi/google-play-keyword-discovery-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 '{}' |
apify call googleapi/google-play-keyword-discovery-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,googleapi/google-play-keyword-discovery-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/s3sC5emt9YopUfTSm/builds/retbihif2I98Yxv12/openapi.json
