# App Store Scraper · Apps, Reviews, Search & Developer Emails (`memo23/app-store-scraper`) Actor

Scrape the Apple App Store — app details, reviews, ranked search (ASO), similar apps and developer portfolios — across multiple countries in one run. Optional ratings histogram and developer contact-email enrichment. Prices, ratings and ranking per storefront. JSON, CSV, Excel.

- **URL**: https://apify.com/memo23/app-store-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Lead generation, AI, SEO tools
- **Stats:** 18 total users, 17 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 result rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## App Store Scraper — App Details, Reviews, Search, Similar & Developer Apps

Turn any Apple App Store app, search term, or developer into a clean, structured dataset. Pull full app info, reviews, ranked search results, similar apps, or a developer's whole portfolio — and run every input across **multiple countries** in a single run.

![How it works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-app-store.png)

Get full app info including score, **ratings histogram (1–5★ breakdown)**, price, content rating, version, release notes, and a screenshot gallery — plus optional **similar apps**, **ASO search rank**, and the **developer website + contact email** for lead generation. Pure HTTP, no browser.

### 🧠 NEW: Review Intelligence — reviews → product intel

Don't just pull reviews — find out **what to fix and build next**. Two opt-in tiers on the `reviews` action, billed per app:

- **📊 Review insights** (free of AI, instant) — one summary row per app: rating breakdown, sentiment split, the recurring complaint themes (crashes, pricing, ads, login…), top negative terms, and the feature requests users keep asking for.
- **🤖 AI pain-point analysis** (premium, Claude) — a deeper teardown: severity-ranked themes with how often they recur, missing features, quick wins, and a written summary.

> _An app, 300 reviews →_ **Frequent crashes on launch** (severity 5, 40% of reviews) · **Aggressive ads / paywall** (28%) · missing: _offline mode, dark theme_ · quick win: _fix the login loop_.

