# App Store & Play Review Monitor (`mmdincer/app-store-play-review-monitor`) Actor

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.

- **URL**: https://apify.com/mmdincer/app-store-play-review-monitor.md
- **Developed by:** [Muhammet Mustafa Dincer](https://apify.com/mmdincer) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 delivered reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 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

| | |
|---|---|
| **Does** | Reads Apple's public customer-reviews JSON feed. Optionally reads Google Play through your Play Console API. Flags low ratings and keeps the app version. |
| **Input** | Apple app ids and storefronts. Optional Play package, Play source, credentials, star range, keywords, low-rating threshold, `onlyNew`, `stateName`. |
| **Output** | `recordType: "review"` and `"source"` rows, plus `RUN_SUMMARY` and `LOW_RATING_ALERTS` in the key-value store. |
| **Needs** | Nothing for Apple. For Play's official API, your own service account or access token. |
| **Depth** | Apple: about the latest 500 reviews per country. Play API: about the last week, for your own apps. |
| **Pricing** | Pay per event. Free plan: $0.0005 per run and $0.003 per delivered review. A baseline is not charged per review. |
| **Does not** | Archive 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

| Field | Type | Default | Meaning |
|---|---|---|---|
| `appleAppIds` | list | prefilled `324684580` | Up to 10 Apple ids or App Store URLs. At most 20 id-and-country pairs. |
| `appleCountries` | list | `us` | Up to 5 storefronts. `uk` is read as `gb`. |
| `onlyNew` | boolean | `true` | Baseline on the first run; only unseen reviews later. |
| `minRating`, `maxRating` | integer | 1 and 5 | Inclusive star range. Reviews outside it are not charged. |
| `keywords` | list | empty | Keep a review if the title or text contains at least one. At most 30. |
| `lowRatingThreshold` | integer | 2 | Flag delivered reviews at or below this. |
| `googlePlayPackageNames` | list | empty | Up to 10 package names or Play URLs. Ignored while Play is off. |
| `googlePlaySource` | `off` | `official-api` | `public-page` | `off` | `public-page` is the scraping path. |
| `googlePlayServiceAccountJson` | secret | empty | JSON key invited in Play Console. Not written to the dataset. |
| `googlePlayAccessToken` | secret | empty | OAuth token for `androidpublisher`, used only if the JSON key is empty. An `AIza` API key is rejected. |
| `confirmGooglePlayPageScrape` | boolean | `false` | Must be true for `public-page`. |
| `googlePlayCountries` | list | `us` | Used only by the public page. |
| `stateName` | string | `default` | Letters, digits, `-` and `_`. Same name, same memory. |
| `maxReviewsPerSource` | integer | 500 | Cap per app and country. 500 is Apple's ceiling. |
| `requestDelayMs` | integer | 400 | Pause between requests. Minimum 200. |
| `proxyConfiguration` | object | Apify Proxy off | Optional. 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

| Field | Meaning |
|---|---|
| `recordType` | `review` |
| `store` | `app-store` or `google-play` |
| `country` | Storefront, or null for the Play Console API |
| `appId` | Apple id or Play package name |
| `reviewId` | Store review id |
| `rating` | 1 to 5 |
| `title`, `text` | Title may be null on Play |
| `author` | Public display name. No profile URL |
| `appVersion` | Version string, or null |
| `reviewedAt` | ISO 8601 time |
| `votes` | Helpful votes |
| `url` | Link from the feed, or the app's reviews page |
| `lowRatingAlert` | True or false |
| `fetchedVia` | `apple-rss`, `google-play-api`, or `google-play-page` |
| `language` | Play 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

| Key | Where | Meaning |
|---|---|---|
| `RUN_SUMMARY` | default store | Sources, delivered reviews, alert count, warnings |
| `LOW_RATING_ALERTS` | default store | Up to 200 alert rows and the full count |
| `STATE` | default store | Internal resume marker |
| `seen--{stateName}--{source}` | named store `app-store-play-review-monitor-state` | Gzipped 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%.

| Event | Free | Bronze | Silver | Gold and above | When |
|---|---|---|---|---|---|
| Actor start | $0.0005 | $0.0005 | $0.0005 | $0.0005 | Once per run (one event per GB of memory, minimum one) |
| Delivered review | $0.003 | $0.0027 | $0.0024 | $0.0021 | One 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 Actor | thewolves App Store reviews | neatrat Google Play reviews | Appbot |
|---|---|---|---|---|
| Apple | Public customer-reviews feed | Apple reviews | No | Yes |
| Google Play | Your API, or a confirmed public page | No | Public Play reviews | Yes |
| New since last run | Yes, saved in a key-value store | Not the product | Not the product | Yes, inside the dashboard |
| App version | Yes | Varies | Varies | Yes |
| Low-rating flag | Yes | No | No | Yes |
| Price signal | $0.003 per delivered review on Free | about $0.0001 per review | about $0.00015 per review | about $49–59/month |

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

### Legal and privacy

**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`:

```bash
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.

# Changelog

This Actor's version history is a separate document: https://apify.com/mmdincer/app-store-play-review-monitor/changelog.md

# Actor input Schema

## `appleAppIds` (type: `array`):

App Store apps to watch, one per line. Use the numeric id from the app URL (<code>id324684580</code> in <code>apps.apple.com/.../id324684580</code>) or paste the App Store URL. Up to 10 apps. Combined with countries, at most 20 pairs per run.

## `appleCountries` (type: `array`):

Two-letter storefront codes, for example <code>us</code>, <code>gb</code>, <code>de</code>, <code>tr</code>. <code>uk</code> is read as <code>gb</code>. Reviews differ by country. At most 5. Empty means <code>us</code> when an Apple app is set. The feed holds about the latest 500 reviews per country, not the archive.

## `onlyNew` (type: `boolean`):

On: the first run saves a baseline in a named key-value store and returns no review rows. Later runs return only reviews that were not saved and that are dated after the previous run (with a two-hour margin). Off: return the reviews currently in the feed and charge for each one, every run. Keep this on for a monitor.

## `minRating` (type: `integer`):

Keep reviews with at least this many stars (1 to 5). Reviews outside the range are not delivered and are not charged. Changing this, the maximum, the keywords or the review cap saves a new baseline instead of reporting the old feed as new.

## `maxRating` (type: `integer`):

Keep reviews with at most this many stars. Set this to 2, with the minimum at 1, when you only want the low ratings.

## `keywords` (type: `array`):

Optional. Keep a review only when its title or text contains at least one of these words (not case sensitive). Leave empty to keep every review in the star range. At most 30.

## `lowRatingThreshold` (type: `integer`):

A delivered review whose stars are this number or lower is marked <code>lowRatingAlert: true</code> and copied into the <code>LOW_RATING_ALERTS</code> key. The default is 2, so 1 and 2 star reviews are alerts. This does not add a second charge, and changing it does not reset the baseline.

## `googlePlayPackageNames` (type: `array`):

Optional. Package names such as <code>com.example.app</code>, or a <code>play.google.com</code> URL. Ignored while Google Play source is off. Up to 10.

## `googlePlaySource` (type: `string`):

<b>Off</b> skips Play. <b>Official API</b> calls Google's Android Publisher reviews API with your own service account or access token. It cannot read a competitor's private console. <b>Public page (scraping)</b> reads the public Play page. That path is off unless you also confirm it below. It can break without notice and may conflict with Google Play's terms.

## `googlePlayServiceAccountJson` (type: `string`):

Paste the JSON key of a service account that has been invited in Play Console for this app. The Actor exchanges it for a short-lived token (scope <code>androidpublisher</code>) and does not write the key to the dataset or the log. Preferred for a schedule, because an access token expires. Leave empty if you pass an access token instead.

## `googlePlayAccessToken` (type: `string`):

Alternative to the service account: an OAuth access token with the <code>androidpublisher</code> scope. A Google API key (starting with AIza) is rejected. Used only when the service account field is empty. Not written to the dataset.

## `confirmGooglePlayPageScrape` (type: `boolean`):

Required only when Google Play source is <b>Public page</b>. Leave this off. Turning it on means you accept an unsupported reader of the public Play page that may conflict with Google Play's terms and can stop working without notice. Rows from that path are labeled <code>fetchedVia: google-play-page</code>.

## `googlePlayCountries` (type: `array`):

Storefronts for the public-page path, for example <code>us</code>. Not used by the official API. At most 5. Empty means <code>us</code> when that path is on.

## `stateName` (type: `string`):

Name of the saved baseline (letters, digits, - and \_). Runs with the same name share a memory. Use another name to watch the same app for a different purpose. The ids are stored in the key-value store <code>app-store-play-review-monitor-state</code>.

## `maxReviewsPerSource` (type: `integer`):

Upper limit of reviews read for one app and country. Apple's feed has at most about 500 (10 pages of 50). A lower cap can miss reviews on a busy app. With new-reviews-only, reviews that are only saved as a baseline are free. With new-reviews-only off, each delivered review is charged.

## `requestDelayMs` (type: `integer`):

Pause between feed requests. Apple pages are requested one at a time. The default is 400. Minimum 200.

## `proxyConfiguration` (type: `object`):

Optional. Leave Apify Proxy off to request Apple directly. Turn it on and select the <b>residential</b> group when the customer-reviews feed comes back empty: datacenter addresses often receive a valid feed with no reviews, while the same URL still has reviews elsewhere. The Actor does not switch proxy by itself after a refusal. Proxy traffic is billed by Apify separately from the per-review price.

## Actor input object example

```json
{
  "appleAppIds": [
    "324684580"
  ],
  "appleCountries": [
    "us"
  ],
  "onlyNew": true,
  "minRating": 1,
  "maxRating": 5,
  "keywords": [
    "crash",
    "login"
  ],
  "lowRatingThreshold": 2,
  "googlePlayPackageNames": [
    "com.example.app"
  ],
  "googlePlaySource": "off",
  "confirmGooglePlayPageScrape": false,
  "googlePlayCountries": [
    "us"
  ],
  "stateName": "default",
  "maxReviewsPerSource": 500,
  "requestDelayMs": 400,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `reviews` (type: `string`):

One row per delivered review, plus the source summary rows. Keep rows with recordType review.

## `alerts` (type: `string`):

The same dataset, with the low-rating flag in the first column. Source rows have no flag.

## `sources` (type: `string`):

One row per app and country, or per Play package, with the outcome and counts.

## `summary` (type: `string`):

Sources checked, reviews delivered, low-rating alerts, warnings and why the run stopped.

## `lowRatingAlerts` (type: `string`):

Up to 200 delivered low-rating reviews, for a webhook. The dataset is the full list.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "appleAppIds": [
        "324684580"
    ],
    "appleCountries": [
        "us"
    ],
    "onlyNew": true,
    "minRating": 1,
    "maxRating": 5,
    "lowRatingThreshold": 2,
    "googlePlaySource": "off",
    "confirmGooglePlayPageScrape": false,
    "googlePlayCountries": [
        "us"
    ],
    "stateName": "default",
    "maxReviewsPerSource": 500,
    "requestDelayMs": 400,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("mmdincer/app-store-play-review-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "appleAppIds": ["324684580"],
    "appleCountries": ["us"],
    "onlyNew": True,
    "minRating": 1,
    "maxRating": 5,
    "lowRatingThreshold": 2,
    "googlePlaySource": "off",
    "confirmGooglePlayPageScrape": False,
    "googlePlayCountries": ["us"],
    "stateName": "default",
    "maxReviewsPerSource": 500,
    "requestDelayMs": 400,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("mmdincer/app-store-play-review-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "appleAppIds": [
    "324684580"
  ],
  "appleCountries": [
    "us"
  ],
  "onlyNew": true,
  "minRating": 1,
  "maxRating": 5,
  "lowRatingThreshold": 2,
  "googlePlaySource": "off",
  "confirmGooglePlayPageScrape": false,
  "googlePlayCountries": [
    "us"
  ],
  "stateName": "default",
  "maxReviewsPerSource": 500,
  "requestDelayMs": 400,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call mmdincer/app-store-play-review-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mmdincer/app-store-play-review-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/NqRbVNx3aEDaL0Dao/builds/DWb0N61IbdxxUPtS1/openapi.json
