# App Store Scraper – App Details & Top Charts (`sfoln/app-store-scraper`) Actor

Apple App Store data by app ID, bundle ID or URL in any country: name, developer, price, rating, ratings count, version, release notes, size, genres, screenshots. Plus keyword search, customer reviews and top free, paid and grossing charts. $1 per 1,000 apps, $0.10 per 1,000 reviews.

- **URL**: https://apify.com/sfoln/app-store-scraper.md
- **Developed by:** [SFOLN LLC](https://apify.com/sfoln) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 app store apps

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

Get **Apple App Store data as clean JSON**: app details by app ID, bundle ID or App Store URL in any country, **customer reviews**, **keyword search results** and **top free, paid and grossing charts**. One record per app, review or chart entry, for app-market research, ASO and competitor tracking, review monitoring and AI agents. **$1 per 1,000 apps, $0.10 per 1,000 reviews**, no start fee; unknown apps and errors are free.

- **What you get:** name, developer, price, rating and ratings count (overall and current version), version, release notes, size, genres, age rating, languages, icon and screenshot links; reviews with rating, title, text, app version, reviewer nickname and date; chart rank.
- **Price:** `app` $0.001 per app, `review` $0.0001 per review, `chart-entry` $0.0005 per chart entry.
- **Works everywhere:** API, MCP for AI agents, Make, Zapier, n8n, schedules and webhooks.

### Input

Choose a `mode` and fill its list. Every app, keyword or chart is fetched in each country of `countries`; each such combination is one **item** with its own record. An app listed twice in one country (for example as ID and as URL) is fetched and charged once.

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `apps` | `apps` (app details), `reviews` (customer reviews), `search` (keyword search) or `charts` (top charts). |
| `apps` | string\[] | – | Apps and reviews modes: App Store IDs (`1232780281`), bundle IDs (`notion.id`) or App Store URLs. |
| `searchTerms` | string\[] | – | Search mode: keywords, one per line. |
| `charts` | string\[] | `["top-free"]` | Charts mode: `top-free`, `top-paid`, `top-grossing`. |
| `chartGenre` | string | – | Charts mode: limit to a genre by ID (`6014`) or name (`Games`, `Productivity`, `Finance`…). |
| `countries` | string\[] | `us` | Two-letter App Store country codes. Empty: `us`, or the country inside an App Store URL. |
| `includeReviews` | boolean | false | Apps mode: also return each app's reviews (charged per review). |
| `maxReviewsPerApp` | integer | 100 | Reviews per app and country (1–500). |
| `reviewSort` | string | `mostrecent` | `mostrecent` or `mosthelpful`. |
| `maxSearchResults` | integer | 50 | Apps per keyword and country (1–200). |
| `chartSize` | integer | 100 | Entries per chart and country (1–100). |
| `maxItems` | integer | 1000 | Safety cap on items per run; the rest is reported in `OUTPUT` as `inputItemsDropped`. |
| `concurrency` | integer | by mode | Items in parallel (1–10): 10 for apps, 2 for reviews and charts, 1 for search. |
| `includeRaw` | boolean | false | Attach Apple's unmodified JSON under `raw`. |

```json
{ "mode": "apps", "apps": ["1232780281", "https://apps.apple.com/us/app/instagram/id389801252"], "countries": ["us", "gb"] }
```

```json
{ "mode": "reviews", "apps": ["notion.id"], "maxReviewsPerApp": 200, "reviewSort": "mostrecent" }
```

```json
{ "mode": "charts", "charts": ["top-free", "top-grossing"], "chartGenre": "Games", "chartSize": 25, "countries": ["us", "jp"] }
```

### Output

Every record has `recordType`: `app`, `review`, `chart-entry`, or `summary` (one per item in the reviews, search and charts modes, free). In the apps mode the `app` record is itself the item's record.

App (apps mode; the search mode adds `rank` and `searchTerm`):

```json
{
  "input": { "mode": "apps", "app": "1232780281", "country": "us" },
  "recordType": "app",
  "appId": "1232780281",
  "bundleId": "notion.id",
  "name": "Notion: Notes, Tasks, AI",
  "url": "https://apps.apple.com/us/app/notion-notes-tasks-ai/id1232780281",
  "country": "us",
  "developer": "Notion Labs, Incorporated",
  "developerId": "1232780280",
  "developerUrl": "https://apps.apple.com/us/developer/notion-labs-incorporated/id1232780280",
  "sellerName": "Notion Labs, Incorporated",
  "developerWebsite": "https://www.notion.so",
  "price": 0,
  "currency": "USD",
  "formattedPrice": "Free",
  "isFree": true,
  "rating": 4.7752,
  "ratingCount": 90387,
  "ratingCurrentVersion": 4.7752,
  "ratingCountCurrentVersion": 90387,
  "version": "1.7.346",
  "currentVersionReleaseDate": "2026-10-13T04:16:20.000Z",
  "releaseNotes": "Bug fixes and performance improvements.",
  "releaseDate": "2017-09-14T19:07:31.000Z",
  "description": "Notion is an AI-powered all-in-one workspace…",
  "sizeBytes": 485872640,
  "minimumOsVersion": "18.0",
  "primaryGenre": "Productivity",
  "primaryGenreId": "6007",
  "genres": ["Productivity", "Business"],
  "genreIds": ["6007", "6000"],
  "contentRating": "4+",
  "advisories": [],
  "languages": ["AR", "DA", "NL", "EN", "FI", "FR", "DE"],
  "iconUrl": "https://is1-ssl.mzstatic.com/image/thumb/Purple211/v4/ba/fa/05/AppIcon/512x512bb.jpg",
  "screenshotUrls": ["https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/94/dd/d8/1.png/392x696bb.png"],
  "ipadScreenshotUrls": [],
  "appleTvScreenshotUrls": [],
  "features": ["iosUniversal"],
  "supportedDeviceCount": 118,
  "gameCenterEnabled": false,
  "kind": "software",
  "status": "ok",
  "charged": true,
  "chargedEvent": "app",
  "source": "appstore",
  "fetchedAt": "2026-10-14T21:48:14.000Z"
}
```

Review (reviews mode, or apps mode with `includeReviews`) and chart entry:

```json
[
  {
    "input": { "mode": "reviews", "app": "1232780281", "country": "us" },
    "recordType": "review",
    "position": 1,
    "reviewId": "14661465107",
    "appId": "1232780281",
    "country": "us",
    "rating": 4,
    "title": "Great for meeting notes",
    "text": "I use it every day; sync could be faster.",
    "version": "1.7.346",
    "authorName": "Reviewer Alpha",
    "updatedAt": "2026-10-13T12:15:16.000Z",
    "helpfulVotes": 0,
    "totalVotes": 0,
    "sort": "mostrecent",
    "status": "ok",
    "charged": true,
    "chargedEvent": "review",
    "source": "appstore",
    "fetchedAt": "2026-10-14T21:50:02.000Z"
  },
  {
    "input": { "mode": "charts", "chart": "top-free", "country": "us" },
    "recordType": "chart-entry",
    "position": 1,
    "chart": "top-free",
    "country": "us",
    "genreId": null,
    "rank": 1,
    "appId": "6760173601",
    "name": "Muse from Meta",
    "developer": "Meta Platforms, Inc.",
    "developerUrl": null,
    "url": "https://apps.apple.com/us/app/muse-from-meta/id6760173601",
    "iconUrl": "https://is1-ssl.mzstatic.com/image/thumb/Purple211/v4/8b/37/be/AppIcon/100x100bb.png",
    "releaseDate": "2026-09-08",
    "genres": [],
    "bundleId": null,
    "price": null,
    "currency": null,
    "summary": null,
    "status": "ok",
    "charged": true,
    "chargedEvent": "chart-entry",
    "source": "appstore",
    "fetchedAt": "2026-10-14T21:49:17.000Z"
  }
]
```

Summary record (one per item in the reviews, search and charts modes; never charged):

```json
{ "input": { "mode": "reviews", "app": "1232780281", "country": "us" }, "recordType": "summary", "country": "us", "sort": "mostrecent", "appId": "1232780281", "appName": "Notion: Notes, Tasks, AI", "rating": 4.7752, "ratingCount": 90387, "resultsDelivered": 200, "stopReason": "limit", "status": "ok", "charged": false, "source": "appstore", "fetchedAt": "2026-10-14T21:50:40.000Z" }
```

| Field | Meaning |
| --- | --- |
| `appId`, `bundleId`, `name`, `url`, `country` | The app in one storefront (prices, ratings and texts differ per country). |
| `rating`, `ratingCount`, `ratingCurrentVersion`, `ratingCountCurrentVersion` | Average star rating and number of ratings, overall and for the current version. |
| `version`, `currentVersionReleaseDate`, `releaseNotes`, `releaseDate` | Current version and its notes; `releaseDate` is the first release. |
| `rank`, `searchTerm` | Search mode: position in Apple's results for the keyword. |
| `reviewId`, `rating`, `title`, `text`, `version`, `authorName`, `updatedAt`, `helpfulVotes`, `totalVotes` | Review rows (`rating` 1–5, `version` = app version reviewed). |
| `chart`, `rank`, `genreId`, `summary` | Chart rows; `bundleId`, `price` and `summary` come with genre and top-grossing charts. |
| `reviewsDelivered`, `reviewsStopReason` | Apps mode with `includeReviews`: how many reviews were delivered and why they stopped. |
| `resultsDelivered`, `stopReason` | Summary rows: rows delivered for the item; `limit`, `end`, `free_plan`, `budget`, `aborted`, `deadline` or `error`. |

`status` is one of:

- `ok`: delivered (rows and app records charged; summaries free);
- `not_found`: no such app in that country's App Store (not charged);
- `error`: Apple failed or throttled the request (not charged);
- `skipped_invalid`: not an App Store ID, bundle ID or URL (not charged);
- `skipped_budget`: your **Maximum cost per run** was reached (not charged);
- `skipped_free_plan`: beyond the free-plan limit below (not charged);
- `skipped_unmetered`: the run is not pay-per-event (not charged).

The run's key-value store `OUTPUT` record contains totals (counts, charged amount).

### Pricing

Pay-per-event, charged only for delivered rows:

| Event | Price | When |
| --- | --- | --- |
| `app` | $0.001 | per app record (apps mode) or app in search results (search mode) |
| `review` | $0.0001 | per review row |
| `chart-entry` | $0.0005 | per chart entry |

Examples: details of 1,000 apps cost $1; 500 reviews of one app cost $0.05; the US top-100 free chart costs $0.05. Set **Maximum cost per run** to cap spend: rows are sized to the remaining budget before they are fetched, and the Actor stops cleanly when the cap is reached. Accounts on the Apify free plan can process up to 10 items per run (an item is one app, keyword or chart in one country) and 20 rows per item; further items are returned with `status: "skipped_free_plan"` and are not charged. Upgrade to any paid Apify plan for full batches.

### Use with AI agents (MCP)

Use this Actor from Claude, ChatGPT, Cursor, VS Code or any other MCP client through the [Apify MCP server](https://mcp.apify.com). Add this server URL to your client and sign in with your Apify account when asked:

```text
https://mcp.apify.com?tools=sfoln/app-store-scraper
```

To run the MCP server locally instead, start `npx -y @apify/actors-mcp-server --tools sfoln/app-store-scraper` with your `APIFY_TOKEN` in the environment.

Example prompt:

> Get the App Store details (rating, ratings count, version, price) of app 1232780281 in the US and UK stores.

Runs started by an agent are billed like any other run (see Pricing). Agents can cap what a run may spend with `maxTotalChargeUsd`.

### API usage

Run the Actor and get its dataset items in one call (the call waits up to 5 minutes for the run to finish):

```bash
curl -X POST "https://api.apify.com/v2/acts/sfoln~app-store-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"apps": ["1232780281"]}'
```

For large inputs, start the run asynchronously and download the dataset when it has finished:

```bash
## 1. Start a run: the response holds the run ID (data.id) and its dataset ID (data.defaultDatasetId)
curl -X POST "https://api.apify.com/v2/acts/sfoln~app-store-scraper/runs" \
  -H "Authorization: Bearer <APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"apps": ["1232780281"]}'
## 2. Repeat until data.status is SUCCEEDED (each call waits up to 60 s)
curl "https://api.apify.com/v2/actor-runs/<runId>?waitForFinish=60" -H "Authorization: Bearer <APIFY_TOKEN>"
## 3. Download the results (format=json, csv or xlsx)
curl "https://api.apify.com/v2/datasets/<defaultDatasetId>/items?format=json" -H "Authorization: Bearer <APIFY_TOKEN>"
```

Python ([apify-client](https://pypi.org/project/apify-client/)):

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("sfoln/app-store-scraper").call(run_input={"apps": ["1232780281"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

Instead of polling, you can attach a webhook to the run (see Integrations). The API tab of this page shows the same calls for JavaScript and the Apify CLI.

### Integrations

- **Make, Zapier and n8n:** run `sfoln/app-store-scraper` with the Apify app (in n8n, the Apify node) and pass the dataset items to the next step of your workflow.
- **Google Sheets:** add the items to a sheet with the Google Sheets step of Make, Zapier or n8n, or download them as CSV or Excel from the run's Storage tab or the API (`format=csv` or `format=xlsx`).
- **Webhooks:** get a POST request when a run succeeds or fails: add a webhook in the Actor's Integrations tab, or pass `webhooks` when you start a run through the API.
- **Schedules:** run it hourly, daily or weekly with the same input from Apify Schedules; every run keeps its results in its own dataset.
- **More:** Slack, Google Drive, GitHub, LangChain, LlamaIndex and other [Apify integrations](https://docs.apify.com/platform/integrations).

### Related Actors

- [Google Play Scraper – App Details & Reviews](https://apify.com/sfoln/google-play-scraper)
- [Website Contact Details Scraper](https://apify.com/sfoln/company-contacts-finder)
- [URL Metadata & Open Graph Extractor](https://apify.com/sfoln/url-metadata)
- [Brand Monitoring – X, Reddit, News & Bluesky](https://apify.com/sfoln/brand-mentions-monitor)

See [all our Actors](https://apify.com/sfoln) on Apify Store.

### FAQ

#### How much does it cost, and am I charged for failed items?

You pay per event at the prices under Pricing above, plus a run start fee of $0.00005 per GB of memory, with no subscription; platform usage is included. Errors and skipped items (`skipped_…` statuses) are never charged; a lookup that finds nothing is charged only where Pricing says so, and every record's `charged` field shows whether it was billed. Set **Maximum cost per run** to cap what a single run can spend.

#### How fresh is the data?

Each run queries its source while it runs, so you get what the source returns at that moment. Source-specific details, such as how often a provider refreshes its own database, are under Limits & notes.

#### What are the limits?

Per-run caps (for example the maximum number of items) are listed under Input, source limits under Limits & notes, and the free-plan limit under Pricing. For big batches, start the run asynchronously (see API usage) and read the dataset when it has finished.

#### Can I schedule runs or get results by webhook?

Yes. Create a schedule in Apify Console to run it hourly, daily or weekly with the same input, and add a webhook to get a POST request when a run finishes (see Integrations).

#### What does this Actor record about my runs?

This Actor records operational metrics about each run (item counts, duration, charges, error codes and a pseudonymous hash of your Apify user ID) to monitor reliability and costs. It never stores your input or results.

#### Which apps can I look up?

Any app listed in the Apple App Store: pass its numeric ID (1232780281), its bundle ID (notion.id) or its App Store URL. iPhone, iPad and Mac apps are supported; an ID that is not an app (a developer ID, a removed app) comes back as not_found and is not charged.

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

Apple's public reviews feed serves the newest (or most helpful) 500 reviews per app and country, 50 per page. To collect more, run the same app in several countries: each storefront has its own reviews.

#### Why did a search fail with a rate_limit error?

Apple throttles keyword search per IP address. The Actor spaces its calls, pauses and tries again; if Apple still refuses, the keyword ends with status error, nothing is charged, and a later run usually succeeds.

#### How do I get help?

Open an issue in the Actor's Issues tab and include the link to the run, so we can reproduce the problem. Feature requests are welcome there too.

### Limits & notes

- **Data source:** Apple's public iTunes Lookup and Search API, the App Store customer-reviews feed and Apple's RSS top charts. Data is live: what the App Store shows in that country at run time (lookups may be up to a day old, as Apple caches them).
- **Pace:** Apple allows about 20 requests per minute, so the Actor spaces its requests across the whole run. Lookups batch 50 apps per request, so 1,000 apps take about a minute; reviews come 50 per request (500 reviews of one app ≈ 30 seconds).
- **Reviews:** at most the newest (or most helpful) 500 reviews per app and country, a limit of Apple's feed. Each country has its own reviews: add countries for more. Reviews have no reviewer ID beyond the public nickname.
- **Search:** Apple throttles keyword search per IP address. A throttled keyword is retried after a pause and otherwise ends as an uncharged `error`.
- **Charts:** 10–100 entries per chart. `top-grossing` and genre charts come from Apple's iTunes RSS feeds, which also return the bundle ID, price and a short description.
- Not returned: in-app purchase lists, privacy labels, download counts or revenue (Apple does not publish them), and the app's full review history beyond 500 per country.

# Actor input Schema

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

apps: one record per app with its details. reviews: the app's customer reviews (newest 500 per country). search: apps matching each keyword. charts: top free, paid or grossing apps.

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

For the apps and reviews modes: App Store app IDs (1232780281), bundle IDs (notion.id) or App Store URLs (https://apps.apple.com/us/app/notion/id1232780281), one per line. Accounts on the Apify free plan can process up to 10 items per run (an item is one app, keyword or chart in one country).

## `searchTerms` (type: `array`):

For the search mode: keywords to search the App Store for, one per line. Results come in Apple's order with their rank.

## `charts` (type: `array`):

For the charts mode: which top charts to fetch (default top-free).

## `chartGenre` (type: `string`):

Optional, charts mode: limit the charts to one genre, by App Store genre ID (6014) or name (Games, Productivity, Finance, Health & Fitness…).

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

Two-letter App Store country codes (us, gb, de, jp…). Every app, keyword or chart is fetched in each of them. Empty: us, or the country in an App Store URL.

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

In the apps mode, also return each app's customer reviews (up to Max reviews per app, charged per review).

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

Reviews returned per app and country (1–500; Apple serves the newest or most helpful 500 at most).

## `reviewSort` (type: `string`):

mostrecent: newest reviews first. mosthelpful: the reviews other users voted most helpful.

## `maxSearchResults` (type: `integer`):

Apps returned per keyword and country (1–200).

## `chartSize` (type: `integer`):

Entries returned per chart and country (1–100).

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

Safety cap on items processed in this run (an item is one app, keyword or chart in one country); the rest is reported as dropped.

## `concurrency` (type: `integer`):

Items processed in parallel (1–10). Default: 10 for apps (lookups are batched), 2 for reviews and charts, 1 for search. Apple's rate limit applies to the whole run either way.

## `includeRaw` (type: `boolean`):

Attach Apple's unmodified JSON to each record under raw (larger output).

## Actor input object example

```json
{
  "mode": "apps",
  "apps": [
    "1232780281"
  ],
  "includeReviews": false,
  "maxReviewsPerApp": 100,
  "reviewSort": "mostrecent",
  "maxSearchResults": 50,
  "chartSize": 100,
  "maxItems": 1000,
  "includeRaw": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

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

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "apps": [
        "1232780281"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sfoln/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 = { "apps": ["1232780281"] }

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

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

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

```

## CLI example

```bash
echo '{
  "apps": [
    "1232780281"
  ]
}' |
apify call sfoln/app-store-scraper --silent --output-dataset

```

## MCP server setup

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

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

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/8zNFfwejqKHBhahBX/builds/790KGDHku5rlfhn0u/openapi.json
