datagrit

datagrit › Data › App Release Review Impact: Rating by Version

Data

App Release Review Impact: Rating by Version

Groups App Store and Google Play reviews by app version and shows how each release changed the rating, with significance flags and the complaints that are new in that version.

Run it on Apify StoreUse the APIfrom $2.80 per 1,000 results + $10 per run · no code needed
from $2.80 per 1,000 results + $10 per runpay only for version rows you get
JSON · CSV · Excelexport or call via API
Scheduled runsdaily or weekly feeds with Apify schedules
v0.19updated 2026-10-02

App Release Review Impact reads the newest public reviews of Apple App Store and Google Play apps and groups them by app version. For every version you get the review count, the average rating, the star distribution, how the rating changed against the previous version, whether that change is statistically significant, and the complaint terms that are new in that release. It is built for product managers, QA and support leads, app store optimization teams and analysts who want to know which release made users unhappy without reading thousands of reviews.

Review scrapers return one row per review with a raw version string. This Actor returns one row per version, so a regression shows up as a single line with a trend of regressed instead of a spreadsheet pivot you have to build yourself.

Use cases

How to use it

  1. Add apps: App Store IDs (digits such as 1064216828), apps.apple.com links, Google Play package names (such as com.spotify.music) or play.google.com links. You can mix both stores in one run.
  2. Choose the App Store countries to read. Reviews of all chosen countries are merged into one row per version.
  3. Set how many newest reviews to read per app and the minimum number of reviews a version needs to get a row.
  4. Optionally keep only the latest versions or only the versions that got worse, then run the Actor.

How the analysis works

Pricing

You pay per version row returned. Apps that are not found, apps without enough reviews and duplicates produce a free status row with found: false and a note, so you are never charged for an empty result. The price per row is set on the Actor page and shown before you run it; set a maximum charge per run in the Apify console to cap spending, and the Actor stops cleanly when the limit is reached. Reading the reviews costs nothing extra.

Good to know

Output fields

Every result is one flat record, so it drops straight into a spreadsheet, a database or a CRM.

