# App Store Scraper (Pay-Per-Event) (`prodiger/app-store-scraper`) Actor

Scrape Apple App Store, iTunes, Music, and Podcasts data — app details, ratings, and reviews. Pay-per-event pricing: $0.30 per 1000 apps + $0.10 per 1000 reviews. No monthly fee.

- **URL**: https://apify.com/prodiger/app-store-scraper.md
- **Developed by:** [Arnas](https://apify.com/prodiger) (community)
- **Categories:** E-commerce, Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.15 / 1,000 app / track scrapeds

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/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 (Pay-Per-Event)

**App Store Scraper** is a fast, HTTP-only crawler that extracts apps, movies, podcasts, music, and reviews from Apple's [App Store](https://www.apple.com/app-store/) and [iTunes Store](https://www.apple.com/itunes/). This is the **Pay-Per-Event** edition — there is no $25/month rental and no minimum spend. **You pay only for the apps and reviews you actually scrape.**

Run it on the Apify platform for scheduling, API access, dataset exports (JSON, CSV, Excel, HTML), proxy rotation, monitoring, and integration with Make, Zapier, and 5000+ other tools.

### What does App Store Scraper do?

Give it App Store URLs (e.g., `https://apps.apple.com/us/app/angry-birds-2/id880047117`), iTunes detail URLs, podcast or music URLs, or a search keyword — the actor hits Apple's **public** `itunes.apple.com/search`, `/lookup`, and `/rss/customerreviews/.../json` endpoints. No API key, no headless browser, no authentication.

It supports two operating modes:

- **Search** — search the App Store / iTunes catalog by keyword + country + media type.
- **Lookup** — fetch one or more specific items by numeric Apple ID.

The scraper extracts:

- **App / track metadata** — title, vendor (`artistName`), genre, average rating, rating count, price, currency, release date, version, file size, supported devices, languages, screenshots, artwork at multiple resolutions.
- **Reviews** (optional) — id, score (1–5), title, body, reviewer username, version, updated date.
- **Cross-media** — works for apps (software), movies, TV shows, podcasts, music albums and songs, music videos, audiobooks, short films, and ebooks.

#### Smarter review pagination — pull ~1000 reviews per app, not ~500

Apple's reviews RSS feed caps each sort order (`sortby`) at roughly 10 pages × 50 reviews = ~500 reviews. This actor runs **two passes** — `sortby=mostrecent` AND `sortby=mosthelpful` — and **de-duplicates by review id**. The result: ~700–1000 unique reviews per popular app, depending on overlap. You're charged once per deduped review, never twice for the same review.

### Why use App Store Scraper?

- **Competitive intelligence** — Track competitor app updates, version bumps, rating drift, and review themes.
- **Market research** — Aggregate app catalogs across categories and countries.
- **Sentiment analysis** — Feed reviews into your LLM or analytics pipeline.
- **ASO (App Store Optimization)** — Surface which keywords match which apps and how rankings shift.
- **Catalog enrichment** — Augment your dataset with Apple-side metadata (icons, descriptions, ratings).

### How to use App Store Scraper

1. **Click "Try for free"** on this actor's page.
2. **Paste one or more Apple URLs** in the Start URLs field, or enter a **Search term**. You can mix any of these in one run:
   - `https://apps.apple.com/us/app/angry-birds-2/id880047117`
   - `https://itunes.apple.com/us/movie/inception/id400763833`
   - `https://podcasts.apple.com/us/podcast/game-dev-unchained/id1043547750`
3. **Enable "Include reviews"** if you want each app's reviews attached. Tune **Max reviews per app** to control review spend.
4. **Set "Max apps per run"** to cap your overall cost.
5. **(Optional)** Set a country, media type filter, or a custom map function.
6. **Click "Save & Start"**. Results stream into the dataset as they're scraped.
7. **Export** as JSON, CSV, Excel, or HTML — or hit the [Dataset API](https://docs.apify.com/api/v2#/reference/datasets) directly.

### Input

| Parameter | Type | Required | Description |
|---|---|---|---|
| `startUrls` | Array | No\* | iTunes / App Store / podcasts / music / books detail URLs. |
| `term` | string | No\* | Search keyword (or numeric ID(s) when `mode=lookup`). |
| `country` | string | No | Two-letter Apple country code. Default `us`. |
| `mediaType` | string | No | One of `all`, `software`, `movie`, `podcast`, `music`, `musicVideo`, `audiobook`, `shortFilm`, `tvShow`, `ebook`. Default `all`. |
| `mode` | string | No | `search` or `lookup`. Default `search`. |
| `includeReviews` | boolean | No | Pull reviews for every scraped app. Default `false`. |
| `maxItems` | integer | No | Hard cap on emitted detail items. `0` = unlimited. Default `100`. |
| `maxReviewsPerApp` | integer | No | Cap reviews per app. `0` = unlimited (effectively ~1000). Default `500`. |
| `endPage` | integer | No | Max search-result pages per source. `0` = unlimited. |
| `customMapFunction` | string | No | JS function body that transforms each item before dataset push. |
| `proxyConfiguration` | object | No | Apify Proxy. Default: Apify Proxy datacenter with AUTO rotation. |

\* You must provide at least one of `startUrls` or `term`.

#### Input examples

| Use case | Input JSON |
|---|---|
| Scrape one app with all reviews | `{ "startUrls": [{ "url": "https://apps.apple.com/us/app/angry-birds-2/id880047117" }], "includeReviews": true, "maxReviewsPerApp": 1000 }` |
| Search "game dev" for podcasts in GB | `{ "term": "game dev", "mediaType": "podcast", "country": "gb", "maxItems": 50 }` |
| Lookup multiple ids at once | `{ "mode": "lookup", "term": "880047117,400763833,1043547750" }` |
| Stay on first 3 search pages only | `{ "term": "calculator", "mediaType": "software", "endPage": 3 }` |
| Custom transform | `{ "term": "todo", "customMapFunction": "return { id: item.trackId, name: item.trackName };" }` |

### Output

All results land in the run's default dataset, one row per app/track. If `includeReviews=true`, each row has a `reviews` array.

#### Sample output

```json
{
    "wrapperType": "software",
    "kind": "software",
    "trackId": 880047117,
    "trackName": "Angry Birds 2",
    "artistName": "Rovio Entertainment Oyj",
    "primaryGenreName": "Games",
    "averageUserRating": 4.5,
    "userRatingCount": 1234567,
    "trackPrice": 0,
    "currency": "USD",
    "trackViewUrl": "https://apps.apple.com/us/app/angry-birds-2/id880047117?uo=4",
    "artworkUrl100": "https://is5-ssl.mzstatic.com/.../100x100bb.jpg",
    "artworkUrl512": "https://is5-ssl.mzstatic.com/.../512x512bb.jpg",
    "releaseDate": "2015-07-27T07:00:00Z",
    "version": "3.18.1",
    "description": "Welcome to the world of Angry Birds 2...",
    "screenshotUrls": ["https://..."],
    "languageCodesISO2A": ["EN", "FR", "DE", "ES"],
    "reviews": [
        {
            "id": "9519350766",
            "userName": "ultrageoffe",
            "userUrl": "https://itunes.apple.com/us/reviews/id212958678",
            "version": "2.3",
            "score": 1,
            "title": "Ad nightmare",
            "text": "Ads every few seconds. Don't waste your time",
            "url": "https://itunes.apple.com/us/review?id=1660464064",
            "updated": "2026-04-12T19:34:21-07:00"
        }
    ],
    "scrapedAt": "2026-05-15T19:00:00.000Z"
}
````

You can download the dataset as JSON, JSONL, CSV, Excel, or HTML.

#### Data table

| Field | Type | Description |
|---|---|---|
| `wrapperType` | string | Apple wrapper (`software`, `track`, `collection`, etc.) |
| `kind` | string | Apple subkind (`software`, `feature-movie`, `podcast`, etc.) |
| `trackId` | integer | Apple numeric id |
| `trackName` | string | Display title |
| `artistName` | string | Developer / publisher / artist |
| `primaryGenreName` | string | Top genre |
| `genres` | string\[] | All assigned genres |
| `averageUserRating` | number | 1.0–5.0 |
| `userRatingCount` | integer | Total rating count |
| `trackPrice` | number | Price in local currency |
| `currency` | string | 3-letter ISO code |
| `releaseDate` | datetime | ISO 8601 |
| `version` | string | App version (software only) |
| `screenshotUrls` | string\[] | iPhone screenshots |
| `ipadScreenshotUrls` | string\[] | iPad screenshots |
| `languageCodesISO2A` | string\[] | Supported languages |
| `reviews` | object\[] | Reviews (when `includeReviews=true`) |
| `scrapedAt` | datetime | ISO 8601 when this row was emitted |

### Pricing / Cost estimation

This actor uses **Pay-Per-Event** pricing. There is no monthly rental. You pay only when records are emitted.

| Event | Fired when | Free tier rate |
|---|---|---|
| `app-scraped` | A detail item is written to the dataset | **$0.0003 / item** (i.e. $0.30 per 1000) |
| `review-scraped` | A review row is written into an app's `reviews` array | **$0.0001 / review** ($0.10 per 1000) |

Higher Apify subscription tiers receive lower per-event rates — see the **Pricing** tab on this actor's listing for the current rate table.

**Cost examples (Free tier):**

| Workload | Apps | Reviews | Cost |
|---|---|---|---|
| One app + 100 reviews | 1 | 100 | **$0.0103** |
| 100 apps, no reviews | 100 | 0 | **$0.030** |
| 500 apps, 200 reviews each | 500 | 100,000 | **$10.15** |
| 10,000 apps, no reviews | 10,000 | 0 | **$3.00** |

#### How does this compare to $25/month App Store actors?

The most popular App Store actor on Apify Store charges **$25/month + usage**. This actor charges **$0.30 per 1000 apps + $0.10 per 1000 reviews** with **no monthly fee**. For workloads under ~80,000 items per month, PPE is strictly cheaper — and for one-off jobs (a few hundred items) the cost is **pennies**, instead of $25.

You also get:

- **Streaming output** — results appear in your dataset within seconds, not after a long batch.
- **Up to ~1000 reviews per app** via dual-sortby pagination (vs ~500 in subscription competitors).
- **No headless browser** — pure HTTP, so runs are 10× faster and cheaper in compute.

### Tips and advanced options

- **Lookup mode is fastest.** If you have numeric IDs, set `mode=lookup` and pass them in `term` (comma-separated) or as the `id...` portion of URLs in `startUrls`. One HTTP request returns up to 100 items.
- **Country matters for reviews.** Reviews are country-specific. To see UK reviews vs. US reviews, run the actor twice with different `country` values.
- **`mediaType=all` is broad.** Set a specific media type (`software`, `podcast`, etc.) to narrow search hits and avoid surprises.
- **Use `endPage`** to cap search-result pagination for shallow scans.
- **`customMapFunction`** runs in the actor container. It receives the raw Apple item shape; return a transformed object. Errors fall back to the unmapped item.

### Errors and partial failures

Bad input (malformed URL, non-existent ID, network error on one app) does **not** abort the run. Each error is captured to a sidecar key-value store entry named `errors-YYYY-MM-DD.jsonl`. Check the **Key-value stores** tab on your run for this file.

### FAQ, disclaimers, and support

**Is this legal?** Scraping public App Store metadata is generally legal in most jurisdictions, but you are responsible for complying with Apple's Terms of Service, copyright on screenshots/icons/copy, and applicable data-protection laws (GDPR, CCPA). Don't scrape personal data, and don't use reviewer names in ways that violate the reviewer's rights.

**Why are some reviews missing?** Apple's reviews RSS feed has a hard cap around 10 pages per sort order. This actor runs two sort orders (mostrecent + mosthelpful) and de-duplicates to get past ~500 — but Apple ultimately decides what's available.

**Why are some fields null?** Apple returns different field sets for different `wrapperType` values. A podcast row won't have `screenshotUrls`; a song row won't have `supportedDevices`. This is normal.

**How do I report bugs?** Open an issue on this actor's **Issues** tab on the Apify Store.

# Actor input Schema

## `startUrls` (type: `array`):

Apple detail URLs to scrape. Accepts apps.apple.com, itunes.apple.com, podcasts.apple.com, music.apple.com, and books.apple.com URLs. Mix any combination. If left empty, you must provide a search term instead.

## `term` (type: `string`):

Keyword to search across the App Store / iTunes catalog. In lookup mode this should be a numeric ID instead. Either this or startUrls is required.

## `country` (type: `string`):

Two-letter country code for the storefront to query. Default: us.

## `mediaType` (type: `string`):

Limit results to a single media category. Default: all.

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

Search returns matches for the term. Lookup expects a numeric ID and returns the single matching record. Default: search.

## `includeReviews` (type: `boolean`):

If enabled, the actor fetches reviews for every scraped app. Reviews are de-duplicated across two sortby passes (mostrecent + mosthelpful) so you typically get up to ~1000 reviews per app instead of the default ~500 cap. Each review is charged separately.

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

Maximum number of detail records (apps, movies, podcasts, etc.) to emit per run. Set to 0 for unlimited. Default: 100.

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

Cap on reviews emitted per app when includeReviews=true. Apple paginates ~50 reviews per page and caps each sortby at ~10 pages (~500 reviews). This actor runs two sortby passes (mostrecent + mosthelpful) and de-duplicates, so values up to ~1000 are practical. Set to 0 for unlimited.

## `endPage` (type: `integer`):

Caps the number of search-result pages walked per startUrl / term. Apple's search endpoint returns up to 200 results per page. Set to 0 for unlimited. Default: 0.

## `customMapFunction` (type: `string`):

Optional JavaScript function body that transforms each scraped item before it is pushed to the dataset. Receives the item as argument `item` and must return the modified item. Errors are logged and the unmodified item is emitted. Example: `return { trackId: item.trackId, name: item.trackName };`

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

Apify Proxy configuration. Default: Apify Proxy with AUTO rotation (datacenter). Apple's iTunes endpoints rate-limit per IP, so proxy rotation is recommended for runs over a few hundred items.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://apps.apple.com/us/app/angry-birds-2/id880047117"
    },
    {
      "url": "https://podcasts.apple.com/us/podcast/game-dev-unchained/id1043547750"
    }
  ],
  "country": "us",
  "mediaType": "all",
  "mode": "search",
  "includeReviews": false,
  "maxItems": 100,
  "maxReviewsPerApp": 500,
  "endPage": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Scraped apps and (optionally) their reviews.

# 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 = {
    "startUrls": [
        {
            "url": "https://apps.apple.com/us/app/angry-birds-2/id880047117"
        },
        {
            "url": "https://podcasts.apple.com/us/podcast/game-dev-unchained/id1043547750"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("prodiger/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 = {
    "startUrls": [
        { "url": "https://apps.apple.com/us/app/angry-birds-2/id880047117" },
        { "url": "https://podcasts.apple.com/us/podcast/game-dev-unchained/id1043547750" },
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("prodiger/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 '{
  "startUrls": [
    {
      "url": "https://apps.apple.com/us/app/angry-birds-2/id880047117"
    },
    {
      "url": "https://podcasts.apple.com/us/podcast/game-dev-unchained/id1043547750"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call prodiger/app-store-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "App Store Scraper (Pay-Per-Event)",
        "description": "Scrape Apple App Store, iTunes, Music, and Podcasts data — app details, ratings, and reviews. Pay-per-event pricing: $0.30 per 1000 apps + $0.10 per 1000 reviews. No monthly fee.",
        "version": "0.1",
        "x-build-id": "3K5tfdO1uDLpg4a99"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/prodiger~app-store-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-prodiger-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/prodiger~app-store-scraper/runs": {
            "post": {
                "operationId": "runs-sync-prodiger-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/prodiger~app-store-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-prodiger-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": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Apple detail URLs to scrape. Accepts apps.apple.com, itunes.apple.com, podcasts.apple.com, music.apple.com, and books.apple.com URLs. Mix any combination. If left empty, you must provide a search term instead.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "term": {
                        "title": "Search term",
                        "type": "string",
                        "description": "Keyword to search across the App Store / iTunes catalog. In lookup mode this should be a numeric ID instead. Either this or startUrls is required."
                    },
                    "country": {
                        "title": "Country",
                        "enum": [
                            "us",
                            "af",
                            "al",
                            "dz",
                            "ao",
                            "ai",
                            "ag",
                            "ar",
                            "am",
                            "au",
                            "at",
                            "az",
                            "bs",
                            "bh",
                            "bb",
                            "by",
                            "be",
                            "bz",
                            "bj",
                            "bm",
                            "bt",
                            "bo",
                            "ba",
                            "bw",
                            "br",
                            "vg",
                            "bn",
                            "bg",
                            "bf",
                            "kh",
                            "cm",
                            "ca",
                            "cv",
                            "ky",
                            "td",
                            "cl",
                            "cn",
                            "co",
                            "cd",
                            "cg",
                            "cr",
                            "ci",
                            "hr",
                            "cy",
                            "cz",
                            "dk",
                            "dm",
                            "do",
                            "ec",
                            "eg",
                            "sv",
                            "ee",
                            "sz",
                            "fj",
                            "fi",
                            "fr",
                            "ga",
                            "gm",
                            "ge",
                            "de",
                            "gh",
                            "gr",
                            "gd",
                            "gt",
                            "gw",
                            "gy",
                            "hn",
                            "hk",
                            "hu",
                            "is",
                            "in",
                            "id",
                            "iq",
                            "ie",
                            "il",
                            "it",
                            "jm",
                            "jp",
                            "jo",
                            "kz",
                            "ke",
                            "kr",
                            "xk",
                            "kw",
                            "kg",
                            "la",
                            "lv",
                            "lb",
                            "lr",
                            "ly",
                            "lt",
                            "lu",
                            "mo",
                            "mg",
                            "mw",
                            "my",
                            "mv",
                            "ml",
                            "mt",
                            "mr",
                            "mu",
                            "mx",
                            "fm",
                            "md",
                            "mn",
                            "me",
                            "ms",
                            "ma",
                            "mz",
                            "mm",
                            "na",
                            "nr",
                            "np",
                            "nl",
                            "nz",
                            "ni",
                            "ne",
                            "ng",
                            "mk",
                            "no",
                            "om",
                            "pk",
                            "pw",
                            "pa",
                            "pg",
                            "py",
                            "pe",
                            "ph",
                            "pl",
                            "pt",
                            "qa",
                            "ro",
                            "ru",
                            "rw",
                            "st",
                            "sa",
                            "sn",
                            "rs",
                            "sc",
                            "sl",
                            "sg",
                            "sk",
                            "si",
                            "sb",
                            "za",
                            "es",
                            "lk",
                            "kn",
                            "lc",
                            "vc",
                            "sr",
                            "se",
                            "ch",
                            "tw",
                            "tj",
                            "tz",
                            "th",
                            "to",
                            "tt",
                            "tn",
                            "tr",
                            "tm",
                            "tc",
                            "ug",
                            "ua",
                            "ae",
                            "gb",
                            "uy",
                            "uz",
                            "vu",
                            "ve",
                            "vn",
                            "ye",
                            "zm",
                            "zw"
                        ],
                        "type": "string",
                        "description": "Two-letter country code for the storefront to query. Default: us.",
                        "default": "us"
                    },
                    "mediaType": {
                        "title": "Media type",
                        "enum": [
                            "all",
                            "software",
                            "movie",
                            "podcast",
                            "music",
                            "musicVideo",
                            "audiobook",
                            "shortFilm",
                            "tvShow",
                            "ebook"
                        ],
                        "type": "string",
                        "description": "Limit results to a single media category. Default: all.",
                        "default": "all"
                    },
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "search",
                            "lookup"
                        ],
                        "type": "string",
                        "description": "Search returns matches for the term. Lookup expects a numeric ID and returns the single matching record. Default: search.",
                        "default": "search"
                    },
                    "includeReviews": {
                        "title": "Include reviews",
                        "type": "boolean",
                        "description": "If enabled, the actor fetches reviews for every scraped app. Reviews are de-duplicated across two sortby passes (mostrecent + mosthelpful) so you typically get up to ~1000 reviews per app instead of the default ~500 cap. Each review is charged separately.",
                        "default": false
                    },
                    "maxItems": {
                        "title": "Max apps per run",
                        "minimum": 0,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Maximum number of detail records (apps, movies, podcasts, etc.) to emit per run. Set to 0 for unlimited. Default: 100.",
                        "default": 100
                    },
                    "maxReviewsPerApp": {
                        "title": "Max reviews per app",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Cap on reviews emitted per app when includeReviews=true. Apple paginates ~50 reviews per page and caps each sortby at ~10 pages (~500 reviews). This actor runs two sortby passes (mostrecent + mosthelpful) and de-duplicates, so values up to ~1000 are practical. Set to 0 for unlimited.",
                        "default": 500
                    },
                    "endPage": {
                        "title": "Max search pages per source",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Caps the number of search-result pages walked per startUrl / term. Apple's search endpoint returns up to 200 results per page. Set to 0 for unlimited. Default: 0.",
                        "default": 0
                    },
                    "customMapFunction": {
                        "title": "Custom map function",
                        "type": "string",
                        "description": "Optional JavaScript function body that transforms each scraped item before it is pushed to the dataset. Receives the item as argument `item` and must return the modified item. Errors are logged and the unmodified item is emitted. Example: `return { trackId: item.trackId, name: item.trackName };`"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy configuration. Default: Apify Proxy with AUTO rotation (datacenter). Apple's iTunes endpoints rate-limit per IP, so proxy rotation is recommended for runs over a few hundred items.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
