# App Store & Google Play Reviews Scraper (`whoareyouanas/app-store-google-play-review-scraper`) Actor

Scrape Apple App Store and Google Play reviews for iOS/Android app and competitor analysis. Export ratings, text, dates, available versions, developer replies, full app metadata and raw data. Bulk JSON/CSV export, filters and AI agent/MCP support.

- **URL**: https://apify.com/whoareyouanas/app-store-google-play-review-scraper.md
- **Developed by:** [Anas Nadeem](https://apify.com/whoareyouanas) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

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 Reviews Scraper

Scrape public **Apple App Store and Google Play reviews** for app research, competitor analysis, app store optimization (ASO) and product feedback. Export iOS and Android reviews together, with ratings, original text, dates, available review versions, helpful votes and developer responses. Full available app metadata, original source payloads and a collection report are included by default.

Use the actor in Apify Console, through the API, or as a tool for an AI agent through Apify MCP. Supply app URLs or IDs; no Apple or Google developer-account credentials are needed.

### Quick start

This example requests up to 40 reviews from each store, with an 80-review total cap:

```json
{
  "apps": [
    "https://apps.apple.com/us/app/whatsapp-messenger/id310633997",
    "https://play.google.com/store/apps/details?id=com.whatsapp"
  ],
  "countries": ["us"],
  "languages": ["en"],
  "maxReviewsPerAppCountry": 40,
  "maxReviews": 80,
  "includeAppMetadata": true,
  "includeRawData": true
}
```

Open **Output** for review rows, or use the run's result links for full JSON, core-field CSV, a short preview, the collection report and app profiles. Set a maximum run charge in Console or `maxTotalChargeUsd` in API run options.

The actor accepts mixed Apple numeric IDs such as `310633997`, Android package names such as `com.whatsapp`, and HTTPS app URLs. Explicit countries/languages override URL hints. Each app/country combination is a separate context; Google additionally creates one context per requested language. Apple uses its storefront and returns `language: null`.

### What you can do with the data

- Compare your app with competitors using original reviews and star ratings.
- Find complaints or feature requests with date, keyword and rating filters.
- Inspect feedback on a specific version where the source exposes that version.
- Analyze developer responses and unresolved feedback.
- Feed review JSON into your own AI analysis, data warehouse or reporting workflow.

The actor exports evidence for analysis. Sentiment labels, translations and inferred reviewer demographics are not generated.

### Bulk export and filtered research

Request up to 5,000 reviews for each of four app/storefront contexts:

```json
{
  "apps": ["310633997", "com.whatsapp"],
  "countries": ["us", "in"],
  "languages": ["en"],
  "sort": "newest",
  "maxReviewsPerAppCountry": 5000,
  "maxReviews": 20000,
  "includeAppMetadata": true,
  "includeRawData": true
}
```

For low-rating reviews mentioning a problem, use:

```json
{
  "apps": ["310633997", "com.whatsapp"],
  "ratings": [1, 2],
  "keywords": ["crash", "login", "notification"],
  "dateFrom": "2026-01-01",
  "replyFilter": "all",
  "maxReviewsPerAppCountry": 500,
  "maxReviews": 1000,
  "maxReviewsScannedPerAppCountry": 10000,
  "maxRequestsPerAppCountry": 1000
}
```

All filter groups combine with AND; any listed keyword matches within the keyword group. Keywords match title/body case-insensitively. Version filters require an exact source version. Filters examine retrieved candidates within the work limits; a batch with no matches does not end collection.

For all reachable reviews, set both review caps to `0`. The candidate/request ceilings still apply. Removing those ceilings also requires setting their inputs to `0`. Keep a maximum run charge and inspect `SUMMARY`: public endpoints do not guarantee access to every historical review.

### Review output contract

The default dataset has **one row per unique exported review**. Every field below is present except `sourceData`, which is omitted when `includeRawData` is `false`. Unavailable scalar values are `null`; source zeros and empty strings retain their meaning. Full JSON preserves nested data. The CSV/table view selects core review fields.

The run API's `output` object provides these result URLs:

| Output link | Result |
| --- | --- |
| `reviews` | Full review dataset as JSON; supports pagination. |
| `reviewsPreview` | First 20 rows projected to core fields for quick inspection. |
| `reviewsCsv` | Core review table exported as CSV. |
| `collectionReport` | The `SUMMARY` collection and quality report. |
| `appProfiles` | The `APPS` metadata index. |
| `appProfileRecords` | List of full profile keys in the key-value store. |

| Fields | Type and meaning |
| --- | --- |
| `schemaVersion` | Integer `1`, the review contract version. |
| `store`, `appId`, `appUrl` | Store is `app_store` or `google_play`; IDs are strings; app store URL. |
| `appName`, `developerName` | Nullable current app/publisher names from optional app metadata. |
| `appRating`, `appRatingCount` | Nullable current app-level rating and rating count, including ratings without written text. |
| `reviewId`, `reviewKey` | Source ID and stable namespaced key for joins and deduplication. |
| `rating`, `title`, `text` | Integer 1–5, nullable original title, original body string. Google titles are usually null. |
| `sourceDate`, `sourceDateType` | ISO UTC source date; `published`, `updated` or `unspecified`. An update date is not an inferred original publication time. |
| `scrapedAt` | ISO UTC observation time. |
| `country`, `language` | Requested country/storefront and nullable requested Google language. Not reviewer residence or detected text language. |
| `appVersion` | Nullable version attached to this review. Current app version is stored separately in the profile. |
| `reviewerName`, `reviewerUrl`, `reviewerImage` | Nullable public reviewer display name, profile URL and image URL. |
| `helpfulCount`, `voteCount`, `voteMetric` | Nullable source vote values. Metric is `net_votes` for Apple, `thumbs_up` for Google, or null. Apple net votes can be negative. |
| `developerReplyStatus` | `present`, `none` or `unavailable`. Unavailable does not mean no reply. |
| `replyId`, `replyText`, `replyDate`, `replyDateType` | Nullable source response ID, original text, ISO UTC timestamp and `modified`/`unspecified` date meaning. |
| `isEdited`, `reviewUrl` | Nullable Apple edit flag and review link. Apple's app-level review links are not represented as unique permalinks. |
| `reviewTags` | Array of `{criteria, rating}` source criteria, where available; empty otherwise. |
| `source`, `sources`, `fieldSources` | Primary adapter, contributing adapter array and per-field provenance map. Adapters: `apple_catalog`, `apple_rss`, `google_play_rpc`. |
| `sourceData` | Optional original payloads keyed by adapter. Included by default; Google retains the full source row array, including unmapped positions. |

Illustrative review below uses a fictional app and reviewer, with `includeRawData: false`. Real rows contain the source's original text and values:

```json
{
  "schemaVersion": 1,
  "store": "google_play",
  "appId": "com.example.notes",
  "appName": "Example Notes",
  "appUrl": "https://play.google.com/store/apps/details?id=com.example.notes",
  "developerName": "Example Developer",
  "appRating": 4.2,
  "appRatingCount": 12500,
  "reviewId": "demo-review-001",
  "reviewKey": "google_play:com.example.notes:demo-review-001",
  "rating": 2,
  "title": null,
  "text": "Sync stopped working after the latest update.",
  "sourceDate": "2026-10-12T09:00:00.000Z",
  "sourceDateType": "unspecified",
  "scrapedAt": "2026-10-14T09:00:00.000Z",
  "country": "us",
  "language": "en",
  "appVersion": "3.2.1",
  "reviewerName": "Example Reviewer",
  "reviewerUrl": null,
  "reviewerImage": null,
  "helpfulCount": 7,
  "voteCount": null,
  "voteMetric": "thumbs_up",
  "developerReplyStatus": "present",
  "replyId": null,
  "replyText": "Please contact support so we can investigate.",
  "replyDate": "2026-10-13T10:00:00.000Z",
  "replyDateType": "unspecified",
  "isEdited": null,
  "reviewUrl": "https://play.google.com/store/apps/details?id=com.example.notes&reviewId=demo-review-001",
  "reviewTags": [],
  "source": "google_play_rpc",
  "sources": ["google_play_rpc"],
  "fieldSources": {
    "reviewId": "google_play_rpc",
    "rating": "google_play_rpc",
    "text": "google_play_rpc",
    "sourceDate": "google_play_rpc",
    "reviewerName": "google_play_rpc",
    "appVersion": "google_play_rpc",
    "helpfulCount": "google_play_rpc",
    "replyText": "google_play_rpc",
    "replyDate": "google_play_rpc"
  }
}
```

Google deduplicates by app and source review ID across requested locales; the first matching observation is retained. Apple keys also include the storefront. Resume within the same run reconciles existing rows before continuing. A separate new run can export the same reviews again; cross-run monitoring is not included.

### App metadata and collection report

The run's key-value store contains three types of result records:

| Record | Contents |
| --- | --- |
| `SUMMARY` | Run totals and one report per app/country/language: examined candidates, matches, unique output, duplicates, requests, field availability counts, source, date bounds, warnings, errors and stop reason. |
| `APPS` | `{ "apps": [...] }` index. Each entry contains `store`, `appId`, `country`, `language` and the `key` of its full profile. Empty if metadata is disabled or unavailable. |
| `APP_*` | Profile identified by the index key: current title, developer, ratings/histogram, capture time, complete available store-specific metadata in `details`, and optional original metadata sections in `sourceData`. |

Profiles retain available descriptions, price/currency, publisher/contact fields, categories, versions, screenshots and platform requirements. Google additionally exposes available install ranges and release/update fields. Exact keys vary by store. App profiles and reports are separate from review rows.

Read a profile at `https://api.apify.com/v2/key-value-stores/{defaultKeyValueStoreId}/records/{key}`, authenticating with your Apify token. Internal `STATE_*`/`ENRICH_*` records support recovery and are not analysis results.

`SUMMARY.failedPartitions` can be positive even when some reviews were successfully exported. All-source failure fails the run; a valid collection with no matching reviews succeeds with a report. A metadata warning does not discard reviews.

Per-context stop reasons distinguish `source_exhausted`, `source_limit`, `per_context_limit`, `global_limit`, `scan_limit`, `request_limit`, `spending_limit`, `source_error` and `interrupted`. Overall `partitions_finished` means each context stopped; inspect those individual reasons. `exhaustedReachableSource: true` describes the selected endpoint, while `historicalCompleteness` remains `not_guaranteed`.

### Inputs

| Input | Default | Behavior |
| --- | --- | --- |
| `apps` | Required | Array of mixed app IDs/package names or HTTPS store URLs. |
| `countries` | URL country, then `us` | Two-letter storefront/country codes. Explicit array overrides URL hints. |
| `languages` | Play URL language, then `en` | Array of Google language codes; each creates a context. Apple language remains null. |
| `sort` | `newest` | `newest` or `mostHelpful` within each context. The combined dataset is not globally sorted. |
| `maxReviews` | `10000` | Total unique output cap. `0` removes this ceiling. |
| `maxReviewsPerAppCountry` | `1000` | Unique output cap for each app/country/language context. `0` removes this ceiling. |
| `ratings` | `[1,2,3,4,5]` | Keep any listed star rating. One Google rating uses a source-side filter. |
| `dateFrom`, `dateTo` | Unset | Inclusive source-date window. YYYY-MM-DD uses UTC and includes the entire ending day. ISO timestamps require a timezone. |
| `keywords` | Unset | Array of case-insensitive title/body matches; any listed keyword matches. |
| `appVersions` | Unset | Exact source review versions. Missing versions cannot match. |
| `replyFilter` | `all` | `all`, `withReply` or `withoutReply`. Unavailable status does not match either reply-specific filter. |
| `appleSource` | `auto` | Catalog pagination with disclosed RSS fallback; `catalog` requires catalog availability; `rss` selects the limited feed. |
| `enrichAppleReviews` | `true` | Supplement Apple catalog rows with available RSS versions/votes from up to ten feed pages. |
| `includeAppMetadata` | `true` | Collect full available app profiles in the key-value store and app context on review rows. |
| `includeRawData` | `true` | Preserve original review/metadata payloads, including unmapped source fields. |
| `maxReviewsScannedPerAppCountry` | `100000` | Examined candidate cap per context, including duplicates and filter rejects. `0` removes it. A positive ceiling must be at least a positive per-context review cap. |
| `maxRequestsPerAppCountry` | `10000` | HTTP-attempt cap per context, including metadata, enrichment and retries. `0` removes it. |
| `maxConcurrency` | `3` | Simultaneous contexts, from 1 to 10. Pages within a context remain sequential. |
| `requestIntervalMillis` | `350` | Minimum shared spacing per source host; Apple lookups have additional spacing. |
| `requestTimeoutSecs` | `30` | Timeout for each HTTP attempt. |
| `maxRetries` | `3` | Bounded retries with backoff for transient failures. |
| `proxyConfiguration` | Direct | Optional standard Apify/custom proxy configuration, applied to review and metadata requests. |

At most 1,000 expanded contexts are accepted per run. Split larger jobs across runs. Contexts receive pages in rounds; a low global cap can leave some unfinished. Inspect the report before comparing context counts.

### Apple and Google field availability

Apple catalog pagination reaches beyond the finite RSS review feed and exposes available developer responses and edit flags. Review versions and votes are not consistently present in the catalog. RSS enrichment supplements its recent/helpful window, generally up to 500 reviews per storefront/sort order. Older catalog rows can therefore have null versions or votes.

Apple RSS alone cannot determine developer replies. A reply-specific filter with RSS, or with an unavailable catalog, produces a visible source error. Automatic fallback is disclosed; reaching the ten-page feed ceiling is reported as `source_limit`.

Google timestamps can reflect edits without exposing the original publication date. Requested countries and languages do not prove reviewer residence or actual text language. Rating counts include ratings without written text and do not establish export completeness.

The actor preserves all fields available from its selected public sources, including original payloads by default. Deleted/private reviews, unavailable historical fields, reviewer email addresses and a complete review edit history are not publicly exposed by these sources.

### Use with AI agents and MCP

Actor identifier: **`whoareyouanas/app-store-google-play-review-scraper`**.

Connect a remote MCP client using OAuth with this configuration, or add an `Authorization: Bearer <APIFY_TOKEN>` header if your client uses token authentication:

```json
{
  "mcpServers": {
    "appReviews": {
      "url": "https://mcp.apify.com?tools=actors,whoareyouanas/app-store-google-play-review-scraper,get-dataset-schema"
    }
  }
}
```

After publication, agents can discover the actor with `search-actors` and inspect its contract with `fetch-actor-details`. Calls return run/storage IDs. Read results with `get-dataset-items` and `get-key-value-store-record`, obtain review field types with `get-dataset-schema`, and poll longer runs with `get-actor-run`. See [Apify MCP documentation](https://docs.apify.com/mcp).

An agent's first inspection can use this bounded input. Turning off raw payloads here reduces response size; keep them enabled for a full archival export:

```json
{
  "apps": ["310633997", "com.whatsapp"],
  "countries": ["us"],
  "languages": ["en"],
  "maxReviewsPerAppCountry": 25,
  "maxReviews": 50,
  "maxReviewsScannedPerAppCountry": 500,
  "maxRequestsPerAppCountry": 50,
  "includeAppMetadata": true,
  "includeRawData": false
}
```

Agent workflow:

1. Read `fetch-actor-details` with the actor identifier and `output: { inputSchema: true, readme: true, outputSchema: true }`. Resolve app IDs/URLs and choose storefronts, filters and finite caps. Use `call-actor` with `callOptions` for memory, timeout or `maxTotalChargeUsd`; those controls are outside actor input.
2. Wait for a terminal run status, then read `SUMMARY` and inspect failed contexts, stop reasons and field coverage.
3. Read the preview or page the dataset with `limit`/`offset`, `clean: false` and selected `fields`. Use `get-dataset-schema` for the collected field types. Read `SUMMARY`/`APPS` with `get-key-value-store-record` using `keyValueStoreId` and `recordKey`; follow profile keys for full app context.
4. Join on `reviewKey`. Treat null values as unavailable, preserve date/vote semantics, and base conclusions on the exported sample and reported coverage.

Example prompt: “Compare one- and two-star feedback for these iOS and Android apps in the US. Start with 50 reviews per app. Identify recurring problems using quoted source text and review IDs, and report any collection limits.”

### API example

Install the official `apify-client` package and set `APIFY_TOKEN` in your environment. Run limits are separate from actor input:

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('whoareyouanas/app-store-google-play-review-scraper').call({
  apps: ['310633997', 'com.whatsapp'],
  countries: ['us'],
  languages: ['en'],
  maxReviewsPerAppCountry: 50,
  maxReviews: 100,
  includeRawData: true
}, { memory: 512, timeout: 600, maxTotalChargeUsd: 1 });

const report = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('SUMMARY');
if (run.status !== 'SUCCEEDED' || report?.value?.failedPartitions > 0) {
  throw new Error('Inspect the run log and SUMMARY before using partial results.');
}
const page = await client.dataset(run.defaultDatasetId).listItems({ limit: 100, offset: 0 });
console.log(page.items);
const appIndex = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('APPS');
console.log(appIndex?.value);
```

For larger exports, keep increasing `offset` until an empty page is returned. Retrieve the full `APP_*` records named in the index. The equivalent REST workflow starts with `POST /v2/acts/whoareyouanas~app-store-google-play-review-scraper/runs`, polls `GET /v2/actor-runs/{runId}`, then reads the default dataset/key-value store. See the [official JavaScript client](https://docs.apify.com/api/client/js/docs) and [run API](https://docs.apify.com/api/v2/actors-runs-post).

### Pricing

Launch pricing is **$0.50 per 1,000 exported reviews** ($0.0005 per unique dataset row), plus **$0.00005 per run start**. For example, 10,000 exported reviews cost $5.00005 before tax. No rental subscription is required. App profiles and collection reports are included; duplicate candidates and filter rejects do not create review charges.

Apify's maximum run charge can stop collection before your review caps are reached. The report records this as `spending_limit`. Interrupted/resurrected runs retain delivered rows and reconcile them before continuing.

### Reliability and support

The actor has been validated with 5,000 distinct reviews from each store, multiple country/language contexts, public developer replies, filtered exports, Apify Proxy and interrupted-run recovery. These checks establish working collection paths, while available fields and reachable history remain source-dependent.

For a collection problem, share the run ID and `SUMMARY` errors/warnings through the actor's Issues tab. Keep app IDs, requested storefronts and filter settings in the report so the workload can be reproduced.

Metadata parsing uses pinned helpers from the MIT-licensed [google-play-scraper](https://github.com/facundoolano/google-play-scraper); all network requests pass through this actor's timeout, proxy and retry controls.

# Actor input Schema

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

Required, nonempty array. Apple numeric app IDs (310633997), Android package names (com.whatsapp) or HTTPS apps.apple.com/play.google.com URLs. Both stores can be mixed. App discovery by search/name is not supported.

## `countries` (type: `array`):

Two-letter codes. Overrides URL countries when supplied; otherwise URL country or US is used.

## `languages` (type: `array`):

Each language is a separate request context. Defaults to the Play URL language or English. It does not translate text or identify its actual language.

## `sort` (type: `string`):

Sort within each source context. The combined dataset is not globally date sorted.

## `maxReviews` (type: `integer`):

Unique exported reviews across all apps; 0 means no result ceiling.

## `maxReviewsPerAppCountry` (type: `integer`):

Unique emitted rows attributed to each context. Duplicates do not consume the cap. 0 means no result ceiling.

## `ratings` (type: `array`):

Keep any listed star rating. Other filters combine with AND.

## `dateFrom` (type: `string`):

YYYY-MM-DD or ISO timestamp with timezone. Compared with sourceDate, which may be an edit date.

## `dateTo` (type: `string`):

Inclusive YYYY-MM-DD UTC day or ISO timestamp with timezone.

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

Case-insensitive title/body match; any listed keyword matches. Searches retrieved candidates within the work limits.

## `appVersions` (type: `array`):

Exact versions attached to source reviews. Apple catalog versions may be unavailable outside the finite RSS enrichment window.

## `replyFilter` (type: `string`):

RSS cannot determine reply status. Unsupported collection is reported as a source error, rather than an empty export.

## `appleSource` (type: `string`):

Auto uses deeper catalog pagination and discloses any limited RSS fallback. Catalog mode fails visibly if catalog becomes unavailable.

## `enrichAppleReviews` (type: `boolean`):

Fetch up to ten RSS pages to add available source versions and vote counts to catalog reviews. Includes additional requests.

## `includeAppMetadata` (type: `boolean`):

Store app profiles, rating histograms and available source metadata in the run key-value store. Metadata is not a charged review row.

## `includeRawData` (type: `boolean`):

Preserves original review payloads and app metadata sections, including unmapped fields. Increases export size.

## `maxReviewsScannedPerAppCountry` (type: `integer`):

Counts examined candidates, including duplicates and filter rejects. Must be at least the per-context review cap; 0 removes this ceiling.

## `maxRequestsPerAppCountry` (type: `integer`):

Counts metadata, enrichment, page requests and retries. 0 removes this ceiling. Endpoint exhaustion still does not prove complete historical coverage.

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

Independent app/country/language contexts. Continuation pages within each context run sequentially.

## `requestIntervalMillis` (type: `integer`):

Shared per-host delay. Apple metadata lookups have an additional 3-second spacing.

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

Timeout applied to each HTTP attempt.

## `maxRetries` (type: `integer`):

Bounded backoff for throttling and transient failures. Permanent errors and parser changes fail visibly.

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

Optional proxy configuration, applied to all source and metadata requests. Direct requests are the default.

## Actor input object example

```json
{
  "apps": [
    "310633997",
    "com.whatsapp"
  ],
  "sort": "newest",
  "maxReviews": 10000,
  "maxReviewsPerAppCountry": 1000,
  "ratings": [
    1,
    2,
    3,
    4,
    5
  ],
  "replyFilter": "all",
  "appleSource": "auto",
  "enrichAppleReviews": true,
  "includeAppMetadata": true,
  "includeRawData": true,
  "maxReviewsScannedPerAppCountry": 100000,
  "maxRequestsPerAppCountry": 10000,
  "maxConcurrency": 3,
  "requestIntervalMillis": 350,
  "requestTimeoutSecs": 30,
  "maxRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `reviews` (type: `string`):

URL returning exported review objects: app/store identity, star rating, original text, source date, available review version, reviewer fields, votes, developer reply, provenance and optional sourceData. Use offset/limit to paginate large exports. No global date sort across apps. A null value means unavailable; country/language are request context.

## `reviewsPreview` (type: `string`):

URL returning at most 20 rows with core review and reply fields, excluding large original payloads. A preview of the existing dataset; it does not change collection or create new review charges. Read the full dataset with pagination for complete analysis.

## `reviewsCsv` (type: `string`):

URL exporting the reviews table view as CSV. This view selects core fields; full JSON also preserves provenance, reviewer details, tags and original source payloads.

## `collectionReport` (type: `string`):

URL returning SUMMARY: total unique reviews, failed contexts and per-app/country/language candidates scanned, requests, duplicates, source, field coverage, warnings, errors, date bounds and stop reasons. Always inspect before claiming complete coverage. historicalCompleteness is not_guaranteed.

## `appProfiles` (type: `string`):

URL returning APPS as {apps:\[{store,appId,country,language,key}]}. Each key identifies one APP\_\* JSON profile in this same key-value store. Fetch /records/{key} for full metadata. Empty when metadata is disabled or unavailable. Profiles are separate from charged review rows.

## `appProfileRecords` (type: `string`):

URL listing APP\_\* record keys in the appProfiles collection. Fetch /records/{key} from the same key-value store for each profile. Use the APPS index for store, app and requested locale context.

# 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": [
        "310633997",
        "com.whatsapp"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("whoareyouanas/app-store-google-play-review-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": [
        "310633997",
        "com.whatsapp",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("whoareyouanas/app-store-google-play-review-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": [
    "310633997",
    "com.whatsapp"
  ]
}' |
apify call whoareyouanas/app-store-google-play-review-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,whoareyouanas/app-store-google-play-review-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/5vX6gzxeh0khBkLxD/builds/61Qu64N2NewDjEEqH/openapi.json
