Google Play Scraper - App Details & Rating Tracker avatar

Google Play Scraper - App Details & Rating Tracker

Pricing

from $1.46 / 1,000 app details returneds

Go to Apify Store
Google Play Scraper - App Details & Rating Tracker

Google Play Scraper - App Details & Rating Tracker

For ASO teams, app marketers and competitor trackers: rating, rating count, star histogram, installs, price, ads, in-app purchases, last update and version for many Google Play apps. Matched the live store page on 5 of 5 apps checked 2026-09-21. Monitoring mode returns only apps that changed.

Pricing

from $1.46 / 1,000 app details returneds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

For ASO teams, app marketers and competitor trackers: the rating, rating count, star histogram, installs, price, ads, in-app purchases, last update date, version and content rating of every Google Play app in your list, one row per app. On 2026-09-21 the rating, rating count, downloads and update date matched what the live store page shows in a browser for 5 of 5 apps checked (WhatsApp, Spotify, Minecraft, AntennaPod, Termux). Paste package names or store URLs, get a clean table, and turn on monitoring mode to receive only the apps whose numbers or release changed since the last run.

Export as JSON, CSV or Excel. Unofficial. Public data only.

What it does

  • Reads the public app page https://play.google.com/store/apps/details?id=<package> for each app, in the country and language you choose.
  • Many apps per run (up to 1,000), from package names (com.spotify.music) or URLs, mixed.
  • Does not fail on bad entries. An app that does not exist, a country Google Play rejects, a bot check or a typo comes back as a free row that says why. The run carries on with the rest of the list.
  • Monitoring mode remembers each app and returns only the apps whose shown rating, rating count, installs, last update, version or price changed, with the previous value and the difference.

It only reads app detail pages. It does not use Google Play search, reviews or the data-safety pages (robots.txt of play.google.com disallows those for crawlers).

Input

FieldWhat it does
appsPackage names or Google Play app URLs. Case-sensitive: com.whatsapp works, COM.WHATSAPP does not. A URL's own gl and hl win over country and language for that app. Leave it out (with monitoring off) to read two example apps.
countryTwo-letter store country (us, gb, de, jp, in ...). The average rating, the split of the star histogram, price, currency and whether the app can be installed differ by country (Minecraft: 4.3 in the US, 4.0 in Japan). The rating count and installs are not per country: the same run read 5,838,279 ratings for Minecraft in both the US and Japan, and 20 apps read in the US and the UK had the same installs. Google Play answers HTTP 400 for some unknown codes (XX) but silently shows the US store for others (ZZ); check currency if you are unsure.
languagePage language (en, en-GB, de, ja ...). Changes the texts and the shown labels (ratingShown, installsShown, priceText, updatedText), not the numbers. Google Play falls back to English for a language it does not know; pageLanguage says what you got.
maxAppsWith monitoring off, stop after this many charged rows (a free row says how many entries were not read).
monitoringModeReturn an app only when it changed since the row last returned for it. The first run returns every app once.
changeOnWhat counts as a change in monitoring mode: any, rating, installs, release or price.
resetMonitoringStateForget everything remembered and start over (turn it off again after one run).
useProxyRetry a page through a datacenter proxy only when Google Play answers with a bot check or a rate limit.

Example:

{
"apps": ["com.spotify.music", "com.duolingo", "https://play.google.com/store/apps/details?id=com.mojang.minecraftpe&gl=JP&hl=ja"],
"country": "us",
"language": "en",
"monitoringMode": true,
"changeOn": "any"
}

Output

One row per app. Example (WhatsApp, US, read on 2026-09-21, monitoring columns shortened):

{
"status": "ok",
"appId": "com.whatsapp",
"appUrl": "https://play.google.com/store/apps/details?id=com.whatsapp",
"country": "us",
"language": "en",
"pageLanguage": "en",
"title": "WhatsApp Messenger",
"developer": "WhatsApp LLC",
"developerId": "WhatsApp LLC",
"category": "Communication",
"categoryId": "COMMUNICATION",
"rating": 4.616693,
"ratingShown": "4.6",
"ratingCount": 244067678,
"ratingHistogram": { "oneStar": 10883019, "twoStars": 3458555, "threeStars": 8912990, "fourStars": 21819053, "fiveStars": 198994008 },
"installsText": "10,000,000,000+",
"installsShown": "10B+",
"minInstalls": 10000000000,
"realInstalls": 12322703000,
"price": 0,
"currency": "USD",
"priceText": null,
"isFree": true,
"containsAds": false,
"inAppPurchases": true,
"inAppPurchaseRange": "$0.40 - $199.99 per item",
"installableInCountry": true,
"updatedAt": "2026-09-19T00:49:04.000Z",
"updatedText": "Sep 19, 2026",
"releasedAt": "2010-10-18T20:58:53.000Z",
"version": null,
"versionVariesWithDevice": true,
"minAndroidVersion": null,
"contentRating": "Everyone",
"summary": "Simple. Reliable. Private.",
"descriptionStart": "WhatsApp from Meta is a FREE messaging ...",
"descriptionLength": 2200,
"iconUrl": "https://play-lh.googleusercontent.com/...",
"change": "details-changed",
"changedFields": ["ratingCount"],
"previousRatingCount": 244040000,
"ratingCountDelta": 27678,
"previousRealInstalls": 12322703000,
"realInstallsDelta": 0,
"hoursSincePreviousDetails": 24
}

