App Store & Play Review Monitor avatar

App Store & Play Review Monitor

Pricing

from $2.10 / 1,000 delivered reviews

Go to Apify Store
App Store & Play Review Monitor

App Store & Play Review Monitor

Monitors new App Store reviews from Apple's public feed, and optional Play reviews with your own console credentials. Flags low ratings and the app version. The first run only saves a baseline. The public Play page stays off unless you confirm it. Not an archive. Not affiliated with Apple or Google.

Pricing

from $2.10 / 1,000 delivered reviews

Rating

0.0

(0)

Developer

Muhammet Mustafa Dincer

Muhammet Mustafa Dincer

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Security

Limited permissions

Share

What is App Store & Play Review Monitor?

App Store & Play Review Monitor watches app reviews and returns the ones that showed up since the last run. For Apple, it reads the public customer-reviews feed at itunes.apple.com/{country}/rss/customerreviews/.../json. For Google Play, the supported path is the official Android Publisher reviews API with your own Play Console credentials. A reader of the public Play page exists, and it stays off unless you turn it on and confirm it.

Each delivered review is one dataset row: store, country, review id, stars, title, text, the public display name, app version, date, helpful votes, link, and lowRatingAlert when the rating is at or below a threshold you set (default 2 stars).

The first run with New reviews only (the default) saves the review ids it saw and does not charge for them. The next run charges only for reviews that are actually new. There is no browser and no login for Apple. Play's official API is limited to apps that the credentials can manage.

Quick answer: when should you (or an AI agent) pick this Actor?

Pick this Actor when you want a scheduled alert for new App Store reviews, especially bad ones, without an Appbot or AppFollow subscription. A typical input is one Apple app id, one or a few storefronts, onlyNew: true, and a low-rating threshold of 2. Add Google Play only for an app you publish, with your own service account.

Pick something else when you need the full history of an app. Apple's feed is about the latest 500 reviews per country (10 pages), and pages in the middle are often empty. It is not a multi-year archive. Google's official API returns reviews from about the last week, and only for apps in that Play Console account. It is not a way to read a competitor's Play console.

Defaults that work: the prefilled input is Spotify's Apple id 324684580 in the US store, new reviews only. The first Start saves a baseline. Schedule that same input. To also fetch the reviews that are already in the feed, send {"appleAppIds": ["324684580"], "appleCountries": ["us"], "onlyNew": false, "maxReviewsPerSource": 50}.

At a glance

DoesReads Apple's public customer-reviews JSON feed. Optionally reads Google Play through your Play Console API. Flags low ratings and keeps the app version.
InputApple app ids and storefronts. Optional Play package, Play source, credentials, star range, keywords, low-rating threshold, onlyNew, stateName.
OutputrecordType: "review" and "source" rows, plus RUN_SUMMARY and LOW_RATING_ALERTS in the key-value store.
NeedsNothing for Apple. For Play's official API, your own service account or access token.
DepthApple: about the latest 500 reviews per country. Play API: about the last week, for your own apps.
PricingPay per event. Free plan: $0.0005 per run and $0.003 per delivered review. A baseline is not charged per review.
Does notArchive old reviews, reply to reviews, read emails or devices, or turn the Play page reader on by itself.

Key terms used in this README

  • Customer-reviews feed: Apple's public RSS JSON document for one app and one storefront. The Actor asks for sortBy=mostRecent. A page holds up to 50 reviews. There are 10 pages.
  • Hole: a page that comes back as a valid feed with no reviews, while a later page, or another spelling of the same URL, has reviews. An empty page is not treated as the end of the list.
  • Baseline: the review ids saved after the first successful read for a watchlist name. Those reviews are not delivered and not charged.
  • New review: a review id that was not saved, and whose date is not older than the previous run (minus two hours, so a review that was posted just before the run can still arrive).
  • Late reveal: a review that was missing from the saved list but is dated before the previous run. It is recorded so it does not alert later, and it is not charged. Apple's feed does this when a hole fills in.
  • Low-rating alert: lowRatingAlert: true on a delivered review at or below lowRatingThreshold. The same rows are also listed under the key LOW_RATING_ALERTS (up to 200). This is not a second charge.
  • Official Play API: GET https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{package}/reviews with your OAuth token. Google documents that this list is about the last week.
  • Public page: the optional scraping path. It is labeled fetchedVia: "google-play-page" on every row from it. Default is off.

