# Google Play App Update Details Scraper (`googleapi/google-play-version-history-scraper`) Actor

Collect rich public Google Play app details and the current update information visible on consumer app listings. Does not claim or infer historical releases.

- **URL**: https://apify.com/googleapi/google-play-version-history-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

### What this Actor does

Google Play App Update Details Scraper collects the current public app listing and latest update information shown on Google Play. The consumer listing does not provide a complete release archive, so a normal dataset row describes one current app observation rather than a historical version.

### Input

Provide one or more Android package IDs or public Google Play app detail URLs. Set `locale`, `language`, and `country` to choose the market.

```json
{"appId":"com.google.android.apps.maps","locale":"en-US"}
```

```json
{"appIds":["com.google.android.apps.maps","com.google.android.youtube"],"maxItems":20}
```

To track public changes across future runs, set `recordReleaseObservations` to `true`. Tracking starts with the first run and does not recover earlier versions. `maxStoredReleases` limits saved observations per app and locale.

```json
{"appId":"com.google.android.apps.maps","recordReleaseObservations":true,"maxStoredReleases":50}
```

| Input | Description | Default |
|---|---|---:|
| `appId` / `appIds` | One or more Google Play package IDs. | — |
| `startUrls` | Public app detail pages. `sourceUrls` is an alias. | — |
| `maxItems` | Maximum current app observations across the run (1–500). | 100 |
| `deduplicate` | Skip repeated app, version, and locale observations. | `true` |
| `locale` / `language` / `country` | Select the Google Play storefront and language. | `en-US` / `en` / `US` |
| `recordReleaseObservations` | Retain public version, update-date, and release-note observations across future runs. | `false` |
| `maxStoredReleases` | Maximum observations retained per app and locale (1–500). | 50 |

Each app is read from one public detail page. `page` and `maxPages` are fixed at `1`.

### Output

Each row represents the current public app listing. Useful fields include:

| Field | What it contains |
| --- | --- |
| `appId`, `appUrl`, `title`, `developerName`, `developerUrl` | App and developer identity |
| `version`, `versionDisplayText`, `versionType`, `historyAvailable` | Version currently exposed and whether public release history is available |
| `updatedOn`, `updatedOnText`, `changeNotes`, `changeNotesParagraphs` | Latest visible update date and release notes |
| `description`, `descriptionHtml`, `descriptionParagraphs` | Public app description and formatting |
| `averageRating`, `ratingText`, `reviewCountText`, `ratingDistribution` | Rating information visible on the listing |
| `downloadCountText`, `downloadCountLowerBound`, `downloadCountIsLowerBound` | Displayed install band and lower-bound meaning |
| `appCategory`, `contentRating`, `androidRequirementText`, `downloadSizeText` | Category, rating, and device information |
| `appIconUrl`, `imageUrls`, `dataSafetySummary`, `appSupport`, `developerContact` | Public media, disclosure, and contact details when available |

Example:

```json
{
  "appId": "com.example.app",
  "title": "Example App",
  "version": "8.1.0",
  "versionType": "current",
  "updatedOn": "2026-09-18",
  "updatedOnText": "Updated on September 18, 2026",
  "changeNotes": "Faster navigation and small stability improvements.",
  "historyAvailable": false,
  "downloadCountText": "1M+",
  "downloadCountIsLowerBound": true,
  "locale": "en-US",
  "country": "US"
}
```

Google Play may round review totals and install bands. The original text is preserved, and lower-bound or approximate values are marked. Unknown listing details are omitted rather than guessed. Results can be downloaded as JSON, CSV, Excel, or another format supported by Apify.

### Coverage, cost, and responsible use

Check the Actor's Pricing tab for current Actor and Apify platform charges. The Actor reads public app pages only; it does not access Play Console or claim to retrieve hidden versions or release dates. Any optional change tracking starts from the first run and captures only public observations made afterward.

Results reflect the app listing and market at run time. This Actor is independent of Google. Follow Google Play's terms and applicable laws when using the data.

# Actor input Schema

## `startUrls` (type: `array`):

Public Google Play app detail pages. Each app uses one detail page; hidden version history is not inferred.

## `sourceUrls` (type: `array`):

Compatibility alias for public app detail URLs.

## `urls` (type: `array`):

Compatibility alias for public app detail URLs.

## `url` (type: `string`):

Compatibility alias for one public app detail URL.

## `appId` (type: `string`):

Google Play package ID for a public app detail page.

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

Up to 50 Google Play package IDs.

## `maxVersions` (type: `integer`):

Compatibility input retained from older Actor versions. Public Google Play listings produce at most one current observation per app; this setting cannot create historical records.

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

Global maximum number of current app-observation records across all app URLs.

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

Compatibility alias for maxItems. If both are set, they must agree.

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

Compatibility input fixed to page 1 because each app is read from one detail page.

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

Fixed at 1; this Actor reads one public app detail page per target and does not paginate through historical versions.

## `locale` (type: `string`):

Requested Google Play language-country locale such as en-US.

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

Two-letter language code. Must agree with locale when both are supplied.

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

Two-letter country code used for the public Google Play detail URL.

## `location` (type: `string`):

Compatibility alias for country. If both are set, they must agree.

## `deduplicate` (type: `boolean`):

Remove repeated app/version/locale observations across submitted URLs.

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

Maximum seconds per public request.

## `requestTimeoutMs` (type: `integer`):

Compatibility timeout in milliseconds. If seconds and milliseconds are both set, they must agree.

## `timeoutSecs` (type: `integer`):

Compatibility alias for requestTimeoutSecs.

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

Finite retries for transient public request failures.

## `maxConcurrency` (type: `integer`):

Maximum number of public app pages processed concurrently.

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

Delay before processing later app pages.

## `maxResponseBytes` (type: `integer`):

Maximum body size accepted for each public HTML response.

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

Optional Apify Proxy configuration for permitted public requests. Off unless explicitly configured.

## `recordReleaseObservations` (type: `boolean`):

Opt-in persistent observations of public version, update date and release notes. This begins with the first run; it does not recover historical releases. Avoid concurrent runs writing the same app and locale.

## `maxStoredReleases` (type: `integer`):

Stops appending when capacity is reached. Existing evidence is preserved. Repeated observations do not create additional releases.

## Actor input object example

```json
{
  "maxVersions": 100,
  "maxItems": 100,
  "page": 1,
  "maxPages": 1,
  "locale": "en-US",
  "language": "en",
  "country": "US",
  "deduplicate": true,
  "requestTimeoutSecs": 30,
  "maxRequestRetries": 1,
  "maxConcurrency": 1,
  "requestDelayMs": 0,
  "maxResponseBytes": 2500000,
  "recordReleaseObservations": false,
  "maxStoredReleases": 50
}
```

# Actor output Schema

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

No description

## `outputSummary` (type: `string`):

No description

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

No description

## `legacyOutputSummary` (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-version-history-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-version-history-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-version-history-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,googleapi/google-play-version-history-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/2MZigXHnvlEt8kyyM/builds/yQWMokqxY3OS2I6lw/openapi.json