FieldTypeDescriptionExample
storestringStore the app and its reviews come from: app-store or google-play.app-store
appIdstringApp Store numeric ID or Google Play package name as given in the input.1064216828
appNamestringName of the app on the store page. Empty only on the status row of an app that was not found, or whose store lookup did not answer.Reddit
versionstringApp version string exactly as reported with the reviews.2026.38.0
versionRankintegerPosition among the versions kept for this app, 1 = newest version.2
reviewCountintegerNumber of reviews written on this version within the reviews that were read.108
avgRatingnumberMean star rating of the reviews on this version, rounded to two decimals.1.93
stars1CountintegerNumber of 1-star reviews on this version.70
stars2CountintegerNumber of 2-star reviews on this version.9
stars3CountintegerNumber of 3-star reviews on this version.6
stars4CountintegerNumber of 4-star reviews on this version.4
stars5CountintegerNumber of 5-star reviews on this version.19
lowStarCountintegerNumber of reviews with one or two stars on this version.79
lowStarSharenumberShare of reviews on this version that have one or two stars, from 0 to 1.0.731
firstReviewAtstringISO 8601 time of the oldest review on this version within the reviews that were read.2026-09-22T14:03:11.000Z
lastReviewAtstringISO 8601 time of the newest review on this version within the reviews that were read.2026-09-26T21:40:02.000Z
previousVersionstringNearest older version of the same app that passes the minimum reviews limit. Empty for the oldest version.2026.37.0
previousAvgRatingnumberMean star rating of the previous version.1.9
ratingDeltanumberAverage rating of this version minus that of the previous version, in stars. Empty for the oldest version.0.03
ratingDeltaMarginnumberHalf-width of the 95 % confidence interval of the rating change, in stars (plus or minus). A change smaller than this margin cannot be told from chance. Empty for the oldest version.0.27
previousLowStarSharenumberShare of 1-2 star reviews on the previous version, from 0 to 1.0.712
lowStarShareDeltanumberShare of 1-2 star reviews on this version minus that of the previous version.0.019
deltaSignificantbooleanTrue when the rating change is statistically significant at 95 % confidence (Welch t test on the star ratings), false when it is not. Empty for the oldest version.false
trendstringregressed or improved when the rating changed by at least 0.15 stars and the change is significant. stable when the change is under 0.15 stars and the 95 % margin is at most 0.3 stars. inconclusive when the sample is too small to tell (a visible change that is not significant, or a margin wider than 0.3 stars): read ratingDelta together with ratingDeltaMargin. baseline for the oldest version that has no predecessor.inconclusive
newComplaintTermsarrayWords and two-word phrases that are significantly more frequent in the 1-2 star reviews of this version than in the 1-2 star reviews of all older versions (one-sided two-proportion test, z of at least 3, at least 3 % of the version's low-star reviews, at least twice the older frequency, at least 4 reviews). Empty array: the comparison was made and no term stands out. Null: no comparison is possible (oldest version, or fewer than 12 low-star reviews in the version or in the older versions together), which is the usual case with 500 reviews per app; it fills mainly on Google Play reads of 5000 reviews. See newComplaintTermStats for the numbers and lowStarTopTerms for the most frequent low-star terms of every version.["login","crash on startup"]
newComplaintTermStatsarrayFor each term in newComplaintTerms: lowStarReviews (1-2 star reviews of this version containing it), versionShare (their share of the version's 1-2 star reviews), olderShare (the same share in the older versions) and lift (versionShare divided by olderShare, the older share never taken below 1 % or below one review of the older pool). Null when newComplaintTerms is null.[{"term":"login","lowStarReviews":104,"versio
lowStarTopTermsarrayThe five most frequent words and phrases in the 1-2 star reviews of this version, new or not, with the same numbers as newComplaintTermStats (olderShare and lift are null for the oldest version and whenever all older versions together hold fewer than 12 low-star reviews; lift is the version share divided by the older share, which is never taken below 1 % or below one review of the older pool). Where a lift exists, a value near 1 means the term is about as frequent as before and a high value that it is more frequent in this release. Null when the version has fewer than 8 low-star reviews; an empty array when it has 8 or more but no word or phrase occurs in at least 4 of them.[{"term":"account","lowStarReviews":103,"vers
lowStarTopTermsTextstringThe same five terms as lowStarTopTerms as one readable string, with the lift against older versions in brackets where one exists (for example "log (lift 11.1), working (lift 4.2), login"). Null when lowStarTopTerms is null or empty. This is the column of the Version impact view.account (lift 3.8), login, update
sampleLowStarReviewsarrayUp to three 1-2 star review texts from this version, preferring those that contain the new complaint terms, then the most helpful, cut at 280 characters. No author names.["App crashes on startup since the last update."]
countriesarrayStorefront countries whose reviews were merged into this row (App Store), or the Google Play country that was read. On a status row of an app that could not be read: the storefronts that were looked up.["us"]
sourceUrlstringStore page of the app. Also on the status row of an app that could not be read, whenever the store lookup answered.https://apps.apple.com/us/app/id1064216828
scrapedAtstringISO 8601 timestamp of the run.2026-10-01T08:00:00.000Z
foundbooleanFalse only on status rows, which explain why an app produced no version rows. Status rows are not billed.true
notestringReason for a status row. On a version row it is empty, or it warns that part of the requested reviews was not served by the store or that only some of the reviews carry an app version (counted per storefront; a storefront below the threshold, 20 % for Google Play and 90 % for the App Store, is named as left out of the statistics).No app version has at least 10 reviews (read 120 reviews across 14 versions). Lo

Sample record

{
  "store": "app-store",
  "appId": "1064216828",
  "appName": "Reddit",
  "version": "2026.38.0",
  "versionRank": 2,
  "reviewCount": 108,
  "avgRating": 1.93,
  "stars1Count": 70,
  "stars2Count": 9,
  "stars3Count": 6,
  "stars4Count": 4,
  "stars5Count": 19,
  "lowStarCount": 79,
  "lowStarShare": 0.731,
  "firstReviewAt": "2026-09-22T14:03:11.000Z",
  "lastReviewAt": "2026-09-26T21:40:02.000Z",
  "previousVersion": "2026.37.0",
  "previousAvgRating": 1.9,
  "ratingDelta": 0.03,
  "ratingDeltaMargin": 0.27,
  "previousLowStarShare": 0.712,
  "lowStarShareDelta": 0.019,
  "deltaSignificant": false,
  "trend": "inconclusive",
  "newComplaintTerms": [
    "login",
    "crash on startup"
  ],
  "newComplaintTermStats": [
    {
      "term": "login",
      "lowStarReviews": 104,
      "versionShare": 0.15,
      "olderShare": 0.022,
      "lift": 6.5
    }
  ],
  "lowStarTopTerms": [
    {
      "term": "account",
      "lowStarReviews": 103,
      "versionShare": 0.149,
      "olderShare": 0.039,
      "lift": 3.8
    }
  ],
  "lowStarTopTermsText": "account (lift 3.8), login, update",
  "sampleLowStarReviews": [
    "App crashes on startup since the last update."
  ],
  "countries": [
    "us"
  ],
  "sourceUrl": "https://apps.apple.com/us/app/id1064216828",
  "scrapedAt": "2026-10-01T08:00:00.000Z",
  "found": true,
  "note": "No app version has at least 10 reviews (read 120 reviews across 14 versions). Lower minReviewsPerVersion or raise maxReviewsPerApp."
}

Input

FieldNameTypeWhat it does
apps requiredAppsarrayApp Store IDs (digits, e.g. 1064216828), apps.apple.com URLs, Google Play package names (e.g. com.reddit.frontpage) or play.google.com URLs. Mix both stores freely; every app is analyzed separately within its own store.
countriesApp Store countriesarrayTwo-letter App Store storefronts to read for App Store apps (us, gb, de, ...; uk is read as gb). A code the App Store does not know is reported and skipped. Reviews of all selected countries are merged into one row per version. The App Store feed exposes at most the 500 newest reviews per country and often only the first 50. Google Play apps ignore this field.
googlePlayCountryGoogle Play countrystringTwo-letter Google Play country used when reading Google Play apps.
googlePlayLanguageGoogle Play languagestringLanguage code of the Google Play page (en, de, pt-br, ...). It sets the language of the interface, not a filter on review language.
maxReviewsPerAppReviews to read per appintegerNewest reviews to read per app. For App Store apps this limit applies per country; the feed pages 50 reviews at a time up to 500 and often stops after the first page. Google Play allows up to 5000, and more reviews reach further back in version history there; the strict newComplaintTerms list fills mainly at 2000 to 5000.
minReviewsPerVersionMinimum reviews per versionintegerVersions with fewer reviews are left out, because averages over a handful of reviews are noise. Rating changes are always compared with the nearest older version that passes this limit.
latestVersionsOnly the latest N versionsintegerKeep only the N newest versions of each app that pass the minimum reviews limit. Zero keeps all of them.
onlyRegressionsOnly versions that got worsebooleanReturn only versions whose average rating dropped by at least 0.15 stars against the previous version and the drop is statistically significant (95 % confidence).
maxItemsMaximum version rowsintegerStop after this many version rows in total across all apps.
proxyConfigurationProxy configurationobjectApify Proxy is on by default. The App Store review feed sometimes answers with an empty page; the Actor retries an empty first page up to six times, gives every app a budget of at most 75 seconds for everything that goes wrong (pauses after empty pages, waits before retrying HTTP 429 or server errors and the time spent in attempts that failed; each attempt is also cut off after 25 seconds), limited to an equal share of the 150 seconds of the whole run and never below 9 seconds so that apps that were not touched yet can still be read, and gives an app it cannot read within its budget a free status row. If the proxy cannot be created the run continues without it.

Call it from your code

Run the Actor and get the results in one request. Replace YOUR_APIFY_TOKEN with the token from your Apify account settings.

curl -X POST "https://api.apify.com/v2/acts/datagrit~app-release-review-impact/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"apps":["com.spotify.music","com.reddit.frontpage","com.whatsapp","com.instagram.android","com.netflix.mediaclient","com.duolingo"],"countries":["us"],"maxReviewsPerApp":500,"minReviewsPerVersion":10,"maxItems":200}'
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('datagrit/app-release-review-impact').call({
  "apps": [
    "com.spotify.music",
    "com.reddit.frontpage",
    "com.whatsapp",
    "com.instagram.android",
    "com.netflix.mediaclient",
    "com.duolingo"
  ],
  "countries": [
    "us"
  ],
  "maxReviewsPerApp": 500,
  "minReviewsPerVersion": 10,
  "maxItems": 200
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);

Install with npm i apify-client.

from apify_client import ApifyClient
import os

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("datagrit/app-release-review-impact").call(run_input={
  "apps": [
    "com.spotify.music",
    "com.reddit.frontpage",
    "com.whatsapp",
    "com.instagram.android",
    "com.netflix.mediaclient",
    "com.duolingo"
  ],
  "countries": [
    "us"
  ],
  "maxReviewsPerApp": 500,
  "minReviewsPerVersion": 10,
  "maxItems": 200
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items), items[0] if items else None)

Install with pip install apify-client.

Frequently asked questions

Is it legal to scrape app store reviews?

The Actor reads public review data from the same public endpoints the stores use for their own pages and the App Store review feed. It collects no data behind a login and does not store reviewer names.

How many reviews can I get?

Up to 5000 per Google Play app. The App Store feed allows up to 500 per country, but it often serves only the first 50, so add countries or run again for more.

How often should I run it?

Weekly or after each release. A scheduled run shows the newest version as soon as it has enough reviews.

Why is a version missing?

It has fewer reviews than the minimum, or it is older than the reviews that the store made available in this run.

Why is a visible drop not marked regressed?

Then the trend is `inconclusive`: with this few reviews the drop cannot be told from chance (see `ratingDeltaMargin`). `stable` is used only when the change is under 0.15 stars and the sample is large enough to rule out a bigger one.

Something looks wrong in the data.

Open an issue on the Actor page with the input you used and the run link.

Try App Release Review Impact: Rating by Version on Apify

Related Actors

Company data

French Company Finder - Sirene Financials

French company lead lists from Sirene screened by net result and revenue, with net margin, size, matching establishment and optional directors.

from $5.60 / 1,000 results
Company data

Poland KRS New Company Registrations Feed

Newly registered Polish companies, foundations and associations from the official KRS court register: NIP, address, PKD, capital, email, with filters and change detection.

from $10.50 / 1,000 results