What can you use it for?

A bad-review alert

Schedule the Actor every few hours with onlyNew: true and lowRatingThreshold: 2. Point an Apify webhook at the dataset or at LOW_RATING_ALERTS. You pay the start fee on quiet runs, and $0.003 per new review on the Free plan when something was actually delivered.

Release checks

appVersion is the version the reviewer had installed, when the feed or the API provides it. Filter the dataset to the version you just shipped.

Several storefronts

Pass appleCountries: ["us", "gb", "de"]. Each country is its own feed and its own baseline. The same review id in two countries is unlikely; they are stored separately.

Your own Play app

Set googlePlaySource to official-api, paste the service account JSON (invited in Play Console), and add the package name. Countries are ignored on this path: Google returns recent reviews for that app across languages. A competitor's package will not work with your key.

How does it work?

  1. Apple app ids are checked as digits, or taken from an apps.apple.com / itunes.apple.com URL. Package names are checked as com.example.app, or taken from a play.google.com URL. Anything else is skipped. The Actor never requests a host you typed yourself. Allowed hosts are itunes.apple.com, oauth2.googleapis.com, androidpublisher.googleapis.com, and play.google.com (only if the public page is confirmed).
  2. For each Apple app and country it requests pages 1 to 10, one request at a time, with a pause (requestDelayMs, default 400). Each page is tried as a few spellings of the same customer-reviews feed, including the storefront as a cc query. Apple caches those spellings separately and one of them is often empty. The spelling that contains reviews is kept for later pages. The first empty spelling on a page is retried once. Review ids are deduplicated.
  3. A 403 or 429 stops that source. The Actor does not try another address, switch proxy, or call a private App Store API. The baseline already saved is kept. If every spelling is a readable document with no reviews, the source row, the log and the run status say so. That run does not write or replace a baseline and does not charge. Set Proxy configuration to Apify Proxy and choose the residential group, then run again. Direct requests stay the default.
  4. Entries without a star rating are skipped (older feeds put the app itself in the first entry). The author profile URL is dropped. Only the display name is kept.
  5. With New reviews only, the ids are compared with the gzipped snapshot in the key-value store app-store-play-review-monitor-state, under the watchlist stateName. The first run that actually reads reviews writes the snapshot and a source row (baseline_saved) and no review rows. An empty feed does not write that snapshot. Later runs write the new reviews and then update the snapshot. A later empty feed leaves the saved ids in place.
  6. If the run hits its maximum charge, reviews that did not fit are left out of the snapshot, and the saved timestamp does not move, so the next run can deliver them.
  7. Changing the star range, the keywords, or the review cap starts a new baseline instead of reporting the whole feed as new. Changing only the low-rating threshold does not.
  8. Google Play's official client exchanges the service account for a token (JWT, scope androidpublisher) or uses the access token you passed. It pages with maxResults=100. Device, OS and screen fields are not copied. A tab in the comment text is treated as the split between title and body, which is how that API joins them.
  9. The public page, when confirmed, posts to Play's public reviews endpoint and stops if the body is not the expected shape or the server refuses it.

How to monitor an app (step by step)

  1. Open the Actor. Keep the prefilled Apple id, or paste your own.
  2. Add storefronts if you need more than the US.
  3. Leave New reviews only on. Leave Google Play source on Off unless you have Play Console credentials.
  4. Click Start. The dataset has a source row and no review rows. That run did not charge per review.
  5. Run it again later, or add a schedule with the same stateName. New reviews appear from the second run. Low ratings are marked in the Low-rating alerts view.

