App Store and Google Play Compared: Rating, Reviews, Price avatar

App Store and Google Play Compared: Rating, Reviews, Price

Pricing

from $2.50 / 1,000 app checkeds

Go to Apify Store
App Store and Google Play Compared: Rating, Reviews, Price

App Store and Google Play Compared: Rating, Reviews, Price

App Store vs Google Play rating comparison for a list of apps: compare an app's rating on iOS and Android, rating and review counts, Google Play installs, version, last update and price, with the rating gap worked out. Any country, no login. Export ratings to Google Sheets or CSV or via API in n8n.

Pricing

from $2.50 / 1,000 app checkeds

Rating

0.0

(0)

Developer

Adriana Voss

Adriana Voss

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

Give it a list of apps and get back one row per app with both stores side by side: rating, number of ratings, version, last update and price on the Apple App Store and on Google Play, plus Google Play installs and written-review count, and the rating gap between the two already worked out. No API key, no login, no proxy, and an app that neither store has is never charged.

It answers the question a single-store scraper cannot: how is the same app doing on iOS compared with Android, right now, in this country.

Who uses it

  • App marketers and ASO teams tracking their own app and competitors on both stores in one sheet, instead of two exports that have to be joined by hand.
  • Product managers who want to see which platform is rated lower, and whether the Android and iOS releases have drifted apart.
  • Investors and analysts screening a list of apps: installs, rating volume and price in one comparable row per company.
  • Agencies building a weekly client report on app ratings across both stores.
  • AI agents and automations that need a structured answer to "how is this app rated on each store?" in one call.

What you get

GroupColumns
Comparisonname, country, onBothStores, ratingGap, priceGap
Apple App StoreappStoreStatus, appStoreId, appStoreBundleId, appStoreName, appStoreDeveloper, appStoreCategory, appStoreRating, appStoreRatingCount, appStoreVersion, appStoreUpdatedAt, appStorePrice, appStoreCurrency, appStoreUrl
Google PlayplayStatus, playId, playName, playDeveloper, playCategory, playRating, playRatingCount, playReviewCount, playInstalls, playVersion, playUpdatedAt, playPrice, playCurrency, playInAppPurchases, playUrl
Every rowsourceUrl, scrapedAt

ratingGap is the App Store rating minus the Google Play rating: 0.42 means the app is rated 0.42 stars higher on the App Store.

How to use App Store and Google Play Compared

  1. In the Apify Console. Open the actor page and click Start — the apps field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
  2. Via the API. Call it directly with a POST request — no Console needed once you have an API token:
    curl "https://api.apify.com/v2/acts/accountable_eel~app-cross-store-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"apps":["324684580 com.spotify.music","479516143 com.mojang.minecraftpe"]}'
  3. On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.

country sets the storefront read on both stores (two letters: us, gb, de, jp, ...). Ratings, prices and availability differ by country, and us is used when you leave it alone.

Input

{
"apps": [
"324684580 com.spotify.music",
"479516143 com.mojang.minecraftpe"
]
}

One app per line: its App Store id and its Google Play package, separated by a space. The App Store id is the number after "id" in the app's App Store link, and the Google Play package is the part after "id=" in its Google Play link. You can paste the two links instead. A line with only one of the two returns that store alone. Accepted formats: 324684580 com.spotify.music, https://apps.apple.com/us/app/id479516143 https://play.google.com/store/apps/details?id=com.mojang.minecraftpe, com.spotify.music.

Each line names one app on both stores, in either order. All of these are read the same way:

You writeRead as
324684580 com.spotify.musicApp Store id and Google Play package
the app's App Store link and its Google Play link on one linethe same, taken from the links
com.spotify.musicGoogle Play only; the App Store columns stay empty
324684580App Store only; the Google Play columns stay empty
ios:com.spotify.client android:com.spotify.musicApp Store bundle id instead of the numeric id

The App Store id is the number after id in the app's App Store link. The Google Play package is the part after id= in its Google Play link. The actor does not guess the matching app on the other store: you name both, so a row never pairs two different apps.

Output

One row per app.

queryfoundstatusnamecountryonBothStoresratingGappriceGapappStoreStatusappStoreIdappStoreBundleIdappStoreNameappStoreDeveloperappStoreCategoryappStoreRatingappStoreRatingCountappStoreVersionappStoreUpdatedAtappStorePriceappStoreCurrencyappStoreUrlplayStatusplayIdplayNameplayDeveloperplayCategoryplayRatingplayRatingCountplayReviewCountplayInstallsplayVersionplayUpdatedAtplayPriceplayCurrencyplayInAppPurchasesplayUrlsourceUrlscrapedAt
324684580 com.spotify.musictrueOK<on both stores?><rating gap (app store minus google play)><price gap (app store minus google play)>1970-01-01T00:00:00.000Z