[See the output rows →](#output-overview)

### Why Use This Scraper?

- ✅ Multi-country in one run — every input runs against each storefront you list; prices, ratings, availability, and ranking are returned per country
- ✅ Five actions from one actor — app details, reviews, ranked search (ASO), similar apps, and a developer's full app list
- ✅ Ratings histogram built in — the full 1★–5★ vote breakdown plus the rating total, not just the average score
- ✅ ASO rank tracking built in — search results come back in the App Store's ranked order, and the array position **is** the rank
- ✅ Optional similar apps — the App Store's own "you may also like" list attached to each app row
- ✅ Developer website + contact email — turn the store into a lead list for app-marketing/ASO outreach (with optional email enrichment)
- ✅ JSON, CSV, or Excel output, ready for spreadsheets, CRMs, and BI tools

### Overview

The App Store Scraper is built for ASO specialists, app marketers, market researchers, and developers who need Apple App Store data in a spreadsheet instead of a browser tab.

You pick one **action** per run and feed it the matching input — app URLs/IDs, search terms, or developer IDs. Every input is then executed against each country in `countries`, so a single run can compare an app's rating in the US, UK, and Japan side by side, or capture how a keyword ranks in different storefronts.

The actor is pure HTTP — it reads Apple's public iTunes and App Store data (built on the maintained `app-store-scraper` engine plus a value-add normalization and enrichment layer). No login, no browser, no API key. Output is clean, flat rows you can export straight to CSV or Excel.

### Supported Inputs

#### Actions

| Action | What it returns | Input used |
|---|---|---|
| **App details** (`appDetails`) | Full app info per app, with optional ratings histogram, similar apps, and developer email | `appUrls` |
| **Reviews** (`reviews`) | App reviews, sorted most recent / most helpful, paginated | `appUrls` |
| **Search** (`search`) | Ranked search results — the array position is the ASO rank | `searchQueries` |
| **Similar apps** (`similar`) | Apps the App Store lists as similar to a given app | `appUrls` |
| **Developer's apps** (`developer`) | Every app published by a developer | `devIds` |

Every action runs across **each country** in `countries`, so the row count is roughly `inputs × countries` (capped by `maxItems`).

#### Input formats

| Input | Accepts | Example |
|---|---|---|
| `appUrls` | Full App Store URL, numeric track ID, **or** bundle ID | `https://apps.apple.com/us/app/spotify/id324684580`, `324684580`, or `com.spotify.client` |
| `searchQueries` | Plain keywords | `podcast app` |
| `devIds` | Developer page URL **or** numeric developer ID | `https://apps.apple.com/us/developer/spotify/id324684583` or `324684583` |
| `countries` | Two-letter storefront codes | `["us", "gb", "jp"]` |
| `language` | Locale tag (optional) | `en-us` |

#### Copy-pasteable input

```json
{
  "action": "appDetails",
  "appUrls": ["com.spotify.client", "324684580"],
  "countries": ["us", "gb", "jp"],
  "language": "en-us",
  "includeRatings": true,
  "includeSimilar": true
}
````

#### Unsupported inputs

- ❌ Content behind an Apple account login (purchase history, library, account settings)
- ❌ Google Play / Android apps — this actor targets `apps.apple.com` only
- ❌ Mixing actions in one run — pick one `action` per run (chain runs or schedule for multiple)

### Use Cases

| Audience | Use case |
|---|---|
| **App marketers & ASO specialists** | Track keyword rank over time, benchmark competitors, study titles, ratings, and screenshots |
| **Market researchers & analysts** | Bulk-export app catalogs, ratings, and pricing across categories and countries |
| **Pricing & availability teams** | Monitor per-country price and availability — the App Store is localized, so it varies by storefront |
| **Review intelligence teams** | Pull review streams (most recent / most helpful) for sentiment, bug surfacing, and feature requests |
| **Competitive intelligence** | Compare ratings histograms and versions across an app portfolio or against rivals |
| **Sales / lead-gen & agencies** | Turn search results and developer portfolios into a prospect list with websites + contact emails |

### How It Works

<p align="center">
  <img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-app-store.png" alt="How It Works" width="100%" />
</p>

1. **Input** — choose an `action` and supply the matching input (app URLs/IDs/bundle IDs, search terms, or developer IDs)
2. **Fan out by country** — each input is queued once per storefront in `countries`, so prices/ratings/ranking are captured per market
3. **Fetch** — Apple's public iTunes and App Store data is retrieved over HTTP (no browser), via the maintained `app-store-scraper` engine
4. **Parse & enrich** — raw data is normalized into clean rows; optionally attach the ratings histogram, similar apps, and the developer contact email
5. **Output** — flat `app`, `review`, or `searchResult` rows as JSON, CSV, or Excel, stopping once `maxItems` is reached

### Input Configuration

| Field | Type | Required | Notes |
|---|---|---|---|
| `action` | `string` | yes | One of `appDetails`, `reviews`, `search`, `similar`, `developer`. Default `appDetails`. |
| `appUrls` | `array<string>` | for `appDetails` / `reviews` / `similar` | App Store URLs, numeric track IDs, or bundle IDs. |
| `searchQueries` | `array<string>` | for `search` | Keywords to search. Results come back in ranked (ASO) order. |
| `devIds` | `array<string>` | for `developer` | Developer page URLs or numeric developer IDs. |
| `countries` | `array<string>` | no | Two-letter storefront codes. **Every input runs against each one.** Default `["us"]`. |
| `language` | `string` | no | Locale tag (e.g. `en-us`) for returned text. Defaults to the storefront's locale. |
| `includeRatings` | `boolean` | no | Attach the ratings histogram (1★–5★ vote counts + total). One extra request per app. App details only. Default `false`. |
| `includeSimilar` | `boolean` | no | Attach a `similarApps[]` list to each app row. One extra request per app. App details only. Default `false`. |
| `enrichEmails` | `boolean` | no | Resolve a contact email from the developer's website (lead-gen). Adds `contactEmail` + `emailEnrichment`. **Billed per email found**, only when an email is returned. App details only. Default `false`. |
| `reviewsSort` | `string` | no | `recent` or `helpful` (action = Reviews). Default `recent`. |
| `maxReviewsPerApp` | `integer` | no | Upper bound on reviews per app per country (action = Reviews). The App Store exposes up to ~500. Default `100`. |
| `reviewInsights` | `boolean` | no | Add a `review_insights` summary row per app: rating breakdown, sentiment split, complaint themes, top negative terms, and feature requests. No AI/keys. **Billed per app analyzed.** Default `false`. |
| `painPointAnalysis` | `boolean` | no | AI (Claude) teardown per app — severity-ranked themes, missing features, quick wins, summary. **Paid Apify plans only; billed per app analyzed.** Default `false`. |
| `resultsLimit` | `integer` | no | Max results per search term, developer, or similar-apps call. Default `50`. |
| `maxItems` | `integer` | no | Hard cap on **total dataset rows** across all inputs and countries. Default `1000`. Free-tier runs are capped at `100`. |
| `maxConcurrency` | `integer` | no | Maximum requests in flight. Default `6`. |
| `proxy` | `object` | no | Defaults to Apify Proxy. Geo is handled by the `countries` param in-request, so a proxy mainly spreads load and avoids rate-limits. |

#### Common scenarios

**1. Compare one app across three countries**

```json
{
  "action": "appDetails",
  "appUrls": ["com.spotify.client"],
  "countries": ["us", "gb", "jp"]
}
```

**2. Track a keyword's ASO rank in two markets**

```json
{
  "action": "search",
  "searchQueries": ["podcast app", "meditation"],
  "countries": ["us", "de"],
  "resultsLimit": 50
}
```

**3. App details with ratings histogram, similar apps + developer email**

```json
{
  "action": "appDetails",
  "appUrls": ["324684580"],
  "countries": ["us"],
  "includeRatings": true,
  "includeSimilar": true,
  "enrichEmails": true
}
```

**4. Most recent reviews for an app**

```json
{
  "action": "reviews",
  "appUrls": ["com.spotify.client"],
  "countries": ["us"],
  "reviewsSort": "recent",
  "maxReviewsPerApp": 200
}
```

### Output Overview

Each dataset item is one of five shapes, set by `rowType`:

- **`app`** — emitted by `appDetails`, `similar`, and `developer`. Carries the full app schema, plus optional `ratings` + `ratingsHistogram`, `similarApps[]`, and (with `enrichEmails`) `contactEmail` + `emailEnrichment`.
- **`review`** — emitted by `reviews`. One row per review.
- **`review_insights`** — emitted by `reviews` when `reviewInsights` is on. Deterministic (no-AI) summary row per app: rating breakdown, sentiment split, complaint themes, top negative terms, feature requests.
- **`painPointAnalysis`** — emitted by `reviews` when `painPointAnalysis` is on (paid plans). AI (Claude) teardown per app: clustered themes with severity, missing features, quick wins, sentiment, summary.
- **`searchResult`** — emitted by `search`. One row per ranked result; `rank` is the 1-based ASO position.

**Two tiers of review analysis:** `reviewInsights` is the free-of-AI, instant, deterministic digest; `painPointAnalysis` is the premium AI version that actually *understands* the reviews (severity-ranked themes, quick wins, a written summary). Use either or both.

Notes on when fields are populated:

- **`country`** is set on every row — the same app/keyword pulled for three countries produces three rows.
- **`developerWebsite`** comes straight from the app's store listing when the developer provides it.
- **`ratings`** + **`ratingsHistogram`** and **`similarApps[]`** appear only when the matching `include*` toggle is on. **`contactEmail`** + **`emailEnrichment`** appear only with `enrichEmails` and a resolvable website.

Output is JSON by default; the Apify Console "Export" tab also produces CSV and Excel.

### Output Samples

#### App row — `appDetails` with optional sections

```json
{
  "rowType": "app",
  "id": 324684580,
  "appId": "com.spotify.client",
  "url": "https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580",
  "country": "us",
  "title": "Spotify: Music and Podcasts",
  "developer": "Spotify",
  "developerId": 324684583,
  "developerWebsite": "https://www.spotify.com/",
  "primaryGenre": "Music",
  "price": 0,
  "free": true,
  "currency": "USD",
  "score": 4.78,
  "reviews": 40672036,
  "version": "9.0.0",
  "ratings": 40672036,
  "ratingsHistogram": { "1": 839493, "2": 327898, "3": 879940, "4": 2842303, "5": 35783634 },
  "similarApps": [{ "id": 0, "appId": "...", "title": "...", "score": 4.5 }],
  "scrapedAt": "2026-06-29T12:00:00.000Z"
}
```

#### Review row — `reviews`

```json
{
  "rowType": "review",
  "id": 324684580,
  "appId": "com.spotify.client",
  "country": "us",
  "reviewId": "11538914627",
  "userName": "Jane D.",
  "score": 5,
  "title": "Love the new mix",
  "text": "The redesigned library makes finding playlists so much faster.",
  "version": "9.0.0",
  "updated": "2026-06-20T10:11:00.000Z",
  "url": "https://itunes.apple.com/us/review?id=324684580",
  "scrapedAt": "2026-06-29T12:00:00.000Z"
}
```

#### Review-insights row — `reviews` with `reviewInsights: true`

One summary per app, mined from the reviews just scraped — the "what are people complaining about / begging for" digest:

```jsonc
{
  "rowType": "review_insights",
  "appId": "com.spotify.client",
  "appName": "Spotify",
  "country": "us",
  "totalAnalyzed": 200,
  "averageScore": 2.9,
  "ratingBreakdown": { "1": 62, "2": 28, "3": 24, "4": 30, "5": 56 },
  "sentimentSplit": { "positive": 43, "neutral": 12, "negative": 45 },
  "topThemes": [
    { "theme": "Pricing & subscriptions", "mentions": 41, "sharePct": 28.5 },
    { "theme": "Crashes & stability", "mentions": 33, "sharePct": 22.9 },
    { "theme": "Ads", "mentions": 22, "sharePct": 15.3 }
  ],
  "topComplaintTerms": [ { "term": "shuffle", "count": 18 }, { "term": "premium", "count": 14 } ],
  "featureRequests": [ "wish it had a sleep timer on the free tier", "please add lyrics offline" ]
}
```

#### AI pain-point row — `reviews` with `painPointAnalysis: true` (paid plans)

An AI teardown per app — the premium version of the digest above:

```jsonc
{
  "rowType": "painPointAnalysis",
  "appId": "com.spotify.client",
  "reviewsAnalyzed": 200,
  "topThemes": [
    { "theme": "Shuffle feels random and repeats artists", "severity": 4, "mentionSharePct": 24,
      "exampleQuotes": ["shuffle plays the same 10 songs", "..."] },
    { "theme": "Premium price hikes without new value", "severity": 4, "mentionSharePct": 19, "exampleQuotes": ["..."] }
  ],
  "missingFeatures": ["true offline lyrics", "sleep timer on free tier"],
  "quickWins": ["fix shuffle randomization", "let free users queue tracks"],
  "overallSentiment": "mixed",
  "summary": "Users love the catalog but are frustrated by shuffle behavior and rising Premium prices.",
  "generatedAt": "2026-07-09T09:00:00.000Z"
}
```

#### Search-result row — `search` (`rank` = ASO position)

```json
{
  "rowType": "searchResult",
  "query": "podcast app",
  "country": "us",
  "rank": 1,
  "id": 324684580,
  "appId": "com.spotify.client",
  "title": "Spotify: Music and Podcasts",
  "developer": "Spotify",
  "score": 4.78,
  "price": 0,
  "scrapedAt": "2026-06-29T12:00:00.000Z"
}
```

### Key Output Fields

#### App row (`rowType: "app"`)

| Field | Description |
|---|---|
| `id` | Numeric App Store track ID, e.g. `324684580` |
| `appId` | Bundle ID, e.g. `com.spotify.client` |
| `url` | Canonical App Store URL (with the row's storefront) |
| `country` | The storefront this row was scraped for |
| `title`, `description` | App name and full description |
| `developer`, `developerId` | Developer name and numeric ID |
| `developerWebsite` | Developer website (lead-gen) |
| `primaryGenre`, `genres` | Primary category plus the full genre list |
| `contentRating` | Content/age rating |
| `price`, `free`, `currency` | Numeric price, free flag, currency |
| `score`, `reviews` | All-time average rating and review count |
| `currentVersionScore`, `currentVersionReviews` | Average rating and review count for the current version |
| `version` | Current version string |
| `released`, `updated` | Original release date and last-updated date |
| `releaseNotes` | "What's New" notes for the current version |
| `size` | Download size |
| `requiredOsVersion` | Minimum iOS version |
| `languages` | Supported languages |
| `icon`, `screenshots` | Icon URL and screenshot gallery |
| `ratings` *(optional)* | Total number of ratings (`includeRatings`) |
| `ratingsHistogram` *(optional)* | 1★–5★ vote counts (`includeRatings`) |
| `similarApps[]` *(optional)* | `{ id, appId, title, score }` per similar app (`includeSimilar`) |
| `contactEmail` *(optional)* | Email resolved from the developer site (`enrichEmails`) |
| `scrapedAt` | ISO timestamp of the scrape |

#### Review row (`rowType: "review"`)

`reviewId`, `userName`, `title`, `text`, `score`, `version`, `updated`, `url` — plus `id`, `appId`, `country`, and `scrapedAt`.

#### Search-result row (`rowType: "searchResult"`)

`rank` (1-based ASO position), `id`, `appId`, `title`, `developer`, `score`, `price` — plus `query`, `country`, and `scrapedAt`.

### FAQ

#### Do I need to log in or supply an API key?

No. The actor reads Apple's public App Store data over HTTP — no Apple ID, no login, no API key.

#### Is this the official App Store API?

No. It is not an official API and is not affiliated with Apple. It uses Apple's public iTunes and App Store data — the same listings you'd see in a browser — and returns them as clean, structured rows.

#### Why do I get different data per country?

The App Store is localized — prices, ratings, availability, and search ranking all differ by storefront. So you pass `countries` (two-letter storefront codes), and every input is scraped once per country. A row's `country` field tells you which storefront it came from.

#### Does it work outside the country I'm in?

Yes. Geo is controlled by the `countries` parameter, in-request — not by your IP or the proxy location. You can sit anywhere and pull US, UK, and Japanese data in the same run.

#### How many reviews can I get per app?

The App Store exposes up to roughly 500 reviews per app per country. Set `maxReviewsPerApp` up to that ceiling and choose `recent` or `helpful` ordering with `reviewsSort`.

#### Is the developer email always present?

Not always. Unlike Google Play, Apple doesn't publish a developer contact email on the app page, so it can only be resolved via the developer's website with the optional `enrichEmails` step — it's best-effort and present only when a website is listed and an email is found.

#### What's the difference between `search` rank and the other actions?

`search` returns results in the App Store's own ranked order and stamps each with a 1-based `rank` — that's the ASO position for the keyword. The other actions (`appDetails`, `reviews`, `similar`, `developer`) aren't ranked.

#### Can I export to JSON, CSV, or Excel?

Yes. Output is JSON by default; the Apify Console "Export" tab also produces CSV and Excel (XLSX).

#### What about rate limits?

Apple can throttle heavy runs. Keep `maxConcurrency` reasonable (the default `6` is a safe start) and use a proxy for large jobs. The actor defaults to Apify Proxy; supply your own pool for very large runs.

### Support

Found a bug, hit throttling we don't handle gracefully, or want another action or field supported? Open an issue on the actor's **Issues** tab, or reach out via the [memo23 profile](https://apify.com/memo23) on Apify.

### Additional Services

Need a custom export shape, a new entry point, scheduled rank monitoring, or a bespoke enrichment pipeline? I build tailored scrapers and data pipelines — get in touch via the [memo23 profile](https://apify.com/memo23).

### Explore More Scrapers

If you track apps, rankings, and developers, these pair well:

- [**Google Play Scraper**](https://apify.com/memo23) — the Android side of the same workflow; cross-reference Apple vs Google Play
- [**Trustpilot Scraper**](https://apify.com/memo23/trustpilot-scraper-ppe) — company-level sentiment for the developers behind the apps
- [**G2 Scraper**](https://apify.com/memo23/g2-scraper) — see how an app's vendor ranks on B2B software reviews
- [**Product Hunt Scraper**](https://apify.com/memo23) — discover newly launched apps and their makers
- [**LinkedIn Profiles Scraper**](https://apify.com/memo23/linkedin-profiles-cheerio) — backfill founder/developer profiles for outreach

Full portfolio: [apify.com/memo23](https://apify.com/memo23).

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Apple Inc., the App Store, or any of their parent companies or subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available App Store data — no authenticated endpoints, no account-gated content, and nothing behind an Apple ID login. Users are responsible for ensuring their use complies with Apple's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization. Developer contact emails and reviewer data are personal data — process them responsibly, honor opt-outs, and seek legal advice before outbound marketing.

***

### SEO Keywords

app store scraper, scrape app store, apple app store scraper, ios app scraper, app store api, itunes app scraper, apple app data, apps.apple.com scraper, Apify app store, app store reviews scraper, app store search scraper, aso rank tracker, app store optimization data, app store developer scraper, ios app reviews api, app market research, app store ratings histogram, multi country app pricing, ios app metadata scraper, developer contact email scraper, app marketing lead generation

# Actor input Schema

## `action` (type: `string`):

What to extract. appDetails returns full app info (with optional ratings histogram, similar apps and developer email); reviews returns app reviews; search returns ranked results (ASO position); similar returns related apps; developer returns a developer's apps. Tip: you can just fill the field you have — a keyword in Search terms OR an app URL in App URLs — and the Actor auto-runs the matching action even if this dropdown says something else.

## `appUrls` (type: `array`):

App Store app URLs, numeric track IDs, or bundle IDs (e.g. https://apps.apple.com/us/app/spotify/id324684580, 324684580, or com.spotify.client). Used by App details / Reviews / Similar apps.

## `searchQueries` (type: `array`):

Keywords to search (Search action). If you fill this and leave App URLs empty, the Actor runs a search automatically — even if Action is still on 'App details'. Results come back in the App Store's ranked order — array position is the ASO rank.

## `devIds` (type: `array`):

Apple developer IDs or developer-page URLs (used by action = Developer's apps), e.g. 324684583 or https://apps.apple.com/us/developer/spotify/id324684583.

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

Two-letter storefront codes to scrape — every input runs against each country. Prices, ratings, availability and ranking are country-specific. Default \['us'].

## `language` (type: `string`):

Optional language code (e.g. en-us) for the returned text.

## `includeRatings` (type: `boolean`):

Attach the total ratings count and the 1–5 star histogram. One extra request per app. (App details only.)

## `includeSimilar` (type: `boolean`):

Attach a list of similar apps to each app row. One extra request per app. (App details only.)

## `enrichEmails` (type: `boolean`):

Resolve a contact email from the developer's website (lead generation). Adds contactEmail + emailEnrichment. Billed per email found; only charged when an email is returned. (App details only.)

## `reviewsSort` (type: `string`):

Order for reviews (action = Reviews). The App Store exposes up to ~500 reviews per app per country.

## `maxReviewsPerApp` (type: `integer`):

Upper bound on reviews collected per app per country (action = Reviews). The App Store caps at ~500.

## `resultsLimit` (type: `integer`):

Max results per search term or developer.

## `reviewInsights` (type: `boolean`):

Adds one `review_insights` summary row per app: rating breakdown & sentiment split, the recurring complaint themes (crashes, pricing, ads, login, missing features…), the top negative-review terms, and feature-request snippets users are asking for. Instant, no AI/keys required. Billed per app analyzed.

## `painPointAnalysis` (type: `boolean`):

The premium tier of review insights. Runs an AI (Claude) pass over each app's reviews and adds a `painPointAnalysis` row: clustered pain-point themes with severity & recurrence, missing features users ask for, quick wins, overall sentiment and a short summary — e.g. an app → 'Frequent crashes on launch' (severity 5, 40% of reviews), missing: offline mode. Requires a paid Apify plan (uses AI credits); billed per app analyzed. For a free, no-AI version use Review insights above.

## `maxItems` (type: `integer`):

Hard cap on total dataset rows across all inputs and countries.

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

Maximum requests in flight.

## `proxy` (type: `object`):

Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies.

## Actor input object example

```json
{
  "action": "appDetails",
  "appUrls": [
    "324684580",
    "https://apps.apple.com/us/app/whatsapp-messenger/id310633997"
  ],
  "searchQueries": [],
  "devIds": [],
  "countries": [
    "us",
    "gb",
    "jp"
  ],
  "includeRatings": false,
  "includeSimilar": false,
  "enrichEmails": false,
  "reviewsSort": "recent",
  "maxReviewsPerApp": 100,
  "resultsLimit": 50,
  "reviewInsights": false,
  "painPointAnalysis": false,
  "maxItems": 1000,
  "maxConcurrency": 6
}
```

# 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 = {
    "appUrls": [
        "324684580",
        "https://apps.apple.com/us/app/whatsapp-messenger/id310633997"
    ],
    "searchQueries": [],
    "devIds": [],
    "countries": [
        "us",
        "gb",
        "jp"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/app-store-scraper").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 = {
    "appUrls": [
        "324684580",
        "https://apps.apple.com/us/app/whatsapp-messenger/id310633997",
    ],
    "searchQueries": [],
    "devIds": [],
    "countries": [
        "us",
        "gb",
        "jp",
    ],
}

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

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

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

```

## CLI example

```bash
echo '{
  "appUrls": [
    "324684580",
    "https://apps.apple.com/us/app/whatsapp-messenger/id310633997"
  ],
  "searchQueries": [],
  "devIds": [],
  "countries": [
    "us",
    "gb",
    "jp"
  ]
}' |
apify call memo23/app-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=memo23/app-store-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "App Store Scraper · Apps, Reviews, Search & Developer Emails",
        "description": "Scrape the Apple App Store — app details, reviews, ranked search (ASO), similar apps and developer portfolios — across multiple countries in one run. Optional ratings histogram and developer contact-email enrichment. Prices, ratings and ranking per storefront. JSON, CSV, Excel.",
        "version": "0.0",
        "x-build-id": "IMqsw6LJkQbTfwKKe"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/memo23~app-store-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-memo23-app-store-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/memo23~app-store-scraper/runs": {
            "post": {
                "operationId": "runs-sync-memo23-app-store-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/memo23~app-store-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-memo23-app-store-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "action": {
                        "title": "Action",
                        "enum": [
                            "appDetails",
                            "reviews",
                            "search",
                            "similar",
                            "developer"
                        ],
                        "type": "string",
                        "description": "What to extract. appDetails returns full app info (with optional ratings histogram, similar apps and developer email); reviews returns app reviews; search returns ranked results (ASO position); similar returns related apps; developer returns a developer's apps. Tip: you can just fill the field you have — a keyword in Search terms OR an app URL in App URLs — and the Actor auto-runs the matching action even if this dropdown says something else.",
                        "default": "appDetails"
                    },
                    "appUrls": {
                        "title": "App Store URLs / IDs",
                        "type": "array",
                        "description": "App Store app URLs, numeric track IDs, or bundle IDs (e.g. https://apps.apple.com/us/app/spotify/id324684580, 324684580, or com.spotify.client). Used by App details / Reviews / Similar apps.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchQueries": {
                        "title": "Search terms",
                        "type": "array",
                        "description": "Keywords to search (Search action). If you fill this and leave App URLs empty, the Actor runs a search automatically — even if Action is still on 'App details'. Results come back in the App Store's ranked order — array position is the ASO rank.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "devIds": {
                        "title": "Developer IDs",
                        "type": "array",
                        "description": "Apple developer IDs or developer-page URLs (used by action = Developer's apps), e.g. 324684583 or https://apps.apple.com/us/developer/spotify/id324684583.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "countries": {
                        "title": "Countries",
                        "type": "array",
                        "description": "Two-letter storefront codes to scrape — every input runs against each country. Prices, ratings, availability and ranking are country-specific. Default ['us'].",
                        "items": {
                            "type": "string"
                        }
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "Optional language code (e.g. en-us) for the returned text."
                    },
                    "includeRatings": {
                        "title": "Include ratings histogram",
                        "type": "boolean",
                        "description": "Attach the total ratings count and the 1–5 star histogram. One extra request per app. (App details only.)",
                        "default": false
                    },
                    "includeSimilar": {
                        "title": "Include similar apps",
                        "type": "boolean",
                        "description": "Attach a list of similar apps to each app row. One extra request per app. (App details only.)",
                        "default": false
                    },
                    "enrichEmails": {
                        "title": "Enrich with developer contact email (billed per email)",
                        "type": "boolean",
                        "description": "Resolve a contact email from the developer's website (lead generation). Adds contactEmail + emailEnrichment. Billed per email found; only charged when an email is returned. (App details only.)",
                        "default": false
                    },
                    "reviewsSort": {
                        "title": "Reviews sort",
                        "enum": [
                            "recent",
                            "helpful"
                        ],
                        "type": "string",
                        "description": "Order for reviews (action = Reviews). The App Store exposes up to ~500 reviews per app per country.",
                        "default": "recent"
                    },
                    "maxReviewsPerApp": {
                        "title": "Max reviews per app",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Upper bound on reviews collected per app per country (action = Reviews). The App Store caps at ~500.",
                        "default": 100
                    },
                    "resultsLimit": {
                        "title": "Results per query / developer",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Max results per search term or developer.",
                        "default": 50
                    },
                    "reviewInsights": {
                        "title": "📊 Review insights — auto-analyze the reviews (billed per app)",
                        "type": "boolean",
                        "description": "Adds one `review_insights` summary row per app: rating breakdown & sentiment split, the recurring complaint themes (crashes, pricing, ads, login, missing features…), the top negative-review terms, and feature-request snippets users are asking for. Instant, no AI/keys required. Billed per app analyzed.",
                        "default": false
                    },
                    "painPointAnalysis": {
                        "title": "🤖 AI pain-point analysis — LLM teardown (paid plans, billed per app)",
                        "type": "boolean",
                        "description": "The premium tier of review insights. Runs an AI (Claude) pass over each app's reviews and adds a `painPointAnalysis` row: clustered pain-point themes with severity & recurrence, missing features users ask for, quick wins, overall sentiment and a short summary — e.g. an app → 'Frequent crashes on launch' (severity 5, 40% of reviews), missing: offline mode. Requires a paid Apify plan (uses AI credits); billed per app analyzed. For a free, no-AI version use Review insights above.",
                        "default": false
                    },
                    "maxItems": {
                        "title": "Maximum items to scrape",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Hard cap on total dataset rows across all inputs and countries.",
                        "default": 1000
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum requests in flight.",
                        "default": 6
                    },
                    "proxy": {
                        "title": "Proxy configuration (optional override)",
                        "type": "object",
                        "description": "Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
