# App Store Top Charts Scraper: iOS App Rankings by Country (`glitchbound/app-charts-scraper`) Actor

Track App Store rankings: top 100 apps by country, top charts by country and category rankings on iPhone and iPad, daily. Top free apps, top paid apps, top grossing apps, top games and new apps, with rank, rating, developer, price. An ASO app rank tracker with rank changes since your last run.

- **URL**: https://apify.com/glitchbound/app-charts-scraper.md
- **Developed by:** [glitchbound](https://apify.com/glitchbound) (community)
- **Categories:** Developer tools, E-commerce, Automation
- **Features:** Limited permissions
- **Stats:** 10 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 charting apps

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/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

## App Store Top Charts Scraper: Rankings by Country

Track **App Store rankings**: Top Free, Top Paid and Top Grossing, for any country, any category, iPhone or iPad.

Built on **Apple's own public chart feeds**, so results are stable rather than scraped out of a rendered page.

Also an **App Store app scraper**: give it `appIds` (App Store ids, bundle ids or URLs) and it returns each app in full, with rating and rating count, price, version, size, description and screenshots, from Apple's own lookup.

### What moved since yesterday

Every row also says where the app stood **the last time your account read
that chart**: `previousRank`, `rankChange` (positive means it climbed) and
`newInChart`. Schedule the run daily and the dataset is a rank tracker, not a
snapshot: the apps that jumped, the ones that fell and the ones that just
entered, with `previousChartedAt` saying when "last time" was. The previous
read is kept in a key-value store in your own account
(`app-store-charts-history`); turn it off with `trackRankChanges: false`.

### Built to be scheduled

Rankings are only interesting *over time*. Schedule this daily and you get a rank history you can chart: who's climbing, who's collapsing, who just entered the top 10.

Each row carries a `chartedAt` timestamp so consecutive runs stack into a time series with no extra work.

### Compare markets in one run

Pass several countries and it returns them all together:

```json
{
  "countries": ["us", "gb", "de", "jp"],
  "charts": ["top-free", "top-grossing"],
  "categories": ["games"],
  "limit": 100
}
```

That's 8 charts in one run, the same category across four markets, free vs grossing side by side.

### Do you need an API key? No. Is there a free tier? Yes.

Measured, nobody searches `app store top charts api`. What people actually type
is `app store charts us`, `app store charts by country` and
`app store ranking tracker`: the thing, not the interface to it.

So, plainly:

- **No API key.** Apple publishes these charts as a public RSS feed with no key
  and no login. Nothing to register for, nothing to rotate.
- **No proxy setup.** Apple does not bot-wall datacenter addresses.
- **Pay per result, not per month.** No subscription, no minimum, and rows your
  filters drop are not charged.
- **Free to try.** Run the prefilled input and see real rows first.

### What you get per app

`rank` · `title` · `developer` · `appId` · `bundleId` · `price` + `currency` · `isFree` · `genre` · `releaseDate` (ISO) · `releaseDateText` · `icon` · `url` · `summary` · `country` · `chart` · `category` · `chartedAt`

With `includeDetails`: `rating` · `ratingCount` · `version` · `updatedAt` · `sizeBytes` · `contentRating` · `minimumOsVersion` · `sellerUrl` · `genres`. One extra request per country covers every chart in it, so a 100-app chart gains a star rating and rating count on every row for one call.

### App details by id, bundle id or URL

Add `appIds` and the run looks up **any App Store app in full**, from Apple's
own lookup service: give it the app's id (`310633997`), its bundle id
(`net.whatsapp.WhatsApp`) or paste the App Store address. One row per app and
country.

```json
{ "appIds": ["479516143", "net.whatsapp.WhatsApp", "https://apps.apple.com/us/app/calm/id571800810"],
  "countries": ["us", "de"], "charts": [] }
```

```json
{
  "rowType": "app",
  "country": "US",
  "appId": "479516143",
  "bundleId": "com.mojang.minecraftpe",
  "title": "Minecraft: Play with Friends!",
  "developer": "Mojang",
  "genre": "Games",
  "rating": 4.51,
  "ratingCount": 845528,
  "price": 6.99,
  "currency": "USD",
  "version": "26.62",
  "updatedAt": "2026-11-04T20:19:36Z",
  "sizeBytes": 1347817472,
  "contentRating": "9+",
  "minimumOsVersion": "14.0",
  "languages": ["DA", "NL", "EN", "FI", "..."],
  "screenshots": ["https://is1-ssl.mzstatic.com/image/thumb/...", "..."]
}
```

- **Also on every app row**: `summary` (the full description), `recentChanges`
  (What's new), `releaseDate`, `developerId`, `developerUrl`, `sellerName`,
  `sellerUrl`, `genres`, `ipadScreenshots`, `icon` (512 px) and `url`.
- **Same names as a chart row.** Checked on 75 charting apps on 2026-11-07:
  title, developer, bundle id, price, currency, genre and genre id matched their
  chart rows, and so did the description (one differed only in line endings).
- **Price, name and availability per country**: each app is looked up once for
  every country in `countries` (Minecraft is "Minecraft: Play with Friends!" in
  the US and "Minecraft" in Germany).
- **One request per 150 apps per country**, so a list of 500 apps in one
  country takes four requests.
- **A URL and the bare id are one app**, read and billed once. A value that is
  neither an id nor a bundle id, and an app Apple does not list in a country,
  each come back as an **unbilled** error row.
- **Leave `charts` empty to read only these apps.** Up to 1,000 apps a run.

### Use cases

- **ASO & competitor tracking**: watch rivals enter or fall out of the charts
- **Market research**: see what's winning in Japan that hasn't reached the US yet
- **Trend spotting**: catch a breakout app while it's still climbing
- **Publisher intel**: find which studios dominate a category
- **Investment / diligence**: track a portfolio app's rank daily

### Options

- **Charts**: Top Free, Top Paid, Top Grossing (iPhone), plus iPad Free/Paid
- **Categories**: all 24 App Store categories, or the overall chart
- **Countries**: any App Store storefront
- **Limit**: up to 100 ranked apps per chart (Apple's maximum)
- **App details**: `includeDetails` adds star rating, rating count, version, last update, size and age rating to every row
- **Apps**: `appIds` looks up any app in full by id, bundle id or App Store URL, see App details by id, bundle id or URL above

### Storefront coverage

The country goes straight into Apple's feed URL, so **any iOS App Store
storefront works**, not a fixed list. The codes are ISO two-letter and
lowercase.

The ones people ask for most:

| | |
|---|---|
| Americas | `us` `ca` `br` `mx` `ar` `cl` |
| Europe | `gb` (UK) `de` `fr` `it` `es` `nl` `se` `pl` `tr` `ru` |
| Asia-Pacific | `jp` `cn` (China) `kr` `in` (India) `au` `sg` `hk` `tw` `id` `th` `vn` |
| Middle East / Africa | `il` `ae` `sa` `eg` `za` |

Pass several at once and every country runs in the same job, so a
**UK / India / China top-charts comparison** is one run rather than three.

`gb` is the code for the United Kingdom, not `uk`. Apple rejects `uk`, and the
Actor returns an unbilled error row naming the country rather than silently
giving you nothing.

### Chart and category reference

**Charts** map to Apple's own iOS RSS feeds:

| Input | Apple feed | Device |
|---|---|---|
| `top-free` | `topfreeapplications` | iPhone |
| `top-paid` | `toppaidapplications` | iPhone |
| `top-grossing` | `topgrossingapplications` | iPhone |
| `top-free-ipad` | `topfreeipadapplications` | iPad |
| `top-paid-ipad` | `toppaidipadapplications` | iPad |
| `top-grossing-ipad` | `topgrossingipadapplications` | iPad |
| `new` | `newapplications` | what launched, all |
| `new-free` | `newfreeapplications` | what launched, free |
| `new-paid` | `newpaidapplications` | what launched, paid |

**Categories**: `all`, `games`, `business`, `education`, `entertainment`,
`finance`, `food-drink`, `health-fitness`, `lifestyle`, `medical`, `music`,
`navigation`, `news`, `photo-video`, `productivity`, `reference`, `shopping`,
`social-networking`, `sports`, `travel`, `utilities`, `weather`, `books`,
`developer-tools`, `graphics-design`.

### Notes

- **Mac App Store is not included.** Apple serves a Top Free Mac Apps feed in the same format, but its Top Paid and Top Grossing Mac feeds come back empty (checked 2026-10-26), so the Mac is left out rather than offered as one chart of three.
- **Google Play is a separate Actor.** [Google Play Top Charts Scraper](https://apify.com/glitchbound/google-play-charts-scraper) reads the chart data the Play Store itself shows: Top Free, Paid, Grossing, Trending and Top New, 130 countries, in the same row shape as this one.
- Rows with an `error` field name the exact country/chart that failed. **They are never charged.**
- Public chart data only, no accounts, no logins, no personal data.

### The rest of this set

- **Quick start on GitHub**: [danielhagever/app-store-top-charts](https://github.com/danielhagever/app-store-top-charts), a ready `curl`, a standard-library Python script that writes a CSV, and the MCP setup
  Six Actors over the same two stores, each answering a different question:

- **[App Store & Google Play Scraper](https://apify.com/glitchbound/app-store-scraper)**: the app itself: ratings, price, metadata

- **[App Store & Google Play Reviews Scraper](https://apify.com/glitchbound/app-reviews-scraper)**: every review for an app, both stores

- **[App Store Developer Portfolio Scraper](https://apify.com/glitchbound/app-developer-scraper)**: every app one publisher has shipped

- **[Google Play Top Charts Scraper](https://apify.com/glitchbound/google-play-charts-scraper)**: Top Free, Paid, Grossing, Trending and Top New on Google Play, 130 countries, with rank changes since the last run

- **[ASO Keyword Rank Tracker](https://apify.com/glitchbound/aso-keyword-rank-tracker)**: where any app ranks for any keyword in both stores, plus each store's keyword ideas

The three `new-*` charts answer what LAUNCHED rather than what is winning, which is the question app-market research usually opens with. Apple ignores the row limit on those three and returns about a hundred whatever you ask for, so this Actor truncates to your own limit rather than billing you for Apple's.

### FAQ

**How do I track App Store rankings daily?** Schedule this Actor once a day with the countries, charts and categories you follow. Each row says where the app stood at your previous run (`previousRank`), how far it moved (`rankChange`, positive is up) and whether it is `newInChart`, so the daily dataset is already a rank tracker.

**Is there an official App Store top charts API?** Apple publishes its top charts as public feeds (the iTunes RSS charts), and this reads exactly those, 100 apps a chart, any storefront. No key and no login.

**Can I scrape one specific App Store app?** Yes: put its id, bundle id or App Store URL in `appIds` and leave `charts` empty. Each app comes back as one row per country with rating and rating count, price, version, size, age rating, description, What's new, languages and screenshots, from Apple's own lookup.

**Can I get ratings too?** Yes: `includeDetails` adds the star rating, rating count, version, last update and size to every row, from Apple's own lookup, one request per country.

### Use it from an AI agent

This Actor is a ready-made tool for Claude, ChatGPT, Cursor or any other MCP
client, through Apify's MCP server. Add it as a connector at:

```
https://mcp.apify.com?tools=glitchbound/app-charts-scraper
```

In Cursor or VS Code the same address goes in `mcp.json`:

```json
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=glitchbound/app-charts-scraper" } } }
```

The first call asks you to sign in to Apify, or takes an API token. From then
on the agent sees this Actor's input fields and calls it directly.

### Feedback

If this saved you time, a review on the Actor's Store page helps other people
find it. If something is missing or wrong, the Issues tab on the same page is
the fastest way to reach me, and it gets read.

# Actor input Schema

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

Two-letter App Store country codes, one per line (us, gb, de, jp, il...). Add several to compare the same chart across markets in one run.

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

Which chart(s) to pull. The top charts rank what is winning now; the three 'new' charts list what launched recently, which Apple publishes as its own feed. Note that Apple ignores the row limit on the new charts and returns about a hundred, so this Actor truncates to your limit itself. Leave empty when you only want app details (appIds); with no apps either, Top Free (iPhone) is read.

## `categories` (type: `array`):

App Store categories. Use "all" for the overall chart.

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

How many ranked apps to return per chart (Apple serves up to 100).

## `includeDetails` (type: `boolean`):

Add each app's star rating, rating count, version, last update date, size, age rating, minimum iOS version and seller website. One extra request per country covers every chart in it.

## `trackRankChanges` (type: `boolean`):

Compare each chart with the last time your account read it, and add previousRank, rankChange (positive = moved up) and newInChart to every row. The last read is kept in a key-value store in your own account, named app-store-charts-history. Schedule the run daily and every row says what moved.

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

One per line: the app's id (310633997, the number after 'id' in its App Store address), its bundle id (net.whatsapp.WhatsApp) or the App Store URL. Each app is read once for every country above, since price, currency, name and availability differ by country. Leave Charts empty to read only these apps.

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

Proxy settings.

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

A hard ceiling on rows for the entire run, across every target. The per-target limits above cap each one separately, so fifty targets at twenty each is still a thousand rows; this caps the total. The run stops cleanly when it is reached and nothing beyond that point is fetched or charged. Leave empty for no ceiling.

## Actor input object example

```json
{
  "countries": [
    "us"
  ],
  "charts": [
    "top-free"
  ],
  "categories": [
    "all"
  ],
  "limit": 50,
  "includeDetails": false,
  "trackRankChanges": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Top Free, Paid and Grossing chart positions by country and category.

# 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"
    ],
    "charts": [
        "top-free"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("glitchbound/app-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"],
    "charts": ["top-free"],
}

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

```

## MCP server setup

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