To receive the reviews that are already public, turn New reviews only off for one run. That run charges for every review it delivers, and it does not update the baseline.

Input

FieldTypeDefaultMeaning
appleAppIdslistprefilled 324684580Up to 10 Apple ids or App Store URLs. At most 20 id-and-country pairs.
appleCountrieslistusUp to 5 storefronts. uk is read as gb.
onlyNewbooleantrueBaseline on the first run; only unseen reviews later.
minRating, maxRatinginteger1 and 5Inclusive star range. Reviews outside it are not charged.
keywordslistemptyKeep a review if the title or text contains at least one. At most 30.
lowRatingThresholdinteger2Flag delivered reviews at or below this.
googlePlayPackageNameslistemptyUp to 10 package names or Play URLs. Ignored while Play is off.
googlePlaySourceoff | official-api | public-pageoffpublic-page is the scraping path.
googlePlayServiceAccountJsonsecretemptyJSON key invited in Play Console. Not written to the dataset.
googlePlayAccessTokensecretemptyOAuth token for androidpublisher, used only if the JSON key is empty. An AIza API key is rejected.
confirmGooglePlayPageScrapebooleanfalseMust be true for public-page.
googlePlayCountrieslistusUsed only by the public page.
stateNamestringdefaultLetters, digits, - and _. Same name, same memory.
maxReviewsPerSourceinteger500Cap per app and country. 500 is Apple's ceiling.
requestDelayMsinteger400Pause between requests. Minimum 200.
proxyConfigurationobjectApify Proxy offOptional. Turn on Apify Proxy and select residential when the Apple feed is empty. Proxy traffic is billed separately.

Output

One dataset, two kinds of rows. Filter on recordType. Views: Reviews, Low-rating alerts, Sources.

An illustrative row (not a live run) is in assets/sample-run-data.json.

Review rows

FieldMeaning
recordTypereview
storeapp-store or google-play
countryStorefront, or null for the Play Console API
appIdApple id or Play package name
reviewIdStore review id
rating1 to 5
title, textTitle may be null on Play
authorPublic display name. No profile URL
appVersionVersion string, or null
reviewedAtISO 8601 time
votesHelpful votes
urlLink from the feed, or the app's reviews page
lowRatingAlertTrue or false
fetchedViaapple-rss, google-play-api, or google-play-page
languagePlay reviewer language, or null

Source rows

status is baseline_saved, no_new_reviews, reviews_found, empty, no_matches, charge_limit, blocked, fetch_failed, auth_failed, or invalid_response. Counts say how many reviews were read, new, delivered, filtered, already seen, revealed late, or held back by the spending limit. message explains the status.

Key-value store

KeyWhereMeaning
RUN_SUMMARYdefault storeSources, delivered reviews, alert count, warnings
LOW_RATING_ALERTSdefault storeUp to 200 alert rows and the full count
STATEdefault storeInternal resume marker
seen--{stateName}--{source}named store app-store-play-review-monitor-stateGzipped review ids. Not for reading by hand.

Up to 20,000 ids are kept per source. Older ids drop off the tail. A dropped id whose review date is before the last run is still not alerted, because of the date check.

Pricing

Pay per event. Prices below are US dollars. Apify's margin is 20%.

EventFreeBronzeSilverGold and aboveWhen
Actor start$0.0005$0.0005$0.0005$0.0005Once per run (one event per GB of memory, minimum one)
Delivered review$0.003$0.0027$0.0024$0.0021One per review row written

The charge in the code is Actor.charge({ eventName: 'review-delivered', count }) after the rows are stored. pushData is called without an event name, so a review is not billed twice.

Not charged: the baseline, reviews already saved, reviews removed by the star or keyword filter, late reveals, source rows, the low-rating copy in the key-value store, empty feeds, and sources that fail or refuse the request. Apify Proxy, when you turn it on, is billed by Apify as platform usage, separate from these events.

A charge result of zero events is a spending limit only when eventChargeLimitReached is true. A run that is not on pay-per-event still stores the reviews it read.

