# Apple App Store Scraper: App Details, Prices & Top Charts (`hridayrungta/apple-app-store-scraper`) Actor

Extract iOS app metadata from Apple's public App Store search API: name, developer, price and currency per country, category, ratings, version, release dates, size, age rating, icon, plus Top Free / Top Paid chart ranks. Search, look up by id or bundle id, or pull charts. Pay per record.

- **URL**: https://apify.com/hridayrungta/apple-app-store-scraper.md
- **Developed by:** [Hriday Rungta](https://apify.com/hridayrungta) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 app scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Apple App Store Scraper: App Details, Prices & Top Charts

Pull iOS app metadata from the **Apple App Store** into a clean, flat dataset: name, developer, price and currency in any storefront, category, rating and rating count, current version and release dates, download size, age rating, icon and App Store link, plus **Top Free / Top Paid chart ranks**. The Actor reads Apple's public JSON feeds (the iTunes Search API `search` and `lookup` endpoints and the App Store chart feeds), so results are structured and fast: no browser, no HTML parsing, no login, no API key.

Three modes:

- **Search** - run keywords against the App Store search (up to 200 apps per term per country).
- **Lookup** - fetch exact apps by numeric App Store id or bundle id, 200 per request, in one or many countries.
- **Charts** - pull the Top Free or Top Paid chart (overall or by category) and enrich every ranked app with full details.

You pay only for the records you receive ($0.50 per 1,000), and `maxItems` caps every run.

> **Not affiliated with Apple.** This is an independent tool that collects data Apple publishes through its public App Store search API. Apple, App Store and iTunes are trademarks of Apple Inc. See the disclaimer at the end.

### What it extracts

One flat record per app per storefront:

| Field | Description |
|---|---|
| `appId`, `bundleId`, `name` | Numeric App Store id, bundle identifier, app name |
| `developer`, `developerId`, `developerUrl`, `developerWebsite` | Seller business name, developer id, developer's App Store page, developer's own website |
| `price`, `currency`, `formattedPrice`, `isFree` | Storefront price (`0` for free), ISO currency, display price such as `$4.99` |
| `category`, `categoryId`, `genres[]` | Primary genre (e.g. `Games`, `6014`) and all genres |
| `rating`, `ratingCount` | Average user rating (0-5) and number of ratings, all versions |
| `currentVersionRating`, `currentVersionRatingCount` | Same for the current version |
| `version`, `versionReleaseDate`, `releaseDate` | Current version string, its release date, first release date (ISO-8601) |
| `minOs`, `sizeBytes`, `ageRating` | Minimum iOS version, download size, content rating (`4+`, `12+`, `17+`) |
| `languages[]`, `supportedDevicesCount`, `screenshotCount` | Localisations and quick size signals |
| `country` | Storefront the record was fetched from (prices and availability differ by storefront) |
| `chartFeed`, `chartRank` | `top-free` / `top-paid` and 1-based position (charts mode; `null` otherwise) |
| `url`, `iconUrl`, `scrapedAt` | App Store page, 512px icon, ISO timestamp |
| `description`, `releaseNotes` | Full description and latest release notes, only with **Include description** |

No user reviews or reviewer names are collected: the dataset contains business-level app metadata only.

### Use cases

- **ASO teams** - track the keyword landscape: which apps rank for your terms in each storefront, their ratings, update cadence and pricing.
- **App marketers and growth teams** - monitor Top Free / Top Paid charts daily, overall or per category, and catch new entrants early.
- **Competitor tracking** - look up your competitor set by bundle id every morning and diff version, price, rating count and release notes.
- **Price monitoring across countries** - one lookup across `us`, `gb`, `de`, `jp`, `in`, `br` gives you every local price and currency for the same apps.
- **Investors and analysts** - build datasets of publishers, categories, ratings and version history for market sizing and due diligence.
- **Product and data teams** - feed app catalogues, recommendation engines and AI assistants with clean, deduplicated metadata instead of scraping HTML.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | `search` / `lookup` / `charts` | `search` | What to run. |
| `searchTerms` | array | - | Keywords (search mode). One API call per term per country. |
| `appIds` | array | - | Numeric ids, `id553834731`, or App Store URLs (lookup mode). |
| `bundleIds` | array | - | Bundle identifiers such as `com.midasplayer.apps.candycrushsaga` (lookup mode). |
| `country` | string | `us` | Storefront code. Ignored when `countries` is set. |
| `countries` | array | - | Run in several storefronts, e.g. `["us","gb","de","jp"]`. Each app is saved once per storefront. |
| `chartFeed` | `top-free` / `top-paid` | `top-free` | Chart to pull (charts mode). |
| `chartGenreId` | string | - | App Store genre id for a category chart, e.g. `6014` Games, `6015` Finance, `6013` Health & Fitness. |
| `limit` | integer | `50` | Apps per search term, or chart length (max 200). |
| `includeDescription` | boolean | `false` | Add `description` and `releaseNotes`. |
| `maxItems` | integer | `500` | Hard cap on saved (and billed) records. |
| `requestsPerMinute` | integer | `18` | Throttle. Apple allows roughly 20 calls per minute per IP. |
| `lang` | string | - | Result language override, e.g. `en_us`, `ja_jp`. |
| `maxRetries` | integer | `4` | Retries with backoff for network errors, 5xx, 403 and 429. |
| `proxyConfiguration` | object | none | Optional Apify Proxy (datacenter is enough) to rotate IPs and spread the per-IP limit. |

#### Examples

Search, one storefront:

```json
{ "mode": "search", "searchTerms": ["budget tracker", "meditation"], "country": "us", "limit": 100 }
```

Competitor set, prices in six storefronts:

```json
{
  "mode": "lookup",
  "bundleIds": ["com.midasplayer.apps.candycrushsaga", "com.mojang.minecraftpe", "com.spotify.client"],
  "countries": ["us", "gb", "de", "jp", "in", "br"]
}
```

Top 100 paid games in Germany, with descriptions:

```json
{ "mode": "charts", "chartFeed": "top-paid", "chartGenreId": "6014", "country": "de", "limit": 100, "includeDescription": true }
```

### Sample output

```json
{
  "appId": "553834731",
  "bundleId": "com.midasplayer.apps.candycrushsaga",
  "name": "Candy Crush Saga",
  "developer": "King.com Limited",
  "developerId": "526656015",
  "developerUrl": "https://apps.apple.com/us/developer/king/id526656015?uo=4",
  "developerWebsite": "https://king.com",
  "price": 0,
  "currency": "USD",
  "formattedPrice": "Free",
  "isFree": true,
  "category": "Games",
  "categoryId": "6014",
  "genres": ["Games", "Puzzle", "Casual"],
  "rating": 4.71,
  "ratingCount": 3405678,
  "currentVersionRating": 4.71,
  "currentVersionRatingCount": 3405678,
  "version": "1.301.0.1",
  "versionReleaseDate": "2026-08-27T09:12:41.000Z",
  "releaseDate": "2012-11-14T14:41:32.000Z",
  "minOs": "13.0",
  "sizeBytes": 355842048,
  "ageRating": "4+",
  "languages": ["EN", "FR", "DE", "JA"],
  "supportedDevicesCount": 3,
  "country": "us",
  "chartFeed": "top-free",
  "chartRank": 2,
  "url": "https://apps.apple.com/us/app/candy-crush-saga/id553834731?uo=4",
  "iconUrl": "https://is1-ssl.mzstatic.com/image/thumb/Purple/v4/aa/512x512bb.jpg",
  "screenshotCount": 2,
  "scrapedAt": "2026-09-11T06:00:02.114Z"
}
```

Export from the Apify Console or API as JSON, CSV, Excel or XML, or push straight to Google Sheets, Airtable, Slack or a webhook with an integration.

### Recipes

**Daily Top Charts snapshot.** Create a **Schedule** (e.g. 06:00 every day) with `{"mode":"charts","chartFeed":"top-free","countries":["us","gb","de"],"limit":100}`. Each run produces 300 ranked records with full details for about $0.15. Keep the dataset per run and join on `appId` + `country` + run date to chart rank movement over time.

**Competitor change alerts.** Schedule a lookup of your competitors' bundle ids with `includeDescription: true` and send the dataset to a Google Sheet; a second sheet with `=IF(version<>previous_version, "UPDATED", "")` (or a small Make/Zapier step) flags version bumps, price changes and new release notes.

**Country price matrix.** Lookup mode with `countries` set to every storefront you sell in; pivot the CSV on `country` with `price`/`currency` as values. Free apps in one country and paid in another show up immediately.

**Keyword landscape for ASO.** Search mode with 20-50 keywords and `limit: 200`; group by `developer` to see who dominates your niche, and by `ratingCount` to estimate traction.

### Pricing

Flat pay-per-event pricing: one `app-scraped` event ($0.0005, i.e. **$0.50 per 1,000 records**) per saved record. There is no start fee and no per-request fee. `maxItems` is your hard cost cap; the run also stops as soon as your Apify "max total charge" limit is reached. Records de-duplicated within a run (same app in the same storefront) are free. Charts mode makes one extra lookup call per 200 ranked apps to enrich them, at no extra charge.

### FAQ

**Do I need an Apple developer account or API key?**
No. The search, lookup and chart feeds are public and unauthenticated. This Actor never logs in.

**Is this legal?**
The Actor uses the iTunes Search API that Apple documents for public use, at a request rate within Apple's published guidance (about 20 calls per minute per IP). Apple asks that content from the API link back to the App Store, which is why every record carries its `url`. Icon URLs are promotional artwork licensed by Apple for promoting store content; do not reuse them for other purposes. This Actor is not affiliated with, endorsed by or operated by Apple.

**Why are ratings or prices different from what I see on my phone?**
Ratings, prices, currency and even availability are per storefront. Set `country` (or `countries`) to the storefront you care about; the `country` field tells you which one each record came from.

**Why did an app come back thin, with `null` rating and version, in charts mode?**
The chart feed listed an app that the lookup endpoint did not return for that storefront (delisted, region-locked or a momentary inconsistency). The rank, name, developer and link are still saved so the chart stays complete.

**Can I get user reviews or reviewer names?**
No. Reviews are out of scope by design; only business-level app metadata is collected.

**How many apps can a search return?**
Apple caps a search at 200 results per term. Use several more specific terms, or run the same terms in more storefronts, to widen coverage.

**What is the maximum chart length?**
200 for Top Free / Top Paid (overall or per category). Category charts and lengths above 100 are served from Apple's legacy RSS chart feed; the Actor switches automatically.

**What happens on rate limits or errors?**
Requests are spaced by `requestsPerMinute` (default 18). If Apple still answers 403 or 429, the Actor backs off exponentially and, when a proxy is configured, rotates to a fresh IP. 5xx and network errors are retried up to `maxRetries` times.

### Disclaimer

Data is obtained from Apple's public App Store search API and chart feeds. This Actor is an independent project and is **not affiliated with, endorsed by or sponsored by Apple Inc.** Apple, App Store, iTunes and the Apple logo are trademarks of Apple Inc., registered in the U.S. and other countries. Per Apple's API terms, please keep the App Store link (`url`) alongside any data you display, treat icon and screenshot URLs as promotional artwork for promoting App Store content only, and stay within Apple's rate guidance. You are responsible for how you use the data.

### Local development

```bash
npm install
npm test                  # offline unit tests against documented fixtures
APIFY_LOCAL_STORAGE_DIR=$PWD/storage node src/main.js
```

# Actor input Schema

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

`search` runs each of **Search terms** against the App Store search API (up to 200 apps per term per country). `lookup` fetches exact apps by **App IDs** and/or **Bundle IDs** (200 per request). `charts` pulls the Top Free or Top Paid chart for each country and enriches every ranked app with full details.

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

Keywords to search, one per line (search mode). Each term costs one API call per country and returns up to **Limit** apps.

## `appIds` (type: `array`):

Numeric App Store ids (lookup mode), one per line. `553834731`, `id553834731` and full URLs such as `https://apps.apple.com/us/app/candy-crush-saga/id553834731` are all accepted. Batched 200 per request.

## `bundleIds` (type: `array`):

Bundle identifiers (lookup mode), one per line, e.g. `com.midasplayer.apps.candycrushsaga`. Batched 200 per request; falls back to one-by-one lookups if Apple rejects the batch.

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

ISO 3166-1 alpha-2 storefront code, e.g. `us`, `gb`, `de`, `jp`, `in`, `br`. Prices, currency, availability and ranks are per storefront. Ignored when **Countries** is filled in.

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

Run the same search / lookup / chart in several storefronts, one code per line (e.g. `us`, `gb`, `de`, `jp`). Each app is saved once per storefront with its local price and currency - ideal for price comparison. Leave empty to use **Country**.

## `chartFeed` (type: `string`):

Which chart to pull in charts mode.

## `chartGenreId` (type: `string`):

Optional App Store genre id to get a category chart instead of the overall chart (charts mode). Common ids: 6014 Games, 6000 Business, 6017 Education, 6016 Entertainment, 6015 Finance, 6023 Food & Drink, 6013 Health & Fitness, 6012 Lifestyle, 6020 Medical, 6011 Music, 6010 Navigation, 6009 News, 6021 Magazines & Newspapers, 6008 Photo & Video, 6007 Productivity, 6006 Reference, 6024 Shopping, 6005 Social Networking, 6004 Sports, 6003 Travel, 6002 Utilities, 6001 Weather, 6018 Books, 6027 Graphics & Design, 6026 Developer Tools; game sub-genres 7001-7019 (7012 Puzzle, 7017 Strategy, ...). Category charts come from Apple's legacy RSS feed.

## `limit` (type: `integer`):

Search mode: apps per search term per country (max 200). Charts mode: chart length (max 200; above 100 or with a genre the legacy feed is used). Ignored in lookup mode.

## `includeDescription` (type: `boolean`):

Add the full App Store description and latest release notes to every record (no extra API calls; makes records much larger).

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

Stop after this many records have been saved. This is also your cost cap: you are billed once per saved record.

## `requestsPerMinute` (type: `integer`):

Throttle for calls to Apple (1-60). Apple documents roughly 20 calls per minute per IP for the search API; 18 is a safe default without a proxy. Go higher only with a rotating proxy.

## `lang` (type: `string`):

Optional result language override, e.g. `en_us` or `ja_jp`. By default Apple returns the storefront's language.

## `maxRetries` (type: `integer`):

Retries with exponential backoff for network errors, 5xx, 403 and 429 responses before a request is given up.

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

Optional. Apple's feeds are public and work without a proxy at <= 18 requests/minute. Enable Apify Proxy (datacenter is enough) to rotate IPs on 403/429 and spread the per-IP limit.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [
    "budget tracker",
    "meditation"
  ],
  "appIds": [],
  "bundleIds": [],
  "country": "us",
  "countries": [],
  "chartFeed": "top-free",
  "limit": 50,
  "includeDescription": false,
  "maxItems": 100,
  "requestsPerMinute": 18,
  "maxRetries": 4,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {
    "mode": "search",
    "searchTerms": [
        "budget tracker",
        "meditation"
    ],
    "appIds": [],
    "bundleIds": [],
    "country": "us",
    "countries": [],
    "limit": 50,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("hridayrungta/apple-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 = {
    "mode": "search",
    "searchTerms": [
        "budget tracker",
        "meditation",
    ],
    "appIds": [],
    "bundleIds": [],
    "country": "us",
    "countries": [],
    "limit": 50,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("hridayrungta/apple-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 '{
  "mode": "search",
  "searchTerms": [
    "budget tracker",
    "meditation"
  ],
  "appIds": [],
  "bundleIds": [],
  "country": "us",
  "countries": [],
  "limit": 50,
  "maxItems": 100
}' |
apify call hridayrungta/apple-app-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hridayrungta/apple-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/m9MQRJytZFJDwrq9h/builds/gUlZGmBTmQ55d5TYz/openapi.json