A real row from 2026-10-11, trimmed to the columns that tell the story:

nameappStoreRatingplayRatingratingGapappStoreRatingCountplayRatingCountplayReviewCountappStoreVersionplayVersionappStorePriceplayPriceplayInstalls
Spotify: Music and Podcasts4.771754.3480343818664550.42425056563646364018557489.1.90001,000,000,000+

An empty cell is a real "not known", never a hidden zero. playVersion is empty here because Google Play lists this app's version as "Varies with device"; an app with one fixed Android version gets it filled. A 0 in a price column is the store's own answer: the app is free.

appStoreStatus and playStatus say what each store answered:

ValueMeaning
OKThe store returned the app
NOT_FOUNDThe store has no such app in this country
NOT_REQUESTEDThe line did not name the app on this store
BLOCKED / ERRORThe store could not be read this time; the row is not charged

An app that neither store has comes back as a row with found: false, a status and a message that says why, and is never charged.

Example runs

Three inputs that return real rows with no key or account of your own.

1. The prefilled example: one free app and one paid app, both stores.

{
"apps": ["324684580 com.spotify.music", "479516143 com.mojang.minecraftpe"]
}

Two rows. The second shows a paid app with a fixed Android version, so appStorePrice, playPrice, priceGap and playVersion are all filled.

2. The same app in another country. Ratings and prices are per storefront:

{
"apps": ["324684580 com.spotify.music"],
"country": "de"
}

3. A rating watchlist with only the columns a weekly report needs.

{
"apps": [
"324684580 com.spotify.music",
"479516143 com.mojang.minecraftpe"
],
"columns": ["name", "appStoreRating", "playRating", "ratingGap", "appStoreRatingCount", "playRatingCount"]
}

How an app gets billed

One event, app-checked, charged once per app row returned.

  • The price is per app, not per store: a row with both stores costs the same as a row with one.
  • An app that neither store has comes back found: false and is not charged.
  • A row where one store answered "no such app here" is charged: that is the answer.
  • A row where a store could not be read (BLOCKED or ERROR) is delivered with what the other store gave and is not charged.
  • Rows removed by your own keyword filters, or past "Stop after this many results", are not charged.

Pricing

Pay-per-event. A flat per-run fee covers session/proxy warmup; each independent source is billed under its own event, only when that source actually returns data — see .actor/pay_per_event.json for exact prices. A miss is never charged.

$5 per 1,000 apps on the free plan, less on paid Apify plans. There is no per-store charge on top.

Limits worth knowing before you buy

  • You name the app on both stores. There is no automatic matching of an iOS app to its Android twin, because the two stores share no common id and a wrong pairing would be worse than none.
  • Review text is not included. The row carries counts and averages, not the reviews themselves.
  • The App Store publishes a rating count, not a written-review count. playReviewCount has no App Store twin.
  • playVersion is empty for apps whose version varies with the device. playUpdatedAt is filled for those apps and tells you when the last release went out.
  • Google Play installs are a band, such as 50,000,000+, exactly as the store shows it.
  • One country per run. To compare storefronts, run it once per country.
  • No history. Each run is a snapshot; schedule it and keep the datasets to build a trend.

Frequently asked questions

How long does a run take? About a second per app. Apps are checked three at a time by default.

Do I need a proxy or an API key? No.

Can I look up an app that is only on one store? Yes. Write only that store's id on the line; the other store's columns stay empty and its status reads NOT_REQUESTED.

Why does the rating differ from what I see in the store? Ratings are per country. Set country to the storefront you are looking at.

Can I track ratings over time? Save the actor as a task, add a schedule, and compare the appStoreRating, playRating and count columns between runs in your own sheet or workflow.

Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

curl "https://api.apify.com/v2/acts/accountable_eel~app-cross-store-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-X POST \
-H "Content-Type: application/json" \
-d '{"apps":["324684580 com.spotify.music","479516143 com.mojang.minecraftpe"]}'

n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~app-cross-store-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"apps":["324684580 com.spotify.music","479516143 com.mojang.minecraftpe"]} (swap in an expression from an earlier node for a real value).

Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~app-cross-store-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"apps":["{{app}}"]}, mapping the row's app into the apps array.

MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "App Store and Google Play app data, one row per app" — the agent will find and run this actor.