# App Review Insights · Release Drops, Complaint Terms, Replies (`thequietstack/app-review-insights`) Actor

Turn a dataset of app reviews into answers: which release lost stars, which words only unhappy users write, per language, plus developer reply rate and monthly trend. Works on Google Play and App Store review datasets. No scraping, no AI cost.

- **URL**: https://apify.com/thequietstack/app-review-insights.md
- **Developed by:** [TheQuietStack](https://apify.com/thequietstack) (community)
- **Categories:** Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 insight rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Insights: Release Drops, Complaint Terms, Reply Rates

You scraped thousands of app reviews. Now what? This Actor reads a review dataset **from your own Apify account** and returns the answers as a small table: which release lost stars, which words only unhappy users write, how often and how fast the developer replies, and how the rating moves month by month.

It does no scraping and uses no AI model, so there is no extra source to break and the same dataset always gives the same result. Review texts and author names never appear in the output.

**Typical uses:** spot the release that caused a rating drop · see complaints per language without reading them · compare a competitor's reply rate with yours · a monthly app health report for a client.

### Input example

```json
{ "datasetIds": ["YOUR_REVIEW_DATASET_ID"], "minReviewsPerVersion": 30 }
```

Pick the dataset of an earlier run in the input form. Several datasets are merged, and the same review is counted once. Leave the field empty to see the output on a small **fictional sample**, free of charge.

Works with the output of [Google Play Reviews Scraper](https://apify.com/thequietstack/google-play-reviews) and [App Store Reviews Scraper](https://apify.com/thequietstack/app-store-reviews), and with other review datasets that have a 1-5 rating field (`rating`, `stars` or `score`). Text, version, language, date and reply fields are recognised by their usual names; a missing field only removes the rows that need it.

### Output

| Row `type` | What it says |
|---|---|
| `app-summary` | Reviews, exact star counts, average, 1-2 star share, reply rate, median reply time, top languages |
| `version` | Per version: reviews, average, 1-2 star share, change against the previous version, `regression` flag |
| `complaint-term` | Words and two-word terms typical of 1-2 star reviews, per language, with exact review counts |
| `month` | Reviews, average and 1-2 star share per month |

```json
{ "type": "version", "app": "Example Notes", "version": "3.3.0", "reviews": 80, "avgRating": 3.138, "lowShare": 0.45,
  "previousVersion": "3.2.0", "lowShareChange": 0.325, "zScore": 4.54, "regression": true }
```

### How the numbers work

- **Counts are exact.** Averages and shares are rounded to 3 decimals, scores to 2.
- `regression` is true when the 1-2 star share rose by at least 5 points and a two-proportion test gives z ≥ 2.58 against the previous version. Versions below `minReviewsPerVersion` are not compared.
- `score` on complaint terms is a log-odds z-score (Monroe et al. 2008): how much more typical a term is of 1-2 star reviews than of 4-5 star reviews. 3-star reviews are not used for terms.

### Pricing

Pay per event: **one charge per insight row**. Your review count does not matter, and the fictional sample is free. `maxRows` caps every run, and app summaries and regressions are written first.

### Honest limits

- The result describes **your dataset**, not the whole app. A dataset filtered by stars or cut by a limit gives a skewed star split. For fair comparisons, collect all ratings with sort "newest".
- People review with delay and may keep an old version number, so a release is a strong hint, not proof of cause.
- Stopwords exist for English, German, Spanish, French, Portuguese and Italian. In other languages some common words can appear as terms.
- Terms come from words, not meaning: "crash" and "crashes" are counted separately.
- Datasets must be selected in the input: this Actor cannot see anything else in your account.

# Actor input Schema

## `datasetIds` (type: `array`):

Datasets from your account with one review per row, e.g. the output of a Google Play or App Store reviews Actor. Several datasets are merged; the same review is counted once. Empty: the Actor analyses a small built-in fictional sample, free of charge, so you can see the output.

## `minReviewsPerVersion` (type: `integer`):

Versions with fewer reviews are not compared: small samples produce false alarms.

## `minReviewsPerTerm` (type: `integer`):

A term must appear in at least this many 1-2 star reviews.

## `maxTermsPerLanguage` (type: `integer`):

Strongest terms first.

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

Reading stops here and the SUMMARY says so. Results then cover only the reviews read.

## `maxRows` (type: `integer`):

Hard cap on charged rows. App summaries and release regressions come first, so the cap cuts the least important rows.

## Actor input object example

```json
{
  "minReviewsPerVersion": 30,
  "minReviewsPerTerm": 5,
  "maxTermsPerLanguage": 20,
  "maxReviews": 500000,
  "maxRows": 500
}
```

# Actor output Schema

## `insights` (type: `string`):

No description

## `summary` (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("thequietstack/app-review-insights").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("thequietstack/app-review-insights").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 thequietstack/app-review-insights --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thequietstack/app-review-insights"
        }
    }
}
```

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/HDFZOvWpgLB57bGnJ/builds/28FRTNjZPXDkPOlO0/openapi.json