How exact are the numbers?

  • ratingCount is the full number from the page data. The store page shows it rounded ("244M reviews"); on 2026-09-21 the rounded label matched ratingCount for all 5 apps compared in a browser. The page calls it "reviews", but it is the number of star ratings; ratingHistogram gives a count per star. Its sum is close to, not always equal to, ratingCount (5,838,190 against 5,838,207 for Minecraft in the US), but the split between stars depends on the country (one-star: 617,987 in the US, 891,306 in Japan for Minecraft), so read it as the star distribution Google shows in that store, not as that country's own ratings.
  • rating is the decimal average from the page data (4.616693); ratingShown is what the page shows (4.6).
  • Installs: the page only shows a tier (installsShown "10B+", installsText "10,000,000,000+", minInstalls 10000000000). realInstalls is a finer number that Google Play puts in the page data but does not show. Google does not document it. Of 12 apps read on 2026-09-21, 10 had a number down to the unit, WhatsApp's ended in 000 and Minecraft's in 00. Treat it as Google's own figure, not an audited count.
  • Counts differ between requests for large apps: reading the same page 4 times within a few minutes gave WhatsApp's rating count as 244,072,282 and 244,067,519 alternately, and Google Maps' rating as 3.219542 and 3.2195508. Installs, update date, version, price and the shown rating did not move. Four smaller apps (6,733 to 250,710 ratings) did not move at all.
  • updatedAt is the exact time from the page data (UTC). updatedText is Google's own date text in the page language; its day can differ from the UTC date of updatedAt (Minecraft: "Sep 16, 2026" shown, 2026-09-15T18:13:38Z).
  • version is null with versionVariesWithDevice: true when Google Play gives no single version (large apps such as WhatsApp and Spotify); minAndroidVersion is null for those too.
  • installableInCountry is false when the store shows no Install or Buy button in that country (measured: d POINT CLUB, Yahoo! JAPAN and Rakuten Pay in the US). Such apps often have no rating in that country; rating and ratingCount are then null, never 0.
  • containsAds and inAppPurchases are false when the page has no such label (checked on AntennaPod).
  • price is in currency (6.99 USD for Minecraft in the US, 1300 JPY in Japan).
  • Personal contact details that appear inside descriptionStart (emails, phone numbers) are replaced with [email removed] / [phone removed].

Rows that are not charged

Every row has status. Only ok rows are charged. The others say why in note:

statusMeaning
okThe app page was read. Charged.
no-such-appGoogle Play answered 404: no public page for this package name (never existed, removed, or spelled differently; names are case-sensitive).
country-not-acceptedGoogle Play answered 400 for that country code.
different-app-returnedThe page belonged to another package than the one asked for; not sold as this app.
blockedA bot check, rate limit or empty answer, even after retries. The app is not reported as missing.
unreadableThe page loaded but its data block was missing or had an unknown shape.
invalid-inputNot a package name or Google Play app URL, or an input setting is wrong.
duplicateSame app, country and language as an earlier entry in the list.
no-changeMonitoring mode: nothing changed since the rows last returned. Only the check fee applies.
not-checkedEntries after maxApps rows, or beyond the first 1,000.
budget-reachedThe run's maximum total charge left no room for another row; says how many entries were not read.

In monitoring mode, an app that disappears (404) keeps its remembered values and its free row carries lastSeenRatingCount, lastSeenRealInstalls, lastSeenVersion and lastSeenAt.

Monitoring mode

Schedule the Actor (for example daily) with monitoringMode: true:

  1. First run: every app comes back with change: "first-check".
  2. Later runs: an app comes back only with change: "details-changed", listing changedFields and the previous values (previousRatingShown, previousRatingCount and ratingCountDelta, previousMinInstalls, previousRealInstalls and realInstallsDelta, previousUpdatedAt, previousVersion, previousPrice, previousCurrency, previousCheckedAt, previousDetailsReadAt, hoursSincePreviousDetails).
  3. Because large apps' rating counts move back and forth by up to 0.002% between reads, a rating count counts as changed only when it moved by more than 0.01% since the row last returned. An app that is not returned keeps the values of that row, so small moves add up and are reported once they pass 0.01%.
  4. When the only change is in the rating count or the shown rating (the values that move between reads), the page is read again a few seconds later and the app is returned only if the change is still there (confirmedByRereading is true; false means the second read failed and the first read was returned). Changes in installs, update date, version or price did not move between reads and are returned without a second read (confirmedByRereading is null). A change that disappears on the second read is not reported and not charged.

Details are remembered per app, country, language and changeOn, across all your runs; a schedule with a different changeOn keeps its own memory and starts with a first check. The rating count and installs are the same in every country, so watching one app in five countries returns and charges the same change five times: watch the rating count and installs in one country. Do not put the same app in two schedules that can run at the same time: the store has no atomic update, so one run can overwrite what the other remembered.

Pricing

Pay per event:

  • $2.00 per 1,000 app rows, charged only for rows with status: "ok".
  • In monitoring mode, also $0.30 per 1,000 app checks: every app whose page was read is a check, changed or not. 100 apps checked every day is 3,000 checks a month, which is $0.90 on top of the rows for the apps that changed.
  • Free rows (missing apps, blocked pages, bad input, duplicates, notes) are never charged.

The Actor never reads more apps than your run's maximum total charge can pay for. In monitoring mode it reserves a check and a change row for each app before reading it.

Tips

  • Paste the URL from your browser: https://play.google.com/store/apps/details?id=com.duolingo&hl=de&gl=DE reads the German store in German.
  • The same app in several countries: list its URL once per country (&gl=us, &gl=jp ...) or run once per country.
  • For release tracking only, use changeOn: "release"; for price drops, changeOn: "price".