# Apple App Store Reviews Scraper - iOS App Reviews & Ratings (`tidytools/apple-app-store-reviews`) Actor

App Store scraper for iOS app reviews and app details from Apple's official public feeds, many countries. Star, date and keyword filters, new-review alerts, optional AI summary. $0.10/1,000 reviews.

- **URL**: https://apify.com/tidytools/apple-app-store-reviews.md
- **Developed by:** [Yukai Lin](https://apify.com/tidytools) (community)
- **Categories:** Marketing, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 does Apple App Store Reviews Scraper do?

It returns **App Store customer reviews and app details** for any list of iPhone and iPad apps, in as many countries as you like, from **Apple's own public endpoints**: the customer reviews feed (RSS/JSON) and the iTunes Search and Lookup API. Paste app links, app ids, bundle ids or plain search terms; get one clean row per review and one row per app and country.

- 🍎 **Official public sources only**: no login, no private API tokens, no browser. The same feeds Apple publishes for developers and affiliates
- 🔗 **Any input**: `https://apps.apple.com/us/app/instagram/id389801252`, `389801252`, `id389801252`, `com.spotify.client`, or a search term such as `habit tracker` (first match or the top N). The same app pasted twice is read once
- 🌍 **Many countries in one run**: Apple keeps reviews per country store; list `us`, `gb`, `de`, `jp`… and every row says which store it came from
- ⭐ **Clean review rows**: `rating`, `title`, `text`, `version`, `date` (ISO, UTC), `author` (public display name only), `helpfulVotes`, `country`, `appName`, `reviewId`. The same fields on every row, every run
- 🎯 **Filters before charging**: minimum/maximum stars, reviews since a date (`2026-09-01` or `30 days`), keywords (any of), excluded keywords, app versions. Filtered-out reviews are free
- ↕️ **Sort**: most recent, most helpful, lowest or highest rating first, oldest first
- 📱 **App details**: developer, price, average rating and rating count (all versions and current version), version, release notes, release dates, category, age rating, size, languages, minimum iOS, icon and screenshot URLs, App Store link
- 🆕 **Only new reviews since the last run**: for daily monitoring. Reviews already seen are not output and not charged
- 🧠 **Optional AI insights per app**: a short summary plus top complaints, praises, feature requests and bug reports, each with an approximate count and an example quote (checked against the reviews: `exampleFound`)
- 🧾 **Honest about Apple's limit**: Apple's feed serves at most **500 reviews per app and country** (10 pages × 50). The Actor says so up front and in every run summary
- 💵 **$0.10 per 1,000 reviews**, $1 per 1,000 app details rows. No start fee

### Where the data comes from, and Apple's limits

| Data | Apple endpoint | Limit |
|---|---|---|
| Reviews | `https://itunes.apple.com/{country}/rss/customerreviews/page={1-10}/id={appId}/sortby={mostrecent or mosthelpful}/json` | 10 pages of 50 = **500 most recent (or most helpful) reviews per app and country**. Older reviews are not in the feed |
| App details, bundle id lookup | `https://itunes.apple.com/lookup?id=…&country=…` (up to 100 apps per call) | Apple asks for about **20 calls per minute** (subject to change) |
| Search terms | `https://itunes.apple.com/search?term=…&entity=software&country=…` | same as above |

What this means in practice:

- **At most 500 reviews per app and country.** This is the most common complaint about App Store review tools ("cannot get more than 200/450/500 reviews"). With 10 countries you can get up to 5,000 reviews of one app. For the full history of a big app you need Apple's own App Store Connect data (for your own apps) or a tool that uses Apple's private web API; this Actor deliberately does not.
- **Apple's feed has hiccups**: it often answers with an empty page for a page that does have reviews. The Actor asks again (with a fresh URL, a few at a time, up to 40 times by default) and reads each page it can get. In our test runs every page was read, with 2–35 requests per country for 2 pages; `SUMMARY.perApp[].perCountry` shows the pages read and requests made, and lists any page that stayed empty as `pagesMissing`.
- **Lookups and searches are spaced about 3 seconds apart** to follow Apple's rate guidance, so 100 search terms take about 5 minutes before reviews are read. App links and ids need no search.
- **No link to a single review**: Apple has no public page per review. Rows link to the app's reviews page (`reviewsUrl`).

### Who is it for?

- **App developers and product managers**: read what users say about your app and competitors, per version and country
- **ASO and app marketing teams**: ratings, rating counts, versions and release notes across countries; monitor new reviews daily
- **Customer support**: a daily feed of new 1- and 2-star reviews that mention "crash", "login" or "refund"
- **Market research**: compare apps in a category (top N search results for a keyword)
- **AI agents and analysts**: sentiment, feature requests and bug reports from real reviews

### How much does it cost?

Price per 1,000 events by Apify plan:

| Event | Free | Starter | Scale | Business and higher |
|---|---|---|---|---|
| Review | **$0.10** | **$0.10** | **$0.09** | **$0.08** |
| App details row (one app in one country) | $1.00 | $1.00 | $0.90 | $0.80 |
| AI insights (optional, per app) | $20 ($0.02 each) | $20 | $18 | $16 |

**No start fee.** Not charged: reviews removed by your filters, duplicate reviews, reviews already seen with **Only new reviews**, apps or search terms that are not found, apps not available in a country, app/country pairs where Apple's feed is empty (`apple_feed_empty` rows), invalid input lines, and AI insights that fail or have fewer than 10 reviews to work with.

For comparison (checked September 2026, Apple App Store review Actors on the Apify Store, Free plan prices): thewolves/appstore-reviews-scraper and theagents/appstore-reviews charge $0.0001 per result ($0.10 per 1,000); automation-lab/apple-app-store-scraper charges $0.00115 per review, $0.00345 per app and $0.005 per run start; johnvc/apple-app-store-reviews-api charges $0.00144 per review plus $0.0175 per run; sourabhbgp/apple-app-store-scraper charges $0.002 per row. Tools that promise thousands of reviews per country use Apple's private web API rather than the public feed.

### Control your cost

- **What is charged:** each review returned, each app details row, and each AI insight produced.
- **Max reviews per app and country** (up to 500, Apple's limit) and **Max reviews** for the whole run (default 10,000: at most $1 on the Free plan) cap the review charge.
- **Filters are applied before charging**, so "1–2 stars in the last 30 days" costs only for those reviews.
- **Only new reviews** makes daily schedules cheap: after the first run you pay only for reviews posted since the previous run.
- **Reviews only** mode skips the app details rows.
- At the start, the run logs its worst case (e.g. `Plan: 1500 reviews × $0.0001 + 15 app details rows × $0.001 + 5 AI insights × $0.02 = at most $0.265`) and warns when that is more than your **maximum charge per run**.
- When the maximum charge per run is reached, the run stops, keeps everything found so far, and says so. The `SUMMARY` record then has `status: "LIMIT_REACHED"` and `notProcessed` (up to 100 apps not processed).

**Worked example (real run, 30 September 2026, Free plan prices):** Instagram, WhatsApp, Spotify (bundle id), ChatGPT (search term) and Duolingo in the US, UK and German stores, 100 reviews per app and country, app details and AI insights on:

| What | Count | Cost |
|---|---|---|
| Reviews | 1,500 | $0.15 |
| App details rows | 15 | $0.015 |
| AI insights | 5 | $0.10 |
| **Total** | | **$0.265** (68 seconds) |

The same run without AI insights costs $0.165; reviews only, $0.15.

### Switching from another App Store reviews Actor

You can paste the input you already use. The field names of the two most-used App Store review Actors on the Apify Store are read as ours, and the log says how each one was read:

| Their field | Read here as |
|---|---|
| `appIds`, `startUrls` (strings or `{ "url": ... }`), `urls`, `product_ids` | `apps` |
| `app_name`, `searchTerm` | `apps`, as a search term |
| `country` (one code) | `countries` (with no country given, the countries in your App Store links are used) |
| `maxItems` | `maxReviews` (whole run) |
| `max_reviews` (`0` = unlimited) | `maxReviewsPerCountry` (500 for unlimited) |
| `sort` / `reviewSort` (`mostrecent`, `mosthelpful`, `mostcritical`, `mostfavorable`) | `sortBy` (`mostRecent`, `mostHelpful`, `lowestRating`, `highestRating`) |
| `until` ("reviews newer than this date") | `sinceDate` |

Our own fields win when both are given. `customMapFunction` is ignored (no custom code runs here; use the filters and the export formats instead), and `country: "all"` is not supported (list the countries you need). Every app is read in every country of the run.

Example: this input, written for another Actor, runs here unchanged:

```json
{ "appIds": ["284882215", "408709785"], "startUrls": ["https://apps.apple.com/gb/app/instagram/id389801252"], "maxItems": 1000 }
```

How they compare (Free plan prices from the Apify Store API and each Actor's README, checked 2 October 2026):

| | This Actor | thewolves/appstore-reviews-scraper | johnvc/apple-app-store-reviews-api |
|---|---|---|---|
| Price per 1,000 reviews | $0.10 (less on higher plans) | $0.10 | $1.44 ($1.25 on paid plans) |
| Start fee per run | none | none | $0.0175 |
| Free plan | full use (Apify's free monthly credit) | demo mode: 5 runs a month, 10 items per run (their README) | no limit stated |
| Reviews per app and country | up to 500 (Apple's public feed) | up to 500 (Apple's limit, per their README) | up to about 1,250 on iOS (their README) |
| Errors, filtered-out and duplicate reviews | not charged (free error rows) | not stated | not stated |
| Filters before charging (stars, date, keywords, app version) | yes | no | no (sort by most critical or favorable) |
| Input | links, ids, bundle ids, search terms; many countries per run | app ids or links; one country per run | app ids or one app name; one country per run; iOS and macOS apps |
| Only new reviews since the last run | yes | no | no |
| App details rows (rating, rating count, version, price…) | yes ($0.001 each, optional) | no | no (separate Actor) |
| AI summary of the reviews | optional ($0.02 per app) | no | no |

If you need more than 500 recent reviews of one app in one country, johnvc/apple-app-store-reviews-api reads deeper; for everything else this Actor costs the same or less.

### How to use it

1. Enter your **apps**, one per line: App Store links, app ids, bundle ids or search terms.
2. Enter the **countries** (two-letter codes; default `us`).
3. Choose **What to return**: app details + reviews, reviews only, or app details only.
4. Optional: set **Max reviews per app and country**, filters (stars, since, keywords, versions) and the sort order.
5. Optional: turn on **AI insights** and/or **Only new reviews since the last run** (then schedule the Actor daily).
6. Click **Start**. The **Reviews**, **App details** and **AI insights** tables are in the Output tab; export as CSV, Excel or JSON, or call the Actor from the API.

#### Input example

```json
{
    "apps": [
        "https://apps.apple.com/us/app/instagram/id389801252",
        "310633997",
        "com.spotify.client",
        "ChatGPT",
        "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128"
    ],
    "countries": ["us", "gb", "de"],
    "mode": "both",
    "maxReviewsPerCountry": 100,
    "aiInsights": true
}
```

Complaints only, last two weeks, most recent first:

```json
{ "apps": ["389801252"], "countries": ["us"], "mode": "reviews", "maxRating": 2, "sinceDate": "14 days", "keywords": ["bug", "crash", "glitch"] }
```

(A real run of that input on Instagram read all 500 reviews Apple serves in the US store and returned the 9 that matched; the 491 others were free.)

#### Output example: review

Real row from the run above:

```json
{
    "type": "review",
    "input": "com.spotify.client",
    "inputIndex": 2,
    "success": true,
    "reviewId": "14603311144",
    "appId": "324684580",
    "appName": "Spotify: Music and Podcasts",
    "country": "us",
    "rating": 1,
    "title": "Hate the update",
    "text": "Hate it thanks.",
    "version": "9.1.86",
    "author": "Poleryeno",
    "date": "2026-09-28T13:07:21.000Z",
    "helpfulVotes": 0,
    "totalVotes": 0,
    "reviewsUrl": "https://apps.apple.com/us/app/id324684580?see-all=reviews",
    "charged": true,
    "scrapedAt": "2026-09-30T06:04:24.099Z"
}
```

With **Only new reviews**, rows also have `changeType: "new"`.

#### Output example: app details

Real row (lists and long texts shortened):

```json
{
    "type": "app",
    "input": "com.spotify.client",
    "success": true,
    "matchedBy": "bundle",
    "appId": "324684580",
    "bundleId": "com.spotify.client",
    "appName": "Spotify: Music and Podcasts",
    "developer": "Spotify",
    "developerUrl": "https://apps.apple.com/us/developer/spotify/id324684583",
    "sellerWebsite": "https://www.spotify.com/",
    "country": "us",
    "price": 0,
    "currency": "USD",
    "formattedPrice": "Free",
    "averageRating": 4.773,
    "ratingCount": 42342256,
    "averageRatingCurrentVersion": 4.773,
    "ratingCountCurrentVersion": 42342256,
    "version": "9.1.86",
    "currentVersionReleaseDate": "2026-09-23T17:49:27Z",
    "releaseNotes": "We’re always making changes and improvements to Spotify. To make sure you don’t miss a thing, just keep your Updates turned on.",
    "releaseDate": "2011-07-14T11:22:37Z",
    "description": "With the Spotify app, you can explore an extensive library of music and podcasts for free. …",
    "primaryGenre": "Music",
    "genres": ["Music", "Entertainment"],
    "contentRating": "12+",
    "minimumOsVersion": "16.1",
    "fileSizeMB": 296.9,
    "languages": ["AF", "AM", "…"],
    "iconUrl": "https://is1-ssl.mzstatic.com/image/thumb/Purple211/v4/…/512x512bb.jpg",
    "screenshotUrls": ["https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/…/392x696bb.png", "…"],
    "appUrl": "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
    "reviewsUrl": "https://apps.apple.com/us/app/id324684580?see-all=reviews",
    "charged": true
}
```

Search-term rows also have `searchTerm` and `searchRank`. Other fields: `developerId`, `seller`, `advisories`, `fileSizeBytes`, `supportedDevicesCount`, `features`, `isGameCenterEnabled`, `ipadScreenshotUrls`.

#### Output example: AI insights

Real row for Spotify (300 reviews in the run; the AI reads up to about 30,000 characters, here 159 reviews with every star rating represented). Lists shortened:

```json
{
    "type": "insights",
    "appName": "Spotify: Music and Podcasts",
    "countries": ["us", "gb", "de"],
    "reviewsInRun": 300,
    "reviewsAnalyzed": 159,
    "ratingsAnalyzed": { "1": 44, "2": 16, "3": 31, "4": 24, "5": 44 },
    "averageRatingInRun": 3.9,
    "overallSentiment": "negative",
    "summary": "Users are frustrated with excessive ads, premium ad issues, and price increases. They also report app freezing, post-update functionality issues, and podcast functionality problems. Despite these issues, many praise the music library, content variety, offline access, and user experience.",
    "complaints": [
        { "topic": "Excessive Advertising", "approxMentions": 15, "example": "Too many ads. When you don’t have premium, you basically cannot use the app.", "exampleFound": true },
        { "topic": "Premium Ad Issues", "approxMentions": 10, "example": "Premium = No adds, not a little less but more intrusive adds.", "exampleFound": true }
    ],
    "praises": [{ "topic": "Offline Access", "approxMentions": 6, "example": "Always there. Thanks Spotify for keeping the music going offline out in the back woods!", "exampleFound": true }],
    "featureRequests": [{ "topic": "Playlist Management Improvements", "approxMentions": 5, "example": "Allow us to add to a playlist by hold the plus instead of it going straight to liked music", "exampleFound": true }],
    "bugReports": [{ "topic": "App Freezing/Freezing Issues", "approxMentions": 5, "example": "The app freezes when I go between APP on my iPad.", "exampleFound": true }],
    "charged": true
}
```

`approxMentions` is the AI's estimate, not an exact count. `exampleFound` is `true` when the quote appears word for word in one of the reviews; `false` means the AI paraphrased it (about a third of the quotes in our test run). Use **Insights language** for a summary in another language. The summary is written by an open model on Cloudflare Workers AI (Qwen3 30B, with Llama 4 Scout as a second try when the first answer is not usable); an insight that still fails is returned as a free error row.

#### Errors (not charged)

Every input that cannot be used gets a row with `success: false`, an `errorType` and an `error` ending in "(not charged)":

```json
{ "type": "input", "input": "https://play.google.com/store/apps/details?id=x", "field": "apps", "success": false, "errorType": "invalid_input", "error": "\"https://play.google.com/store/apps/details?id=x\": play.google.com is not an App Store link (apps.apple.com/.../id123) (not charged)", "charged": false }
```

`errorType` is `invalid_input` (a line or country code that cannot be used), `not_found` (no such app or bundle id, a search with no results, or an app not available in a country), `blocked` (Apple kept refusing requests), `network`/`timeout`, `apple_feed_empty` (Apple's reviews feed answered but had no review at all for that app and country, even after retries; the row has `ratingCountInStore` from the App Store so you can tell "no written reviews" from a feed problem), or `no_text` (AI insights skipped: fewer than 10 reviews).

The `SUMMARY` record (key-value store) has `status` (`SUCCESS`, `PARTIAL_RESULTS`, `FAILED`, `NO_RESULTS`, `LIMIT_REACHED`), totals (`reviewsOutput`, `detailsOutput`, `insightsOutput`, `reviewsFilteredOut`, `duplicatesSkipped`), `feed` (requests, rate-limited answers, pause time) and `perApp[].perCountry` (pages read, reviews fetched, matched and returned, a `note` such as "no new reviews since the last run").

### Integrations

- **Schedules**: run daily with **Only new reviews** for a new-reviews feed; add a 1–2 star filter for a complaints alert.
- **API and webhooks**: start runs and read the dataset from any language; use a webhook to get notified when a run finishes.
- **Exports**: CSV, Excel, JSON, XML and HTML from the dataset.
- **Apify integrations**: send results to Google Sheets, Slack, Zapier, Make, n8n and others from the Integrations tab.

#### Use with AI agents (MCP)

Connect Apify's MCP server (https://mcp.apify.com?tools=tidytools/apple-app-store-reviews) to Claude, Cursor or any MCP client, then ask e.g. "What do UK users complain about in the latest Duolingo reviews? Show the top issues with examples."

```json
{ "apps": ["570060128"], "countries": ["gb"], "mode": "reviews", "maxReviewsPerCountry": 200, "maxRating": 3, "aiInsights": true }
```

Failed items are not charged and carry an `errorType`.

### Tips and limitations

- **500 reviews per app and country is Apple's limit** for the public feed (see above). Add countries to get more reviews of the same app.
- **Apple's feed can lag behind the App Store page.** In late September 2026 the newest review in the feed was 1 to 2.5 days old for every app we checked. When the newest review read in a run is more than 48 hours old, the run says so (`SUMMARY.feedLagWarning`, `newestReviewInFeed`); with **Only new reviews** the late reviews simply appear in a later run. `SUMMARY.perCountry` gives the same per country: `newestReviewInFeed`, `feedLagHours` (age of the newest review over all apps of the run), `feedLagWarning` (over 48 hours), and how many apps had reviews or an empty feed. A quiet app with few reviews makes the lag look bigger than it is, so compare countries with apps that get reviews every day.
- **Search terms** are searched in the first country of your list; use **Search results per term** for the top N. App links and ids are more precise.
- **Bundle ids**: a dotted token like `com.spotify.client` or `notion.id` is looked up as a bundle id first and searched as a term if no app has it.
- **Country matters**: an app's name, price, rating and reviews differ per store; an app that is not sold in a country gets a free `not_found` row for that country.
- **Sorting by rating or oldest** reads all 500 recent reviews first (a few seconds more); newest-first and most-helpful stop as soon as they have enough.
- **Dates** are converted to UTC. Reviews have no language field; the text is in the reviewer's language.
- **Only new reviews** remembers review ids per app and country for each monitor name. Use a different monitor name for a different app list.
- If a run reports many rate-limited requests (`SUMMARY.feed.rateLimited`), lower **Feed requests in parallel** in Advanced settings.

### Terms and responsible use

- The Actor uses only Apple's public endpoints listed above, with no login. Apple's Search API documentation (checked September 2026) says the API is limited to approximately 20 calls per minute; the Actor spaces its lookups and searches accordingly and backs off when Apple answers "rate limited".
- Apple's terms for promotional content from these APIs (app icons, screenshots and other artwork) allow using it to promote the store content, next to a link or badge to the App Store; Apple may ask for it to be removed. Keep that in mind before republishing icons or screenshots.
- Reviews are written by App Store users. Only the reviewer's public display name is returned (no profile link or id). Use reviews for analysis, research and product work; if you quote them publicly, attribute them to the App Store and do not present them as your own content.

### FAQ

**Why do I get at most 500 reviews per country?** Apple's public reviews feed serves only the 500 most recent (or most helpful) reviews per app and country. The Actor does not use Apple's private web API.

**Why did I get fewer reviews than I asked for?** Check your filters (`SUMMARY.reviewsFilteredOut`), **Max reviews**, and `SUMMARY.perApp[].perCountry`: small apps have few written reviews in some countries, and a page that stayed empty after all retries is listed in `pagesMissing`.

**Is the average rating the same as the reviews?** No. `averageRating` and `ratingCount` count all star ratings, most of which have no written review; the reviews feed contains written reviews only.

**Does it support Google Play?** No, only the Apple App Store.

**Can I run it on a schedule?** Yes. Turn on **Only new reviews since the last run**, set a monitor name, and create a daily schedule in Apify Console.

Found this useful? A short review on the Store helps other users find it.

# Actor input Schema

## `apps` (type: `array`):

Main input: the run needs at least one line here. One app per line, any mix of: an App Store link (https://apps.apple.com/us/app/instagram/id389801252), a numeric app id (389801252 or id389801252), a bundle id (com.burbn.instagram) or a search term (e.g. habit tracker — the top result, or the top N with "Search results per term"). Prefix with id:, bundle: or search: to force one kind. Invalid lines and apps that are not found get an error row and are not charged.

## `countries` (type: `array`):

Two-letter country codes, e.g. us, gb, de, fr, jp, br, in. Reviews and app details are read from each country's store (Apple keeps reviews per country). Search terms are searched in the first country. Default: us.

## `mode` (type: `string`):

App details are one row per app and country; reviews are one row per review. Values: both = App details + reviews; reviews = Reviews only; details = App details only (name, developer, price, rating, rating count, version, release notes, size, languages, screenshots…).

## `maxReviewsPerCountry` (type: `integer`):

Apple's public reviews feed serves at most 500 reviews per app and country (10 pages of 50, most recent or most helpful first). Counted after your filters.

## `maxReviews` (type: `integer`):

Stop after this many reviews in total. You pay only for reviews returned: 10,000 reviews cost at most $1 on the Free plan.

## `sortBy` (type: `string`):

Which reviews Apple serves (newest or most helpful) and the order of the output rows. Values: mostRecent = Most recent first (Apple's newest-first feed); mostHelpful = Most helpful first (Apple's most-helpful feed); lowestRating = Lowest rating first (reads all 500 recent reviews, then sorts); highestRating = Highest rating first (reads all 500 recent reviews, then sorts); oldest = Oldest first (of the 500 most recent).

## `searchResultsPerTerm` (type: `integer`):

For search-term lines: take the top N apps of the App Store search (1 = first match only).

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

Keep reviews with at least this many stars. Filtered-out reviews are not charged.

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

Keep reviews with at most this many stars, e.g. 2 for complaints only.

## `sinceDate` (type: `string`):

A date (2026-09-01) or a period (7 days, 2 weeks, 3 months). Older reviews are skipped and not charged; with the newest-first order, reading stops at the first older page.

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

Keep reviews whose title or text contains at least one of these words or phrases (case-insensitive), e.g. crash, subscription, dark mode.

## `excludeKeywords` (type: `array`):

Drop reviews whose title or text contains any of these.

## `appVersions` (type: `array`):

Keep reviews written for these app versions only, e.g. 448.0.0, or 448 for every 448.x version.

## `aiInsights` (type: `boolean`):

One extra row per app: an AI summary of the reviews returned in this run, with top praises, complaints, feature requests and bug reports (each with an example quote). Charged per app ($0.02 on the Free plan) only when the summary is produced; needs at least 10 reviews.

## `insightsLanguage` (type: `string`):

Language of the AI summary, e.g. German or Japanese. Default: English. Example quotes stay in the reviewers' words.

## `onlyNewReviews` (type: `boolean`):

Remember the reviews of every app and country and return only reviews that were not there on the previous run of the same monitor (the first run returns everything and becomes the baseline). Reviews already seen are not output and not charged. Ideal for daily schedules.

## `monitorName` (type: `string`):

Runs with the same name are compared with each other (letters, digits, dashes). Use different names for different app lists. Default: "default".

## `dedupeReviews` (type: `boolean`):

Apple's feed can shift while it is read (new reviews push older ones to the next page), so the same review may appear twice. Duplicates are removed by review id and never charged.

## `emptyPageRetries` (type: `integer`):

Apple's reviews feed often answers with an empty page for a page that has reviews. Each empty page is asked again up to this many times (with a fresh URL so a cached empty answer is not reused). Higher = more complete, a bit slower.

## `maxConcurrency` (type: `integer`):

How many apps are processed at the same time. App lookups and searches are always spaced about 3 seconds apart, as Apple asks (about 20 calls per minute).

## `feedConcurrency` (type: `integer`):

How many reviews-feed requests run at the same time across all apps. When Apple answers "rate limited" (HTTP 403/429), every request pauses together and retries later (not charged). Lower it if runs report many rate-limited requests (SUMMARY.feed).

## `appTimeoutSecs` (type: `integer`):

An app that takes longer gets a timeout error row (not charged) so one slow app cannot hold the run.

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

Only used for requests sent from Apify's network (all requests of this Actor). Apify proxy usage is billed to your Apify account. Not needed normally.

## Actor input object example

```json
{
  "apps": [
    "https://apps.apple.com/us/app/notion-notes-tasks-ai/id1232780281",
    "com.spotify.client"
  ],
  "countries": [
    "us",
    "gb"
  ],
  "mode": "both",
  "maxReviewsPerCountry": 20,
  "maxReviews": 10000,
  "sortBy": "mostRecent",
  "searchResultsPerTerm": 1,
  "minRating": 1,
  "maxRating": 5,
  "aiInsights": false,
  "onlyNewReviews": false,
  "dedupeReviews": true,
  "emptyPageRetries": 40,
  "maxConcurrency": 3,
  "feedConcurrency": 4,
  "appTimeoutSecs": 900
}
```

# Actor output Schema

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

No description

## `apps` (type: `string`):

No description

## `insights` (type: `string`):

No description

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

No description

# 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 = {
    "apps": [
        "https://apps.apple.com/us/app/notion-notes-tasks-ai/id1232780281",
        "com.spotify.client"
    ],
    "countries": [
        "us",
        "gb"
    ],
    "maxReviewsPerCountry": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidytools/apple-app-store-reviews").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 = {
    "apps": [
        "https://apps.apple.com/us/app/notion-notes-tasks-ai/id1232780281",
        "com.spotify.client",
    ],
    "countries": [
        "us",
        "gb",
    ],
    "maxReviewsPerCountry": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("tidytools/apple-app-store-reviews").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 '{
  "apps": [
    "https://apps.apple.com/us/app/notion-notes-tasks-ai/id1232780281",
    "com.spotify.client"
  ],
  "countries": [
    "us",
    "gb"
  ],
  "maxReviewsPerCountry": 20
}' |
apify call tidytools/apple-app-store-reviews --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tidytools/apple-app-store-reviews"
        }
    }
}
```

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/Z9MXLhY9FvkLVvdB2/builds/94PB8196pnYupeDeo/openapi.json