A quiet daily run is the start fee. Ten new reviews on the Free plan are $0.03 plus the start fee. A one-off run with onlyNew: false and 500 reviews is 500 times the review price.

The band is $0.002 to $0.005 per new review: above the $0.0001 Apple-only scrapers, and aimed at a monitor that replaces a $49/month review dashboard when you only need new reviews. It is the wrong tool if you need to export the whole history in one cheap pass.

Comparison

This Actorthewolves App Store reviewsneatrat Google Play reviewsAppbot
ApplePublic customer-reviews feedApple reviewsNoYes
Google PlayYour API, or a confirmed public pageNoPublic Play reviewsYes
New since last runYes, saved in a key-value storeNot the productNot the productYes, inside the dashboard
App versionYesVariesVariesYes
Low-rating flagYesNoNoYes
Price signal$0.003 per delivered review on Freeabout $0.0001 per reviewabout $0.00015 per reviewabout $49–59/month

Those competitor prices are public list prices from the research snapshot of 5 November 2026, not a measurement of this run.

Apple. The customer-reviews feed is public and needs no key. itunes.apple.com/robots.txt contains Disallow: /*/rss/*, and this feed is under /{country}/rss/. Apple's Media Services Terms (the text last updated 14 September 2026) say the services are for personal, noncommercial use, and they prohibit using an automated process to scrape, copy, or monitor the content. This Actor reads that feed anyway. It does not have Apple's permission. It does not rotate addresses or switch to a private API when Apple refuses. A proxy is used only if you set one; the Actor does not turn a proxy on after an empty page or a refusal. Whether you may use it is your decision. This README is not legal advice. The Actor is not affiliated with Apple.

Google Play, official API. This is the path to use. You supply credentials for a Play Console account, and Google returns reviews for apps that account manages. Follow Google's API terms and quota (the reviews list is a small number of reads per hour per app). The Actor is not affiliated with Google.

Google Play, public page. Off by default. You must set googlePlaySource to public-page and confirmGooglePlayPageScrape to true. The input label calls it scraping. It may conflict with Google Play's terms, it is unsupported, and it can break without notice. Every row is marked fetchedVia: "google-play-page". A browser user agent is sent on that path only, because the page expects one. A refusal stops the source.

Personal data. The display name is the name the store already shows next to the review. Profile URLs, account ids, and Play device details are not stored. If you keep the dataset, you are responsible for that copy.

No archive. Do not schedule this once a month on a busy app and expect every review. Apple only exposes about 500 recent reviews per country, and a gap larger than that between runs drops reviews that fell out of the window. Play's official API is about a week.

FAQ

Why did the first run return no reviews? If the source row says baseline_saved, new reviews only is on and the ids were saved. Run the same input again later. If the source row says empty and the message starts with "Warning", Apple returned a document with no reviews. That is not a baseline. Turn on a residential proxy and run again.

Why is the Apple feed empty for a famous app? Page 1 is often a hole, so the Actor still requests the other pages and the other spellings, and it retries the first empty spelling once. If every one of them is an empty document, the run warns you. Datacenter addresses often get that empty document while the same URL still has reviews elsewhere. Set Proxy configuration to Apify Proxy, select the residential group, and run again. An existing baseline is kept. The Actor does not invent reviews and does not switch to a private App Store API.

Can I watch a competitor on Google Play? Not with the official API. That API only returns apps your Play Console credentials manage. The public page can be pointed at any package, and it is the path that stays off until you confirm it.

Does a 1-star review cost more? No. The flag is free. You pay once if the review was delivered.

What happens if I change keywords? The next run saves a new baseline and does not dump the old reviews as new. Use onlyNew: false for one run if you want the current feed under the new filter.

Local run

From actors/app-store-play-review-monitor after npm install:

$mkdir -p storage/key_value_stores/default

Write storage/key_value_stores/default/INPUT.json, then npm start. npm test runs the unit tests and does not call Apple or Google.