# App Store & Google Play Scraper: Apps, Reviews, Search, Charts (`pulsedata/app-store-google-play-scraper`) Actor

Scrape Google Play and the Apple App Store in one actor: full app details (ratings, installs, price, developer, version, screenshots), reviews with replies, keyword search results, top charts by category & country, and developer portfolios. Fast, no proxies needed.

- **URL**: https://apify.com/pulsedata/app-store-google-play-scraper.md
- **Developed by:** [PulseData](https://apify.com/pulsedata) (community)
- **Categories:** E-commerce, Business, Developer tools
- **Features:** Limited permissions
- **Stats:** 4 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 app scrapeds

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

## App Store & Google Play Scraper

Scrape Google Play and the Apple App Store in one actor: full app details, user reviews, keyword search results, top charts per category and country, and every app of a developer. You pay $0.001 per app and $0.0002 per review, so 1,000 apps cost $1 and 1,000 reviews cost $0.20.

### Features

- **Scrape Google Play app details**: developer email, website and address, rating histogram, installs, price, in-app purchases, content rating and version.
- **Scrape Apple App Store app details**: bundle ID, developer website, genres, rating histogram, price, size, required iOS version and release notes.
- **Export Google Play reviews to CSV or JSON**, with app version, thumbs-up count and developer reply.
- **Export App Store reviews by country**, several storefronts in one run.
- **Search apps by keyword for ASO research** in any country and language.
- **Get the top charts of Google Play and the App Store**: top free, top paid and top grossing, per category and per country.
- **List all apps of a developer** from a developer name, ID or developer page URL.
- **Google Play permissions and data safety** per app, optional.
- **Monitor new reviews of an app**: with `onlyNewReviews` a scheduled run returns and charges only reviews it has not delivered before, on both stores.

No login and no API key. Built on the open-source libraries `google-play-scraper` and `app-store-scraper`.

### Use cases

- **ASO and keyword research**: compare the ratings and installs of the apps that rank for a keyword.
- **Review mining and sentiment analysis**: cluster complaints and feature requests in your app's or a competitor's reviews, or feed the text to an LLM.
- **Competitor monitoring and market sizing**: track version, rating and new reviews of competitor apps, or compare publishers and monetization across the top charts of several countries.
- **Lead generation**: developer emails, websites and addresses from Google Play listings.

### Input

Apps with reviews from both stores:

```json
{
  "apps": [
    "https://play.google.com/store/apps/details?id=com.spotify.music",
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ],
  "country": "us",
  "language": "en",
  "includeReviews": true,
  "maxReviewsPerApp": 500,
  "reviewsSort": "newest",
  "reviewsCountries": ["us", "gb", "de"]
}
```

Keyword search and top charts, without reviews:

```json
{
  "searchTerms": ["meditation", "sleep sounds"],
  "topCharts": [
    { "collection": "TOP_FREE", "category": "HEALTH_AND_FITNESS", "num": 100 },
    { "collection": "GROSSING", "num": 50 }
  ],
  "stores": "both",
  "maxSearchResults": 100,
  "country": "de",
  "language": "de",
  "includeAppDetails": true,
  "includeReviews": false
}
```

| Field | Type | Default | What it does |
|---|---|---|---|
| `apps` | array | `[]` | Google Play URLs or package names (`com.spotify.music`), App Store URLs or IDs (`id324684580`, `324684580`). |
| `searchTerms` | array | `[]` | Keywords to search. |
| `stores` | string | `both` | `both`, `google-play` or `app-store`. Applies to search, charts and developers. |
| `maxSearchResults` | integer | `50` | Per keyword and store. Max 250 on Google Play, 200 on the App Store. |
| `topCharts` | array | `[]` | Items like `{"collection": "TOP_FREE", "category": "GAME", "num": 100}`. |
| `developers` | array | `[]` | Developer names, IDs or developer page URLs. |
| `country` | string | `us` | Two-letter store country. |
| `language` | string | `en` | Language code for content and Google Play reviews. |
| `includeAppDetails` | boolean | `true` | Fetch the full detail page for apps found via search, charts or developers. Off returns list data only. |
| `includeReviews` | boolean | `true` | Scrape reviews for apps in `apps`. |
| `reviewsForDiscoveredApps` | boolean | `false` | Also scrape reviews for apps found via search, charts or developers. |
| `maxReviewsPerApp` | integer | `100` | Review cap per app. `0` means all available. |
| `reviewsSort` | string | `newest` | `newest`, `rating` or `helpfulness`. |
| `reviewsCountries` | array | `[]` | App Store storefronts to read reviews from. Empty means the app's own country. |
| `includePermissions` | boolean | `false` | Adds `permissions` and `dataSafety` to Google Play app rows. |
| `proxyConfiguration` | object | off | Usually not needed. |
| `onlyNewReviews` | boolean | `false` | Monitor mode: output and charge only reviews not delivered on an earlier run. |
| `monitorStoreName` | string | empty | Key-value store that remembers delivered reviews. Empty means a name derived from the apps and filters. |

Chart collections: `TOP_FREE`, `TOP_PAID` and `GROSSING` work on both stores. The App Store also accepts `NEW_FREE`, `NEW_PAID` and `NEW`. Categories are Google Play category IDs (`GAME`) or App Store genre names or IDs (`GAMES`). `num` is capped at 500 on Google Play and 200 on the App Store.

### Monitor new reviews of an app

Turn on `onlyNewReviews` to get only the reviews written since your last run:

```json
{
  "apps": [
    "https://play.google.com/store/apps/details?id=com.spotify.music",
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ],
  "reviewsCountries": ["us", "gb"],
  "maxReviewsPerApp": 500,
  "reviewsSort": "newest",
  "onlyNewReviews": true
}
```

The actor remembers delivered review IDs in a named key-value store in your Apify account and drops them on the next run, so they are neither output nor charged. With `reviewsSort: "newest"` it stops reading an app at the first page that holds a known review.

For new-review alerts, save the input as an Apify task, add an [Apify schedule](https://docs.apify.com/platform/schedules) and an integration (email, Slack, Google Sheets, Make, Zapier or a webhook) that fires when a run succeeds. A ready task is on the example page [Monitor new reviews of an app](https://apify.com/pulsedata/app-store-google-play-scraper/examples/monitor-new-app-reviews).

Details:

- Monitor mode needs `includeReviews`. Apps from search, charts or developers that get no reviews are returned and charged on every run as usual.
- The app details row comes once, on the first run, which returns up to `maxReviewsPerApp` per app and fills the store.
- Keep `maxReviewsPerApp` above the number of new reviews you expect between two runs; a review cut off by the cap is usually not reached later.
- Without `monitorStoreName` each different input keeps its own history; the run log names the store. Schedule one run per store.

### Output

Every row has a `type` (`app` or `review`) and a `store`. A Google Play app row, shortened:

```json
{
  "type": "app",
  "store": "google-play",
  "appId": "com.spotify.music",
  "url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us",
  "title": "Spotify: Music and Podcasts",
  "developer": "Spotify AB",
  "developerEmail": "android-support@spotify.com",
  "genre": "Music & Audio",
  "score": 4.34,
  "ratings": 32994517,
  "histogram": { "1": 2193010, "2": 703640, "3": 1246120, "4": 2937350, "5": 25915000 },
  "installs": "1,000,000,000+",
  "minInstalls": 1000000000,
  "price": 0,
  "free": true,
  "offersIAP": true,
  "adSupported": true,
  "contentRating": "Teen",
  "version": "VARY",
  "updated": "2026-08-18T06:18:15.000Z",
  "source": "input",
  "scrapedAt": "2026-09-25T08:12:40.511Z"
}
```

An App Store review row:

```json
{
  "type": "review",
  "store": "app-store",
  "appId": "324684580",
  "reviewId": "14442249531",
  "userName": "Cooler spiel das beste",
  "score": 3,
  "title": "Danke für die Antwort",
  "text": "...",
  "date": "2026-08-18T10:25:03.000Z",
  "version": "9.1.74",
  "thumbsUp": null,
  "replyText": null,
  "country": "de",
  "scrapedAt": "2026-09-25T08:13:02.104Z"
}
```

The `source` field on app rows tells you where the app came from: `input`, `search:<term>`, `chart:<collection>:<category>` or `developer:<id>`. An app that cannot be loaded gives an uncharged `type: "error"` row.

### Pricing

Pay per event, no monthly fee:

- **$0.001 per app** (`app-scraped`), that is $1 per 1,000 apps.
- **$0.0002 per review** (`review-scraped`), that is $0.20 per 1,000 reviews.

Worked example: the top 100 free games in the US on both stores is 200 apps, $0.20. Adding 500 reviews for each of 10 competitor apps adds 5,000 reviews ($1.00) plus 10 app rows ($0.01). Platform usage is included in the event prices.

In monitor mode only new reviews are charged, and the app row only on the first run. A daily run on the two Spotify apps above that finds 40 new reviews costs 40 x $0.0002 = $0.008. The actor has no start event, so a run that finds nothing new costs nothing.

### FAQ

**How many reviews can I get per app?**
On Google Play `0` returns everything Google serves. The App Store feed stops at about 500 reviews per storefront; add countries to `reviewsCountries` to collect more. On the App Store `maxReviewsPerApp` applies per app and country.

**Does `reviewsSort` work the same on both stores?**
No. The App Store feed has no rating order, so `rating` falls back to newest there.

**Does it return developer replies?**
On Google Play, yes. The App Store feed has no developer responses or helpful counts, so those fields are `null` there.

**Are install counts exact?**
No. Google Play shows ranges like `1,000,000+`, returned as `installs`, `minInstalls` and `maxInstalls`. The App Store does not publish installs.

**How do I schedule it or call it from code?**
Use Apify schedules, or start runs through the Apify API and SDKs. Export JSON, CSV or Excel, or send results to Google Sheets, Make, Zapier, n8n or Airtable.

**What can it not do?**
It does not log in, so there is no developer console data (downloads, revenue).

### Use it from Claude, ChatGPT or Cursor (Apify MCP server)

The actor can be called as a tool by any AI assistant that speaks the Model Context Protocol. Add the Apify MCP server to your client with this URL, which loads only this actor as a tool:

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

You sign in to Apify on first connection, then ask in plain language, for example "compare rating, installs and the 200 newest reviews of Duolingo and Babbel on Google Play". Billing is the same as a normal run.

### Paying from an AI agent without an Apify account (x402 and Skyfire)

An agent can buy a prepaid, spend-capped Apify token at [Apify AGI](https://agi.apify.com), paid in USDC through [x402](https://docs.apify.com/platform/integrations/x402) or from a [Skyfire](https://docs.apify.com/platform/integrations/skyfire) wallet, and use it for both the API and the MCP server. This actor runs with limited permissions, so it works with these tokens. The smallest token is $1, tokens expire 14 days after purchase, and Apify marks agentic payments as experimental.

### Ready-made report from this actor

[App-Market Intelligence: US Top Charts 2026](https://pulsdata.gumroad.com/l/app-market-us-2026/LAUNCH) covers 840 top-chart apps from both US stores as a PDF report plus CSV dataset, built with this actor. The launch discount is applied at the link.

### Related actors

- [Google Play Reviews Scraper](https://apify.com/pulsedata/google-play-reviews-scraper): a reduced input form if you only need Google Play reviews.
- [App Store Reviews Scraper](https://apify.com/pulsedata/app-store-reviews-scraper): a reduced input form for App Store reviews across several countries.
- [Website Tech Stack Detector](https://apify.com/pulsedata/website-tech-stack-detector): check the tech stack behind the developer websites you collected.
- [Google Ads Transparency Center Scraper](https://apify.com/pulsedata/google-ads-transparency-scraper): see which ads an app publisher runs on Google.
- [YouTube Comments Scraper](https://apify.com/pulsedata/youtube-comments-scraper): user feedback on app review and tutorial videos.

# Actor input Schema

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

App store URLs or IDs, one per line. Google Play: `https://play.google.com/store/apps/details?id=com.spotify.music` or `com.spotify.music`. App Store: `https://apps.apple.com/us/app/spotify/id324684580`, `id324684580` or `324684580`.

## `searchTerms` (type: `array`):

Keywords to search in the stores (e.g. `meditation`, `budget planner`). Results are scraped as apps.

## `stores` (type: `string`):

Which store(s) to use for keyword search, top charts and developer listings.

## `maxSearchResults` (type: `integer`):

Up to 250 for Google Play, 200 for the App Store.

## `topCharts` (type: `array`):

Scrape top chart lists. Each item: `{"collection": "TOP_FREE"|"TOP_PAID"|"GROSSING", "category": "GAME"|"HEALTH_AND_FITNESS"|... (Google Play category id or App Store genre name/id, optional), "num": 100}`. The App Store also accepts `NEW_FREE`, `NEW_PAID` and `NEW`; Google Play has no new-app charts and uses TOP_FREE for them.

## `developers` (type: `array`):

Developer IDs/names or developer page URLs to list all their apps (e.g. `Spotify AB`, `https://play.google.com/store/apps/dev?id=...`, `https://apps.apple.com/us/developer/spotify/id324684583`).

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

Two-letter store country code (us, gb, de, fr, in, br, …). Affects availability, prices, charts and reviews.

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

Language code for Google Play content and reviews and for App Store app details (en, de, fr, es, …). App Store reviews are not filtered by language; the storefront country decides which reviews you get.

## `includeAppDetails` (type: `boolean`):

For apps found via search, charts or developers, fetch the full detail page (description, installs, ratings histogram, version, permissions…). Off = only the list data.

## `includeReviews` (type: `boolean`):

Scrape reviews for every app (from the `apps` list, and from search/charts/developers if enabled below).

## `reviewsForDiscoveredApps` (type: `boolean`):

By default reviews are only scraped for the apps you list explicitly. Enable to also scrape reviews for apps discovered via search, top charts or developer pages.

## `maxReviewsPerApp` (type: `integer`):

0 = all available. Google Play allows tens of thousands per app. On the App Store the limit applies per app and country, and Apple exposes the latest ~500 per country.

## `reviewsSort` (type: `string`):

Order in which reviews are collected: newest first, by rating, or most helpful. The App Store supports newest and most helpful only; "Rating" runs as newest there.

## `reviewsCountries` (type: `array`):

App Store reviews are per country. List several codes to collect reviews from multiple storefronts (e.g. us, gb, de). Defaults to the main country.

## `includePermissions` (type: `boolean`):

Adds the list of Android permissions and the Data Safety section to Google Play app items (two extra requests per app).

## `onlyNewReviews` (type: `boolean`):

Output and charge only reviews this monitor has not delivered on an earlier run. The review IDs are remembered in a named key-value store in your account, so a scheduled daily or weekly run returns just the reviews written since the last run. With newest-first order the run stops reading an app once it reaches a known review. The app details row comes once, on the first run. The first run returns up to "Max reviews per app" and fills the store.

## `monitorStoreName` (type: `string`):

Name of the key-value store that remembers delivered reviews. Leave empty to name it after the apps and filters, so each different input keeps its own history. Set a name to share one history between inputs, or to start over by picking a new one. Letters, digits and hyphens.

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

Usually not needed. Enable Apify Proxy if you run very large volumes.

## Actor input object example

```json
{
  "apps": [
    "https://play.google.com/store/apps/details?id=com.spotify.music",
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ],
  "searchTerms": [],
  "stores": "both",
  "maxSearchResults": 50,
  "topCharts": [],
  "developers": [],
  "country": "us",
  "language": "en",
  "includeAppDetails": true,
  "includeReviews": true,
  "reviewsForDiscoveredApps": false,
  "maxReviewsPerApp": 100,
  "reviewsSort": "newest",
  "reviewsCountries": [],
  "includePermissions": false,
  "onlyNewReviews": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Apps and reviews stored in the default dataset (JSON/CSV/Excel via the dataset API).

# 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 = {
    "apps": [
        "https://play.google.com/store/apps/details?id=com.spotify.music",
        "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("pulsedata/app-store-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 = { "apps": [
        "https://play.google.com/store/apps/details?id=com.spotify.music",
        "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("pulsedata/app-store-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 '{
  "apps": [
    "https://play.google.com/store/apps/details?id=com.spotify.music",
    "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580"
  ]
}' |
apify call pulsedata/app-store-google-play-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pulsedata/app-store-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/3ZLOLBtpCctdfsWC4/builds/y2bygwh1D9UvQ9zkW/openapi.json
