App Review Triage Monitor — App Store & Google Play Alerts
Sort new App Store and Google Play reviews into bugs, billing and feature requests. Get alerts on rating drops in Slack. $0.40 per 1,000 reviews.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
apps,competitorApps,weeklyReport(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.0004 per review = $0.4 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Review processed | The returned review got processed | $0.0004 |
| Report generated | The job report got generated | $0.005 |
| App checked | The user checked an app | $0.004 |
| AI triage generated | generated AI triage | $0.0005 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-04, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
apps | Each app: an optional label plus an App Store URL and/or a Google Play URL. You can monitor one store or both, reviews are unified. | array |
competitorApps | Same shape as 'apps'. If provided, the run includes a comparison of competitors' new-review theme volume. | array |
weeklyReport | Write a forwardable HTML + Markdown triage report to the run's key-value store (REPORT.html / REPORT.md). | boolean |
useLLMTriage | On by default, but it does nothing unless you add your own Anthropic key above. Set to off to force the free built-in classifier even if a key is present. | boolean |
country | Two-letter store country code (e.g. us, gb, de, fr, jp). Applies to both stores. | string |
maxReviewsPerRun | Upper bound on reviews fetched per app per store, most-recent first. The diff means you only pay to triage the NEW ones. | integer |
onlyNewSinceLastRun | Emit and triage only reviews that are new or changed since the last scheduled run (recommended, this is what makes it a monitor, not a dumper). | boolean |
detectBugsCrashes | Surface bug/crash reviews as urgent items (with text + version). | boolean |
detectBillingComplaints | Surface billing/refund/subscription reviews as urgent items. | boolean |
detectFeatureRequests | Count feature-request reviews separately. | boolean |
detectRatingDrops | Alert when an app's blended (cross-store) rating drops vs the last snapshot. | boolean |
clusterThemes | Group similar new reviews (e.g. '5 new reviews mention login failure after v4.2'). | boolean |
webhookUrl | Optional. POST a compact JSON summary here after each run. A Slack incoming-webhook URL works directly (uses the 'text' field). | string |
anthropicApiKey | Totally optional. The Actor already works great with no key, its built-in classifier sorts every review for free, with zero setup. If you add your own Anthropic key, only the ~1-in-4 ambiguous reviews (sarcasm, mixed feedback, no clear keyword) get a sharper second look for a more accurate call. Your key, billed to your own Anthropic account, private to your runs. Get one at console.anthropic.com. Leave blank to stay 100% free and rules-based. | string |
What you get
A structured dataset — each result includes fields like:
app_idbucket_countschanged_countclustersfresh_countlabelnew_countrating_afterrating_beforerating_changerating_drop_alertrun_atstore_ratingsstoresExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
4 ready-to-run use cases
Play Store and App Store Review Scraper for Crashes
New reviews from both stores in one run, with the crash and bug ones flagged and grouped by theme. Keyword rules do the flagging, not a model.
App Review Management: Billing and Refund Complaints
Pulls new reviews from both stores and flags the ones about charges, refunds and subscriptions, grouped by theme with a per-run count of each.
App Review Analytics: Feature Requests by Theme
Reads new App Store and Google Play reviews, flags the ones asking for something, and clusters them so you can see which request repeats most.
App Review Monitoring for Your App and Rival Apps
Runs the same review pull over your app and the rivals you name, over the same window, so the theme counts sit next to each other and compare.
Related tools in App Store Data
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
Google Play Reviews Scraper
Google Play reviews by app ID or URL: score, text, reviewer, date, developer reply. Any country. Up to 5,000 per app. $0.09 per 1,000.
App Store Scraper
Scrape the Apple App Store: app name, developer, rating, review count, price, genre and artwork, plus reviews. $0.09 per 1,000 apps.
Where this tool sits
- Categories
- App Store Data Monitors & Alerts Reviews & Reputation Data
- Platforms
- App Store & Google Play
App Review Triage: new App Store and Google Play reviews, sorted into bugs, billing and requests
Give it your apps and it reads the new reviews from both stores, sorts each one into a bucket (bug or crash, billing complaint, feature request, praise, other), groups the ones saying the same thing, and tells you when the rating moved. It remembers what it already saw, so the second run only brings you what is new.
The classifier is keyword-based and its keywords are English, so a review in another language usually lands in other at low confidence. That is the main reason to add your own Anthropic key: with one set, the ambiguous reviews get a second look. Without one it still runs, on rules alone.
The App Store's public feed carries about 500 recent reviews per app and no developer replies, so replies only ever come from Google Play.
| Input | Your apps, each with an App Store URL, a Google Play URL, or both |
| Output | One digest row per app, plus one row per new review |
| Ceiling | Up to 500 reviews per app per store per run |
| Account needed | None. Your own Anthropic key is optional |
| Price | $0.40 per 1,000 new reviews, plus per-app and per-report charges listed below |
🔔 What App Review Triage does
Every run it fetches the most recent reviews for each app, from each store you gave it a URL for, and compares them against the snapshot it kept last time. What is new gets a row.
Each new review goes into one bucket with a severity. Bugs and billing complaints come back as urgent items carrying their text and the app version, so a crash report does not sit at position 40 of a list nobody reads.
Similar reviews are grouped: five people saying login fails after 4.2 arrive as one cluster with an example and the review ids, not as five things to notice separately.
The rating is tracked across both stores against the last run's figure, so a drop is a flag rather than something you spot a week later.
Two optional outputs. webhookUrl posts a summary after the run, and a Slack incoming webhook works as-is. weeklyReport writes REPORT.html and REPORT.md into the run's key-value store.
Competitor apps feed the comparison in that report and the webhook summary. Their reviews are not written as dataset rows, and they are checked and processed the same way your own are.
📥 What you give it
{
"apps": [
{
"label": "My App",
"appStoreUrl": "https://apps.apple.com/us/app/instagram/id389801252",
"playStoreUrl": "https://play.google.com/store/apps/details?id=com.instagram.android"
}
],
"maxReviewsPerRun": 100,
"onlyNewSinceLastRun": true,
"country": "us"
}
apps takes objects, not plain URLs. An entry that is not an object is skipped, which is the quickest way to end up with a run that checks nothing.
| Field | Default | What it is |
|---|---|---|
apps | none | One entry per app: an optional label, plus appStoreUrl, playStoreUrl, or both. One store is fine. |
competitorApps | empty | Same shape. Adds a comparison of their new-review themes. |
country | us | Two-letter store country, both stores. Pick one and stay on it: the snapshot is not kept per country. |
maxReviewsPerRun | 100 | Reviews fetched per app per store, 10 to 500, most recent first. |
onlyNewSinceLastRun | true | What makes this a monitor rather than a dumper. Turn it off and every run returns everything it fetched. |
detectBugsCrashes, detectBillingComplaints, detectFeatureRequests | true | Which buckets get flagged as urgent or counted separately. |
detectRatingDrops | true | Flag a fall in the blended cross-store rating against the last snapshot. |
clusterThemes | true | Group new reviews that say the same thing. |
weeklyReport | true | Write the forwardable HTML and Markdown report. |
webhookUrl | empty | Where to POST the run summary. A Slack webhook URL works directly. |
anthropicApiKey | none | Your own key, in a secret field, billed to your own Anthropic account. Only the ambiguous reviews use it. |
useLLMTriage | true | Does nothing without a key. Set it off to stay on rules even when a key is present. |
📤 What you get back
Two kinds of row. First the per-app digest, real, from a real run:
{
"type": "app_digest",
"run_at": "2026-09-14T05:42:04.860601+00:00",
"label": "My App",
"app_id": "app_c9aa11a4733bf08e",
"sync_status": "ok",
"stores": ["app_store", "google_play"],
"fresh_count": 10,
"new_count": 10,
"changed_count": 0,
"bucket_counts": {"bug_or_crash": 0, "billing_complaint": 0, "feature_request": 0, "praise": 5, "other": 5},
"urgent_count": 0,
"urgent_items": [],
"clusters": [],
"rating_before": 4.096,
"rating_after": 4.097,
"rating_change": 0.001,
"rating_drop_alert": false,
"store_ratings": {"app_store": 4.69062, "google_play": 3.9933133}
}
Then one row per new review. This real row also shows the language limit: a one-star review in Hindi, which the rules could not place, so it landed in other at 0.2 confidence.
{
"type": "new_review",
"review_id": "gp_f8c2b0af-356e-4d7b-a14b-763ca2d2ebee",
"store": "google_play",
"app_id": "com.instagram.android",
"app_label": "My App",
"rating": 1,
"title": "",
"text": "mere original account ko bhi suspend Kar Diya",
"author": "Hashim khan Hashim khan",
"version": null,
"date": "2026-09-13T05:40:16",
"developer_response": false,
"developer_response_text": null,
"country": "us",
"url": "https://play.google.com/store/apps/details?id=com.instagram.android",
"is_competitor": false,
"content_hash": "1b3b199fb19e4faee3f1a7dee827b51933be9417",
"triage": {"bucket": "other", "severity": "low", "version": null, "keywords": [], "method": "rules", "confidence": 0.2}
}
| Field | What it is |
|---|---|
triage.bucket | One bucket per review: bug_or_crash, billing_complaint, feature_request, praise or other. |
triage.severity, triage.confidence | high, medium or low, and how sure the classifier was. Sort by confidence to find what needs a human. |
triage.method | rules or llm, so you can always see which decided. |
triage.keywords | The words that drove the call. Empty when nothing matched. |
review_id, content_hash | The id is prefixed as_ or gp_ by store. The hash is what spots an edited review. |
version | The app version the reviewer was on, when the store reports one. Null often. |
developer_response | Google Play only. The App Store feed does not carry replies. |
urgent_items | On the digest row: the flagged reviews in full, with text, version, severity and link. |
clusters | On the digest row: theme, how many mentions, the dominant bucket and version, an example and the review ids. |
rating_before, rating_after, rating_drop_alert | Blended across the stores you gave it. store_ratings keeps them separate. |
🧾 Reading the output
type separates the two kinds of row, and both share one table view, so the columns look sparse either way. Export it, or open a row.
| Row | How to spot it | Charged |
|---|---|---|
| A per-app digest | type is app_digest | The app check is charged |
| A new review | type is new_review | yes |
| A failed app | type is app_digest with sync_status: failed and an error | The app check is charged |
One thing to watch: sync_status: ok with new_count: 0 means nothing new was found, and a store quietly refusing looks the same. A steady zero from one store on a busy app is worth checking by hand.
The report files land in the run's key-value store as REPORT.html and REPORT.md, on the Storage tab.
▶️ How to run it
1. Open App Review Triage and click Try for free. 2. In Apps to monitor, replace the example with your own: a label and one or both store URLs. 3. Set Store country if you are not on us. 4. Paste a Slack incoming-webhook URL into Webhook / Slack URL if you want the summary pushed. 5. Click Start. Then schedule it, daily or weekly, and let the snapshot do its job.
💰 How much does it cost?
| What | Free plan | Paid plans |
|---|---|---|
| A new review, sorted and written as a row | $0.0004, so $0.40 per 1,000 | same |
| Each app on your list, each run | $0.004 | $0.002 |
| The triage pass on an app that had something new | $0.0005 | $0.0003 |
| A report written | $0.005 | $0.003 |
An app is checked whether or not it has anything new, so a quiet app on a daily schedule still costs its check. A review you already saw is not charged again, and an edited one is re-sorted without being charged as new.
💡 What people use it for
- A morning Slack post of everything new, bugs and billing complaints at the top.
- Catching the crash nobody filed a ticket for, visible only in reviews of one version.
- Counting the feature people keep asking for, rather than remembering it.
- Rating-drop alerts on release days, when a bad build hits the score first.
- Watching a rival's themes without reading their reviews yourself.
🚧 What it does not do
- The rules are English. Other languages usually land in
otherat low confidence. Your own
Anthropic key is the fix.
- One bucket per review. A crash report that also asks for a feature gets the stronger of the
two, not both.
- About 500 App Store reviews per app, and no developer replies from that store.
- It does not reply to reviews or touch your listings.
- It cannot tell "nothing new" from "could not look".
- One country per run, and the memory is not kept per country, so switching mid-stream compares
against the old country's snapshot.
- The blended rating needs both stores answering. If one store's metadata fails, the blend
becomes the other store's number, which can look like a drop that never happened.
- Competitor reviews are not written as rows.
🧭 Which review monitor do you need?
| If you want | Use |
|---|---|
| New app reviews triaged and alerted on | This one |
| App Store metadata, or an app's reviews in bulk | App Store Scraper |
| Reviews for a physical location | Google Maps Reviews Scraper |
| Business reviews from Trustpilot | Trustpilot Scraper |
❓ Questions people ask
Do I need an Anthropic key? No. The built-in classifier runs on rules and needs nothing. A key only sharpens the ambiguous cases, and it bills to your own Anthropic account.
How does it know what is new? It keeps a snapshot of the review ids and their content hashes between runs, in its own key-value store. Nothing to configure.
Can I monitor one store only? Yes. Give an app just the App Store URL or just the Play URL.
Will it post to Slack? Paste an incoming-webhook URL into webhookUrl. It posts after every run, including quiet ones.
What happens on the first run? Everything it fetches is new, so expect a big first batch. Set maxReviewsPerRun low for that run if you would rather ease in.
Is scraping reviews legal? These are public store pages. Reviews carry author names, which are personal data under GDPR and similar laws, so have a reason for holding them. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the app URLs and the run ID. The digest row's sync_status and error usually name the reason already. Never paste your Anthropic key into an issue.