# App Store Top Charts Scraper (`renzomacar/app-store-top-charts-scraper`) Actor

Scrape App Store top charts: free, paid, grossing and new, for iPhone and iPad, in any country and any category. No API key. Optional rating enrichment.

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

## Pricing

from $0.80 / 1,000 chart entries

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

## App Store Top Charts Scraper - Free, Paid & Grossing

Pull the Apple App Store top charts as structured data: Top Free, Top Paid, Top Grossing, the iPad versions of each, and the New Apps feeds - for any country storefront and any App Store category. No API key, no developer account, no proxy. One row per ranked app, with its position, publisher, category, price and store URL, and optionally its rating, current version and file size.

The charts come from Apple's public RSS feeds, which answer `HTTP 200` anonymously. Every chart type and every genre-filtered feed in this actor was verified live before the parser was written.

### What you get per ranked app

| Field | What it holds |
|---|---|
| `rank` | Position in the chart, 1 upward |
| `chart` | Which chart this row came from |
| `country` | Storefront |
| `genreId` | Category filter used, or `null` for the overall chart |
| `appId` | Numeric App Store ID |
| `appName` | App title as shown in the chart |
| `developer` | Publisher name |
| `developerUrl` | Publisher's App Store page |
| `category` / `categoryId` | The app's own primary category |
| `price` / `currency` / `priceFormatted` | Price in the storefront's currency |
| `releaseDate` | ISO 8601 |
| `iconUrl` | Highest resolution icon the feed carries |
| `appUrl` | Direct store link |
| `summary` | Apple's description text for the app |
| `scrapedAt` | Collection timestamp |

With `enrich: true` the following are added by a batched lookup against Apple's metadata endpoint. On a live run they attached to **40 of 40** delivered rows:

`averageUserRating`, `userRatingCount`, `version`, `currentVersionReleaseDate`, `fileSizeMb`, `contentRating`.

### The real ceiling, and the right way to get volume

Apple's chart feed **clamps at about 100 entries**. Requesting `limit=200` still returns 99 rows. Any tool promising the "top 500" from this source is describing something the source does not serve.

The volume is not in a bigger `limit`. It is in the multiplication:

```
charts x categories x countries
```

Nine chart types, dozens of App Store categories and 175 storefronts. Six charts across ten categories in five countries is 300 feeds and up to roughly 30,000 ranked rows, all from one run. That is also where the *useful* data lives: nobody is breaking into the overall US Top Free chart, but the per-category charts are reachable, and a category chart in a mid-size storefront is a real, winnable ranking.

### Input

```json
{
  "countries": ["us", "gb", "de", "jp", "br"],
  "chartTypes": ["topfreeapplications", "topgrossingapplications"],
  "genreIds": ["6014", "6013", "6017"],
  "limit": 100,
  "enrich": true,
  "maxItems": 5000
}
```

#### Chart types

| Value | Chart |
|---|---|
| `topfreeapplications` | Top Free, iPhone |
| `toppaidapplications` | Top Paid, iPhone |
| `topgrossingapplications` | Top Grossing, iPhone |
| `topfreeipadapplications` | Top Free, iPad |
| `toppaidipadapplications` | Top Paid, iPad |
| `topgrossingipadapplications` | Top Grossing, iPad |
| `newapplications` | New Apps |
| `newfreeapplications` | New Free Apps |
| `newpaidapplications` | New Paid Apps |

Short aliases work too: `free`, `paid`, `grossing`, `new`, `topFree`, `top_paid` and similar are mapped to the correct feed. An unrecognised chart name is recorded in `FAILURES` with the list of valid values, and the rest of the run continues.

#### Category IDs

Leave `genreIds` empty for the overall chart. Add IDs for per-category charts:

| ID | Category | ID | Category |
|---|---|---|---|
| 6014 | Games | 6015 | Finance |
| 6017 | Education | 6012 | Lifestyle |
| 6013 | Health & Fitness | 6008 | Photo & Video |
| 6007 | Productivity | 6002 | Utilities |
| 6005 | Social Networking | 6000 | Business |
| 6016 | Travel | 6023 | Food & Drink |
| 6018 | Books | 6020 | Medical |
| 6011 | Music | 6021 | Newsstand |
| 6004 | Sports | 6003 | Weather |

**Input aliases.** `chartTypes` also accepts `charts`, `chart`, `chartType` and `feeds`. `genreIds` also accepts `genreId`, `categories`, `categoryIds` and `genres`. `countries` also accepts `country`, `countryCodes` and `storefronts`. `maxItems` also accepts `maxResults` and `maxRows`. Comma separated strings work anywhere a list does.

### Top Grossing is the chart that tells you about money

Top Free tells you about install volume. Top Grossing tells you about revenue, and it is the chart most competitive research should start from. An app sitting high in Top Grossing while absent from Top Free is monetising a small audience extremely well - that is a business model worth studying. The inverse, high in Free and invisible in Grossing, is a growth story with no revenue engine attached yet.

Pull both charts in the same run and join on `appId` to see the gap directly.

### Tracking chart movement over time

Schedule the actor daily with a fixed chart, category and country set. Each run stamps `scrapedAt`, so consecutive datasets diff into a rank movement table: who entered the chart, who fell out, who is climbing. For a category you compete in, the entrants are your new competitors before they are on anyone's radar.

### Finding market gaps by category and country

Run one category across twenty countries. Apps that rank in the US but are missing from the German or Brazilian chart in the same category are either not localised or not launched there. That gap list is a market entry brief that took one actor run to produce.

The New Apps feeds do a related job: they surface what is being launched into a category right now, which is a leading indicator of where a category is heading.

### Enrichment: what it adds and what it costs

`enrich: true` runs a batched metadata lookup over the ranked app IDs, up to 50 apps per HTTP call, and attaches rating average, rating count, current version, last update date, file size and content rating. On a verified run it matched 40 of 40 rows.

This is what turns a ranking into an analysis. A chart position next to `userRatingCount` shows you whether an app is riding a long-accumulated reputation or is genuinely new and hot. Next to `currentVersionReleaseDate` it shows you which top-charting apps have quietly stopped shipping.

Enrichment is billed as a separate event, and only for rows that both landed in the dataset **and** actually gained the extra fields.

### How this actor behaves when something goes wrong

1. **Errors never enter the dataset.** A chart that comes back empty, an unknown chart name, a storefront that is temporarily unavailable - each is recorded in a `FAILURES` key-value record with the exact reason. None become dataset rows, because a row that says "error" would bill you for receiving an error.
2. **A run that delivered nothing is marked FAILED**, not SUCCEEDED.
3. **Transient store errors are retried.** Apple's chart feed occasionally answers `HTTP 502`; the actor retries with backoff before recording a failure.
4. **The free tier returns data.** Proxy is optional and off by default.

### Pricing

Pay per event.

- **$0.0002 per chart entry delivered** - $0.20 per 1,000 ranked rows.
- **$0.0004 per enriched entry**, charged only when `enrich` is on and only for rows that gained data.

No subscription, no charge for starting a run. `maxItems` is a hard ceiling on both rows and spend.

A full six-chart, ten-category, five-country sweep capped at 5,000 rows costs $1.00 without enrichment, $3.00 with it.

### Output sample

