# App Store / Play Store Reviews — Unified ASO Review Feed (`codeclouds/app-store-play-store-reviews-unified`) Actor

Fetch Apple App Store and Google Play reviews for a given app ID or name, normalized to one flat schema per review. No API keys needed.

- **URL**: https://apify.com/codeclouds/app-store-play-store-reviews-unified.md
- **Developed by:** [Dennis](https://apify.com/codeclouds) (community)
- **Categories:** E-commerce, Other
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 review 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 / Play Store Reviews — Unified ASO Review Feed

Fetch Apple App Store and Google Play reviews for a given app (by app name or store ID) and get them normalized into one flat schema per review. Ideal for ASO monitoring, sentiment comparison, and feeding review intelligence into AI agents.

### When should an AI agent use this?

- "Get Apple and Google reviews for Spotify in one dataset."
- "Compare sentiment for my iOS and Android apps side-by-side."
- "Pull recent reviews (rating + text) for Apple app ID 324684580."
- "Monitor Play Store reviews by package ID com.spotify.music."
- "Fetch French reviews for an app to check local feedback."
- "Feed a review-watchdog or LLM trend analysis with fresh cross-store data."

### What this Actor does

This actor combines both major app stores into a single, predictable JSON feed:

- **Apple App Store** — uses Apple's official customer-reviews RSS endpoint
  (`itunes.apple.com/rss/customerreviews/id=<id>`). No tokens, no scraping on
  the details page, and the response stays small.
- **Google Play** — reads the public, non-authenticated app details page and
  extracts the visible review cards. No login and no API key required.
- **Normalized output** — both sources are flattened into the same record
  shape, so you never have to write merge logic yourself.
- **App-name resolution** — if you know the app's name but not its store IDs,
  the actor resolves the Apple track ID and the Android package ID for you.
  Explicit store IDs always win when you provide them.
- **Resilience** — Apple paginates until empty or `maxReviews` is reached;
  Play reads the visible review cards on the details page. `maxReviews` caps
  both. One failing source never aborts the other.

### Input

| Field | Type | Description |
|---|---|---|
| `appStoreId` | string | Apple numeric store ID (e.g. `324684580`). Optional if `appName` is given. |
| `playStoreAppId` | string | Google Play package ID (e.g. `com.spotify.music`). Optional if `appName` is given. |
| `appName` | string | App name used to resolve missing store IDs. Optional if the IDs are provided. |
| `country` | string | Two-letter country code, default `us`. |
| `language` | string | Two-letter language code, default `en`. |
| `maxReviews` | integer | Maximum reviews per source, default `50`, max `500`. |
| `platforms` | array | Which sources to run. Default `["app-store", "play-store"]`; allowed values `app-store` and `play-store`. |

At least one of `appStoreId`, `playStoreAppId`, or `appName` must be provided.

#### Example inputs

```json
{
  "appName": "Spotify",
  "maxReviews": 25
}
```

```json
{
  "appStoreId": "324684580",
  "platforms": ["app-store"],
  "maxReviews": 10
}
```

```json
{
  "playStoreAppId": "com.spotify.music",
  "platforms": ["play-store"],
  "maxReviews": 10
}
```

### Output

A flat JSON object per review. Same fields for both platforms.

| Field | Description |
|---|---|
| `id` | Stable composite ID: `platform:sourceId:reviewId`. |
| `platform` | `app-store` or `play-store`. |
| `appId` | Apple track ID or Android package ID. |
| `appName` | App title as published in the respective store (where available). |
| `author` | Reviewer pseudonym. |
| `rating` | Star rating as a number (1-5). |
| `title` | Review title (Apple only; empty for Play). |
| `text` | Review body text. |
| `version` | App version the review refers to (Apple only). |
| `date` | Review date when available (Apple ISO timestamp, Play text like `April 10, 2026`). |
| `country` | Country used for the fetch. |
| `sourceUrl` | Direct URL to the source review/store page. |
| `reviewId` | Source review identifier. |
| `scrapedAt` | ISO timestamp when the actor fetched the record. |

```json
{
  "id": "app-store:324684580:14567140607",
  "platform": "app-store",
  "appId": "324684580",
  "appName": "Spotify: Music and Podcasts",
  "author": "You'reMakingThingsWorse",
  "rating": 1,
  "title": "$$$ For what we should get free",
  "text": "If you like listening to one song then 5 ads...",
  "version": "9.1.84",
  "date": "2026-09-18T23:25:33-07:00",
  "country": "us",
  "sourceUrl": "https://itunes.apple.com/us/review?id=324684580",
  "reviewId": "14567140607",
  "scrapedAt": "2026-09-20T12:52:14Z"
}
```

### Use cases

- **Unified ASO monitoring** — track both stores from one scheduled run.
- **Cross-platform sentiment comparison** — join rating and text on the same
  `appName` to compare iOS vs Android perception.
- **Review dataset for AI agents** — a clean per-review feed that fits easily
  in an LLM context window.
- **Feedback triage pipelines** — pass recent reviews (text, version, date,
  rating) into issue trackers or dashboards.
- **Localization checks** — set `country`/`language` to pull storefront-specific feedback.

### Limitations

- Google Play's public page only renders a handful of review cards server-side;
  the actor returns those visible reviews (capped by `maxReviews`). Full Play
  pagination is not part of this MVP.
- Apple's RSS feed exposes recent reviews only; historical or paginated
  archives are not available through this endpoint.
- Play ratings are read from the `aria-label` of the star row; if the label
  format changes, the parser falls back safely to `0`.

### Pricing

Pay-Per-Event.

- `apify-actor-start`: $0.00005 (default start event)
- `review-result`: $0.003 per delivered review

### Legal

- **Apple**: the actor uses Apple's official customer-reviews RSS feed; no
  terms-of-service circumvention and no scraping of the details page.
- **Google Play**: the actor reads the public, non-authenticated app details
  page (the same HTML a visitor loads). No login, no consent wall bypass.
- Only pseudonymous reviewer names are collected. No email addresses, device
  identifiers, or other personal data are fetched or stored.

### FAQ

**Q: Can I use an app name instead of IDs?**\
A: Yes. `appName` resolves the Apple track ID via the iTunes Search API and
the Android package ID via a Play Store search. IDs, when provided, are always
used directly.

**Q: What happens if one source has no reviews or is empty?**\
A: That source yields no records and the run continues with the other one.
The exit status stays successful.

**Q: Can I run only one store?**\
A: Yes, set `platforms` to `["app-store"]` or `["play-store"]`.

**Q: Are there any API keys?**\
A: No. Both sources are public endpoints.

### Related Actors

This actor is the only portfolio actor that combines Apple and Google Play
reviews in one normalized dataset. For other application-level data, see the
portfolio overview in `PORTFOLIO_STATUS.md`.

### Keywords

app store reviews, play store reviews, aso, sentiment, review monitoring,
apple reviews, google play reviews, unified feed, app feedback, ASO review
scraper, app ratings.

### Changelog

#### 0.1.0

- Initial release: Apple App Store RSS + Google Play details page, app-name
  resolution, `maxReviews`, `platforms`, normalized output schema, pay-per-event
  pricing (`review-result`), dataset view, icon, tests.

# Actor input Schema

## `appStoreId` (type: `string`):

Numeric Apple App Store ID (e.g. 324684580). Optional if appName is provided.

## `playStoreAppId` (type: `string`):

Google Play package ID (e.g. com.spotify.music). Optional if appName is provided.

## `appName` (type: `string`):

App name to resolve IDs for both stores (default: Spotify). Optional if IDs are provided.

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

Two-letter country code for store feeds (default: us).

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

Two-letter language code (default: en).

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

Maximum reviews per source (default 50, max 500).

## `platforms` (type: `array`):

Platforms to include (default both).

## Actor input object example

```json
{
  "appName": "Spotify",
  "country": "us",
  "language": "en",
  "maxReviews": 50,
  "platforms": [
    "app-store",
    "play-store"
  ]
}
```

# Actor output Schema

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

Results stored in the default dataset.

# 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("codeclouds/app-store-play-store-reviews-unified").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("codeclouds/app-store-play-store-reviews-unified").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 codeclouds/app-store-play-store-reviews-unified --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,codeclouds/app-store-play-store-reviews-unified"
        }
    }
}
```

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/1tMw5RL64gbFv8tGg/builds/IKUdaqBgeN7q6eiFU/openapi.json
