# App Review AI Analyzer: Your App Store & Play Reviews (`reliable_tools/app-review-scraper`) Actor

Upload your own App Store and Google Play reviews (CSV or JSON) or connect the Google Play Developer API for your own Android apps, and get AI labels for bugs, pricing, billing, feature requests and churn, with trends by app version.

- **URL**: https://apify.com/reliable_tools/app-review-scraper.md
- **Developed by:** [Reliable Tools](https://apify.com/reliable_tools) (community)
- **Categories:** Developer tools, AI, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 Review Analyzer with AI Labels for Your App Store and Google Play Reviews

This app review analyzer turns your own App Store and Google Play reviews into a clear list of what users complain about and ask for. Upload a reviews file (CSV or JSON) for any of your apps, or connect the official Google Play Developer API for Android apps you manage. Every review gets labels such as bug or crash, pricing complaint, subscription or billing issue, feature request, ads complaint and churn intent, plus a severity score. Every app also gets a summary with label counts, trends by app version, month and country, the most requested features and the most severe reviews.

The Actor does not scrape app stores. It only reads data you bring yourself, or data the official Google Play Developer API returns for your own apps with your own service account.

### Who it's for

- **Product managers** who want to see which release broke something and what users keep asking for.
- **App developers and indie studios** who don't have time to read hundreds of reviews after every update.
- **Growth and monetization teams** watching for paywall, pricing and billing pain before it shows up in churn.
- **Agencies and consultants** analysing review exports that their clients share with them.

### Where the reviews come from

| Source | What you provide | What you get |
|---|---|---|
| **Reviews file** | A CSV, JSON or JSON Lines file: upload it, give a direct link, pick a record in one of your Apify key-value stores, or paste the reviews as JSON | Every row with a rating and text, up to 10,000 per run |
| **Google Play Developer API** | Package name of your app plus the JSON key of a service account you invited in Play Console | Reviews created or edited in the **last 7 days** only (a Google limit) |

**Getting older Google Play reviews:** the Google Play Developer API only returns reviews from about the last week. For your full history, download the reviews export from Play Console (Download reports, Reviews) and upload that CSV here. The Actor reads Play Console's export format, including its UTF-16 encoding and column names, as is.

**App Store reviews:** there is no App Store API mode. Analyse your iPhone or iPad app's reviews from a file: copy your reviews out of App Store Connect (Ratings and Reviews) into a spreadsheet, or take an export from the review tool you already use, save it as CSV or JSON, and upload it. Apple has no one-click review export in App Store Connect, so a spreadsheet with the columns below is the simplest way.

#### File format

Column names are matched automatically and are not case sensitive. A row needs a **rating** (1 to 5) and **text**. The other columns are optional but make the trends more useful.

| Field | Accepted column names (examples) |
|---|---|
| rating | `rating`, `star rating`, `stars`, `score` |
| text | `text`, `review text`, `review`, `body`, `content`, `comment` |
| date | `date`, `review submit date and time`, `created date`, `createdAt`, `timestamp` (ISO dates, `10/31/2026`, `31.10.2026`, `Oct 31, 2026` or Unix time) |
| version | `version`, `app version name`, `appVersion` |
| country | `country`, `territory`, `storefront` |
| title | `title`, `review title` |
| app | `app`, `app name`, `package name`, `bundle id` (one summary per app) |
| store | `store`, `platform` (`ios`, `android`, `App Store`, `Google Play`) |
| other | `language`, `helpful votes`, `developer reply text` |

Comma, semicolon, tab and pipe separated files work. Rows that cannot be used are skipped and counted in one error row that says why, for example "3 rows skipped (1 missing rating, 1 date not readable, 1 rating not a number from 1 to 5)".

### What you get

| Field | What it is |
|---|---|
| `store`, `appId`, `appName` | `apple`, `google` or `import`, and the app the review belongs to |
| `country`, `language` | Country or territory and language, when the source provides them |
| `rating` | Star rating, 1 to 5 |
| `title`, `text` | Review title and review text, shortened to 500 characters by default |
| `date` | When the review was posted or last edited (UTC) |
| `version` | App version the review was written for |
| `helpfulVotes`, `developerReplied` | Helpful votes and whether you replied, when the source provides them |
| `labels` | AI labels the review clearly matches (probability 0.7 or higher) |
| `labelScores` | Probability for each of the 12 labels, 0 to 1, so you can set your own cut off |
| `severity`, `severityLevel`, `severityConfidence` | How serious the problem is: 0 means nothing is wrong, 1 means critical. Levels are none, minor, degraded, broken, critical |

The 12 labels are always the same, so results are comparable across apps and over time:

`bug_crash`, `performance`, `pricing_complaint`, `subscription_billing`, `feature_request`, `ux_design`, `customer_support`, `ads_complaint`, `privacy_concern`, `praise`, `churn_intent`, `competitor_mentioned`

A review can have several labels at once. "Love it but please add dark mode" is both `praise` and `feature_request`.

#### The app summary

After the reviews of each app, the Actor adds one row with `itemType` set to `appSummary`. It is also saved in the run's key-value store as `SUMMARY-<store>-<appId>`. It contains:

- Average rating and star distribution
- `labelCounts` and `labelShare` (share of AI labeled reviews with each label)
- `trendByVersion`, `trendByMonth` and `trendByCountry`: review count, average rating, label counts and average severity per version, month and country
- `topFeatureRequests`: reviews labeled as feature requests, most helpful first, with date, version, rating and a short quote
- `mostSevereReviews`: the reviews with the highest severity, with date, version, rating and a short quote

All of these numbers are computed from the reviews themselves, so you can always trace a count back to the reviews behind it.

### How to run it

**With a file**

1. Export your reviews as CSV or JSON, for example the Play Console reviews export, App Store reviews copied from App Store Connect into a spreadsheet, or an export from your support tool.
2. Upload it in **Reviews file**, or paste a direct link in **Reviews file URL**.
3. Optional: set **App name for the file** if the file has no app column, and **Only reviews since** to skip older reviews.
4. Start the run. Reviews show up in the **Reviews** tab, summaries are in the same dataset.

**With the Google Play Developer API (your own Android apps only)**

1. In Google Cloud create a service account and a JSON key, then invite the service account's email in Play Console (Users and permissions) with access to your app.
2. Paste the JSON key and add the package name, for example `com.example.app`, in **Your Google Play apps**.
3. Start the run. The key is a secret input: it is encrypted by Apify, used only to call Google's API during your run, and never written to the output.

You can combine both modes in one run.

### Example output

These examples come from a test run on a file of invented reviews for a fictional app.

```json
{
  "itemType": "review",
  "store": "import",
  "appId": "DemoFit (fictional test app)",
  "appName": "DemoFit (fictional test app)",
  "rating": 1,
  "title": "Cancelling",
  "text": "Cancelled my subscription today. Too many bugs lately, switching to another tracker.",
  "date": "2026-10-23T00:00:00+00:00",
  "version": "4.2.0",
  "country": "gb",
  "language": null,
  "helpfulVotes": 0,
  "developerReplied": null,
  "labels": [
    "bug_crash",
    "subscription_billing",
    "churn_intent"
  ],
  "labelScores": {
    "bug_crash": 0.86,
    "performance": 0.07,
    "pricing_complaint": 0.05,
    "subscription_billing": 0.96,
    "feature_request": 0.07,
    "ux_design": 0.14,
    "customer_support": 0.02,
    "ads_complaint": 0.02,
    "privacy_concern": 0.06,
    "praise": 0.01,
    "churn_intent": 0.99,
    "competitor_mentioned": 0.11
  },
  "severity": 0.562,
  "severityLevel": "degraded",
  "severityConfidence": 0.79
}
```

A shortened summary row from the same run:

```json
{
  "itemType": "appSummary",
  "store": "import",
  "appId": "DemoFit (fictional test app)",
  "appName": "DemoFit (fictional test app)",
  "source": "import",
  "reviewsCollected": 50,
  "reviewsAiLabeled": 50,
  "avgRating": 3.24,
  "avgSeverity": 0.355,
  "labelCounts": {
    "praise": 22,
    "bug_crash": 10,
    "subscription_billing": 8,
    "feature_request": 7,
    "ux_design": 6,
    "performance": 4
  },
  "trendByVersion": [
    {
      "key": "4.2.0",
      "reviews": 15,
      "avgRating": 2.67,
      "avgSeverity": 0.483
    },
    {
      "key": "4.1.3",
      "reviews": 15,
      "avgRating": 3.33,
      "avgSeverity": 0.317
    }
  ],
  "topFeatureRequests": [
    {
      "country": "us",
      "rating": 4,
      "date": "2026-10-07T00:00:00+00:00",
      "version": "4.1.3",
      "quote": "Love it. Could you add swimming as a workout type?"
    }
  ],
  "mostSevereReviews": [
    {
      "country": "de",
      "rating": 1,
      "date": "2026-09-02T00:00:00+00:00",
      "version": "4.0.2",
      "quote": "All my data disappeared after changing phones. Backup did not work."
    }
  ]
}
```

### How to use the app review analyzer via API

You can run the Actor in the Apify Console, or call it from your own code through the Apify API. The **API** tab of this Actor has ready-to-copy examples for the JavaScript and Python API clients, the Apify CLI, plain HTTP and the OpenAPI definition. To use it from an AI assistant or agent, connect the Apify MCP server and add this Actor as a tool.

Send reviews inline in the `reviews` field, or a file link in `reviewsFileUrl`, start a run, and read the results from the run's default dataset as JSON, CSV or Excel. You can also schedule runs in Apify, for example a weekly run with the official API mode and **Only reviews since** set to `7 days`.

### Pricing

You pay per result:

- **Review**: charged once for every review saved to your dataset.
- **AI labeled review**: charged once for every review that got its labels and severity score. Turn AI labels off and this charge disappears.

Error rows, skipped file rows, summary rows and duplicate reviews are never charged. The example reviews filled in on the input form are a free demo (marked `demo: true`). If you set a maximum cost for the run, the Actor stops cleanly when it is reached.

### FAQ

**Does it scrape the App Store or Google Play?**
No. Earlier versions read public store pages. That path has been removed. The Actor now only analyses reviews you upload, or reviews that the official Google Play Developer API returns for your own apps with your own service account. Links to app store, Apple or Google pages are refused as file URLs. Every address, including each redirect, is normalized and checked before anything is requested, so a link that redirects to such a page is stopped without a request to that site. Use a normal web address of your own file, for example from your cloud storage, or upload the file.

**Can I analyse a competitor's reviews?**
Only if you have the right to use that data, for example a dataset you licensed. The Google Play API mode only works for apps your service account has access to.

**Why does the Google Play API mode return so few reviews?**
Google's reply-to-reviews API only returns reviews created or edited in the last 7 days, and only reviews with text. For older reviews, upload the Play Console reviews export instead.

**Can I connect my App Store Connect API key?**
No. For App Store apps the Actor works from a file only. Upload your reviews as CSV or JSON as described above.

**Is using my Google Play service account with this Actor allowed?**
Google's API documentation describes using the reply-to-reviews API from your existing customer support tools, and the Google APIs Terms cover others acting on your behalf. The Actor uses your key only during your run, never writes it to the output or to any other storage, and uses the data for nothing else. Apify keeps the run input, with the key encrypted, for your account's data retention period, so delete the run if you want it gone sooner. Use a separate service account with access only to the apps you want to analyse, so you can remove it at any time.

**What personal data does it return?**
None on purpose. Reviewer names, nicknames and store review IDs are not output and review text is shortened. Review text can still mention people, so treat the output with care. Privacy: the Actor runs on Apify, which processes the data as our processor. Review text is sent to an AI service provider (a sub-processor bound by a data processing agreement with standard contractual clauses) only to compute the labels and is not kept after the run. Results stay in your own Apify storage.

**Why does a review have no labels at all?**
Either none of the 12 labels clearly fits (short reviews like "ok" often end up here), or AI labels were turned off. Check `labelScores` to see how close each label came.

**How accurate are the labels?**
They are a fast first pass, not a human reading. The obvious cases (crashes, billing problems, praise, ads) are labeled reliably, and borderline reviews show up with middle probabilities in `labelScores`. Spot check a sample before you report numbers to others. Labels work best in English; other languages are labeled too, with a little more noise.

**What happens if my file has a problem?**
You get an error row that explains it, for example an empty file, JSON that cannot be parsed, or a CSV without a rating column, and you are not charged for it.

### Disclaimer

Not affiliated with, endorsed or sponsored by Apple or Google. App Store and App Store Connect are trademarks of Apple Inc. Google Play is a trademark of Google LLC.

### About Reliable Tools

Reliable Tools builds focused Actors that do one job well and tell you exactly what you pay for. See all our Actors at [apify.com/reliable_tools](https://apify.com/reliable_tools).

# Actor input Schema

## `reviewsFile` (type: `string`):

Upload your own reviews as CSV, JSON or JSON Lines, for example a Play Console reviews export, or App Store reviews you copied out of App Store Connect or exported from your review tool. Each row needs a rating (1 to 5) and the review text. Date, version, country, title and app name are recommended. Column names are matched automatically (date, rating, text, title, version, country, app, ...).

## `reviewsFileUrl` (type: `string`):

Direct link to a CSV or JSON file you own, for example a cloud storage link. App store pages are not accepted. The website's robots.txt must allow the download. Max 20 MB.

## `reviewsKeyValueStore` (type: `string`):

Pick one of your Apify key-value stores that holds the reviews file. The Actor only gets read access to this store.

## `reviewsRecordKey` (type: `string`):

Key of the record with the reviews file, for example REVIEWS_CSV.

## `reviews` (type: `array`):

A list of review objects, for example \[{"date": "2026-10-01", "rating": 2, "text": "Crashes on login", "version": "3.2.0", "country": "us"}]. The example reviews filled in here are a free demo and are not charged.

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

Optional. Used in the summary when your file has no app column.

## `maxImportedReviews` (type: `integer`):

At most this many reviews from your file are analysed (up to 10000).

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

Only for Android apps you manage, together with your own service account key below. Google Play package names, for example com.example.app. Public store pages are never read. For App Store apps, upload your reviews as a file instead.

## `googlePlayServiceAccountJson` (type: `string`):

JSON key of a Google Cloud service account that you invited in Play Console with access to the app. Google returns only reviews created or edited in the last 7 days through this API; for older reviews upload a Play Console reviews export as a file.

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

Newest reviews first, at most 1000 per app.

## `reviewsSince` (type: `string`):

Optional. Skip reviews older than this date (both modes).

## `aiLabels` (type: `boolean`):

Adds 12 AI labels with probabilities (bug/crash, performance, pricing, subscription/billing, feature request, UX/design, support, ads, privacy, praise, churn intent, competitor mentioned) and a severity score to every review. Charged per labeled review.

## `maxTextLength` (type: `integer`):

Review text is shortened to this many characters (50 to 500). The AI labels still read the whole review.

## Actor input object example

```json
{
  "reviews": [
    {
      "date": "2026-10-02",
      "rating": 1,
      "text": "Example review: the app crashes every time I open the camera screen since the last update.",
      "version": "3.2.0",
      "country": "us"
    },
    {
      "date": "2026-10-05",
      "rating": 2,
      "text": "Example review: I was charged twice for the yearly plan and support has not answered.",
      "version": "3.2.0",
      "country": "gb"
    },
    {
      "date": "2026-09-20",
      "rating": 5,
      "text": "Example review: love it, please add a dark mode.",
      "version": "3.1.4",
      "country": "de"
    }
  ],
  "maxImportedReviews": 10000,
  "maxReviewsPerApp": 1000,
  "aiLabels": true,
  "maxTextLength": 500
}
```

# Actor output Schema

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

Dataset with review rows (itemType review) and summary rows (itemType appSummary).

## `summaries` (type: `string`):

Same dataset, all fields, including the appSummary rows.

# 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 = {
    "reviews": [
        {
            "date": "2026-10-02",
            "rating": 1,
            "text": "Example review: the app crashes every time I open the camera screen since the last update.",
            "version": "3.2.0",
            "country": "us"
        },
        {
            "date": "2026-10-05",
            "rating": 2,
            "text": "Example review: I was charged twice for the yearly plan and support has not answered.",
            "version": "3.2.0",
            "country": "gb"
        },
        {
            "date": "2026-09-20",
            "rating": 5,
            "text": "Example review: love it, please add a dark mode.",
            "version": "3.1.4",
            "country": "de"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("reliable_tools/app-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 = { "reviews": [
        {
            "date": "2026-10-02",
            "rating": 1,
            "text": "Example review: the app crashes every time I open the camera screen since the last update.",
            "version": "3.2.0",
            "country": "us",
        },
        {
            "date": "2026-10-05",
            "rating": 2,
            "text": "Example review: I was charged twice for the yearly plan and support has not answered.",
            "version": "3.2.0",
            "country": "gb",
        },
        {
            "date": "2026-09-20",
            "rating": 5,
            "text": "Example review: love it, please add a dark mode.",
            "version": "3.1.4",
            "country": "de",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("reliable_tools/app-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 '{
  "reviews": [
    {
      "date": "2026-10-02",
      "rating": 1,
      "text": "Example review: the app crashes every time I open the camera screen since the last update.",
      "version": "3.2.0",
      "country": "us"
    },
    {
      "date": "2026-10-05",
      "rating": 2,
      "text": "Example review: I was charged twice for the yearly plan and support has not answered.",
      "version": "3.2.0",
      "country": "gb"
    },
    {
      "date": "2026-09-20",
      "rating": 5,
      "text": "Example review: love it, please add a dark mode.",
      "version": "3.1.4",
      "country": "de"
    }
  ]
}' |
apify call reliable_tools/app-review-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reliable_tools/app-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/2dliEN40xzslO11Pj/builds/16YkeSjPocV8oW0ND/openapi.json