```json
{
  "rank": 1,
  "chart": "topfreeapplications",
  "country": "us",
  "genreId": null,
  "appId": "6448311069",
  "appName": "ChatGPT",
  "developer": "OpenAI OpCo, LLC",
  "developerUrl": "https://apps.apple.com/us/developer/openai-opco-llc/id1684349733?uo=2",
  "category": "Productivity",
  "categoryId": "6007",
  "price": 0,
  "currency": "USD",
  "priceFormatted": "Free",
  "releaseDate": "2023-05-18T00:00:00.000Z",
  "iconUrl": "https://is1-ssl.mzstatic.com/image/thumb/.../100x100bb.png",
  "appUrl": "https://apps.apple.com/us/app/chatgpt/id6448311069?uo=2",
  "averageUserRating": 4.8303,
  "userRatingCount": 9552259,
  "version": "1.2026.224",
  "currentVersionReleaseDate": "2026-08-22T01:20:24.000Z",
  "fileSizeMb": 312.44,
  "contentRating": "12+",
  "scrapedAt": "2026-08-22T04:16:40.201Z"
}
```

### Dataset views

- **Ranking** - position, chart, country, app, developer, category, price. The clean leaderboard.
- **With ratings** - position plus rating, rating count, version and last update. The analysis view, populated when `enrich` is on.

### Frequently asked questions

**How deep do the charts go?** About 100 entries per chart, per category, per country. That is Apple's limit on this feed, not the actor's. Use categories and countries to multiply.

**Do I need an API key or a developer account?** Neither. These are public feeds.

**Which countries work?** Any two letter iTunes storefront. `us`, `gb`, `de`, `jp`, `br`, `in`, `pe` and `au` were each verified.

**Is Top Grossing real revenue data?** It is Apple's own revenue-based ordering. It is not dollar amounts - no public source gives those - but the ordering is Apple's, not an estimate.

**Can I get iPad charts?** Yes, the three `...ipadapplications` chart types.

**Why did I get 99 rows when I asked for 100?** Apple's feed does that. The actor reports what it received rather than padding.

### Related actors

- **App Store Search Scraper** - keyword to ranked apps, up to 200 results.
- **ASO Keyword Rank Tracker** - where a specific app sits for a specific keyword.
- **App Store App Details Scraper** - full metadata including in-app purchase prices.
- **App Store Reviews Scraper** - customer reviews across every storefront.

# Actor input Schema

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

Two letter iTunes storefronts. One row per app per chart per country. Aliases: country, countryCodes.

## `chartTypes` (type: `array`):

Which charts to pull. Each one is a separate Apple feed with a different app set.

## `genreIds` (type: `array`):

Leave empty for the overall chart. Add App Store genre IDs to get the per-category chart, which is where the reachable rankings actually live. 6014 Games, 6017 Education, 6013 Health & Fitness, 6015 Finance, 6012 Lifestyle, 6008 Photo & Video, 6002 Utilities, 6007 Productivity, 6005 Social Networking, 6000 Business.

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

Apple clamps this feed at about 100 entries, so 100 is the real ceiling per chart, per category, per country.

## `enrich` (type: `boolean`):

Runs a batched iTunes lookup on the ranked apps to attach rating average, rating count, current version, release date and file size. Costs one extra event per enriched row.

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

Hard ceiling on rows delivered and therefore on what you are charged.

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

Not required.

## Actor input object example

```json
{
  "countries": [
    "us"
  ],
  "chartTypes": [
    "topfreeapplications",
    "topgrossingapplications"
  ],
  "genreIds": [],
  "limit": 100,
  "enrich": false,
  "maxItems": 500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per app position in the chart, with the full app record attached.

# 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 = {
    "countries": [
        "us"
    ],
    "chartTypes": [
        "topfreeapplications",
        "topgrossingapplications"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("renzomacar/app-store-top-charts-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 = {
    "countries": ["us"],
    "chartTypes": [
        "topfreeapplications",
        "topgrossingapplications",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("renzomacar/app-store-top-charts-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 '{
  "countries": [
    "us"
  ],
  "chartTypes": [
    "topfreeapplications",
    "topgrossingapplications"
  ]
}' |
apify call renzomacar/app-store-top-charts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,renzomacar/app-store-top-charts-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/NRYZN4PjQooK1W7bu/builds/pEwmKlV2rqX70N8we/openapi.json
