App Store Rankings Scraper: Top Charts by Country avatar

App Store Rankings Scraper: Top Charts by Country

Pricing

from $1.50 / 1,000 ranking scrapeds

Go to Apify Store
App Store Rankings Scraper: Top Charts by Country

App Store Rankings Scraper: Top Charts by Country

Scrape Apple App Store top charts: rankings by category, country and chart type, with app metadata, publisher and price. Track rank movement over time.

Pricing

from $1.50 / 1,000 ranking scrapeds

Rating

0.0

(0)

Developer

Arman Hossain

Arman Hossain

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

5 hours ago

Last modified

Share

App Store Rankings — Top free, paid and grossing charts for every storefront and every category

App Store Rankings Scraper pulls Apple's top free, top paid and top grossing charts for any storefront and any App Store category, rank, app name, publisher, price, currency, category, release date, icon and the full store description.

Every combination of country × chart type × category is fetched as its own chart, so one run can cover a dozen markets at once. No proxy setup, no browser, no credentials to manage.

What you get

Output fieldMeaning
countryStorefront the chart came from, e.g. us, gb
chartTypetopfree, toppaid or topgrossing
categoryIdApple genre ID requested, or null for the overall chart
rankPosition in that chart, 1-based
appIdApple's numeric app ID, your join key across runs
appNameApp name as it appears in the store
publisherDeveloper / seller name
price, currencyNumeric price and the storefront's currency (0 + USD for free apps)
categoryThe app's own primary category, which can differ from the chart you pulled
releaseDateFirst release date, ISO 8601 with the store's timezone offset
iconUrlHighest-resolution icon Apple ships in the feed (100×100)
summaryFull store description text
rightsCopyright line
scrapedAtRun timestamp, the field you diff on to measure rank movement

A RUN_SUMMARY record in the key-value store holds per-run counts, per-chart counts, the filters applied and any chart that failed.

Input

FieldTypeDefaultNotes
countriesarray["us"]Two-letter storefront codes, lowercase. An unknown code returns HTTP 400 and is recorded as a failure without stopping the run.
chartTypesarray["topfree"]Any of topfree, toppaid, topgrossing. An unrecognised value fails validation up front.
categoryIdsarray[]Apple genre IDs. Empty = the overall chart.
limitinteger100Chart depth. Capped at 200, though Apple currently truncates at ~100.

Which combinations make sense

  • The run fetches the full cross product: 4 countries × 3 chart types × 2 categories is 24 requests and up to 2,400 records. Size limit accordingly.
  • topgrossing is the most useful signal for revenue tracking; topfree moves fastest day to day.
  • categoryIds is where breakout detection lives, a new entrant at rank 40 in Games is far more informative than rank 400 overall.

Common category IDs: 6014 Games · 6015 Finance · 6016 Entertainment · 6017 Education · 6018 Books · 6020 Medical · 6023 Food & Drink · 6002 Utilities · 6005 Social Networking · 6008 Photo & Video · 6012 Lifestyle.

Example input

{
"countries": ["us", "gb"],
"chartTypes": ["topfree", "toppaid"],
"categoryIds": ["6014"],
"limit": 25
}

Output

A real record from the run above:

{
"country": "us",
"chartType": "topfree",
"categoryId": "6014",
"rank": 1,
"appId": "6748084174",
"appName": "Smash Fest!",
"publisher": "Flow Games Bilisim Yazilim ve Pazarlama Anonim Sirketi",
"price": 0,
"currency": "USD",
"category": "Games",
"releaseDate": "2025-12-16T00:00:00-07:00",
"iconUrl": "https://is1-ssl.mzstatic.com/image/thumb/Purple221/v4/74/15/3a/74153a85-8436-259e-5297-63fbd718af84/AppIcon-0-0-1x_U007emarketing-0-8-0-85-220.png/100x100bb.png",
"summary": "Welcome to Smash Fest! Get ready for the most explosive festival in town! …",
"rights": "© Flow Games 2025",
"scrapedAt": "2026-08-06T11:31:55.000Z"
}

Prices come back in the storefront's own currency, so the same app on the GB chart reads:

{
"country": "gb",
"chartType": "toppaid",
"rank": 1,
"appId": "479516143",
"appName": "Minecraft: Dream it, Build it!",
"publisher": "Mojang",
"price": 6.99,
"currency": "GBP"
}

RUN_SUMMARY:

{
"chartsRequested": 6,
"chartsFailed": 2,
"failures": [
{ "chart": "zz/topfree/6014", "error": "no such chart, check country \"zz\" (HTTP 400)" },
{ "chart": "zz/toppaid/6014", "error": "no such chart, check country \"zz\" (HTTP 400)" }
],
"appsSaved": 100,
"appsPerChart": {
"us/topfree/6014": 25,
"us/toppaid/6014": 25,
"gb/topfree/6014": 25,
"gb/toppaid/6014": 25
},
"filters": {
"countries": ["us", "gb", "zz"],
"chartTypes": ["topfree", "toppaid"],
"categoryIds": ["6014"],
"limit": 25
},
"finishedAt": "2026-08-06T11:31:55.771Z"
}

Use cases

1. Track your app's rank daily. Schedule a run in the categories and storefronts you care about, then filter the dataset to your appId and plot rank against scrapedAt.

{
"countries": ["us", "gb", "de", "jp", "br"],
"chartTypes": ["topfree", "topgrossing"],
"categoryIds": ["6014"],
"limit": 100
}

2. Competitive ASO monitoring. Pull the paid and grossing charts for a category and watch which publishers gain positions week over week. summary gives you their live store copy for keyword analysis.

{
"countries": ["us"],
"chartTypes": ["toppaid", "topgrossing"],
"categoryIds": ["6015", "6017", "6023"],
"limit": 100
}

3. Spot breakout apps early. Diff consecutive runs on appId: an app that appears in a category chart for the first time, or jumps more than ~20 places, is a breakout candidate. releaseDate separates new apps from re-surging old ones.

{
"countries": ["us"],
"chartTypes": ["topfree"],
"categoryIds": ["6014", "6005", "6008"],
"limit": 100
}

Limits and behaviour

  • Charts are already ranked. rank is the app's position in the feed as Apple ordered it, the Actor does no sorting or scoring of its own.
  • Apple currently truncates at ~100 entries per chart. The feed URL accepts limit=200 and the Actor caps there, but every chart tested returns 100 (99 for toppaid). A request for 200 that yields 100 is Apple's behaviour, not a bug here.
  • The cross product is fetched in full. Requests are sequential, one per chart, and each takes a few hundred milliseconds.
  • category is the app's own category, not the chart's. An app pulled from the Games chart can carry a different primary category; use categoryId for the chart you asked for.
  • A failing chart never aborts the run. An unknown storefront returns HTTP 400, is recorded in RUN_SUMMARY.failures, and the next chart proceeds. The Actor only errors out if every chart fails.
  • Transient errors are retried. 429 and 5xx get three attempts with linear backoff. HTTP 400 fails fast, because retrying an invalid storefront never helps.
  • Single-app feeds are handled. With limit=1 Apple returns entry as a bare object instead of an array; the Actor normalises that.
  • Public data only. No authentication, no personal data, no access-control bypass.

FAQ

Do I need a proxy? No. Proxy configuration is not required to run this Actor.

Do I need an Apple developer account? No. You supply no credentials.

What happens if a storefront is unavailable? It is reported in RUN_SUMMARY.failures and the run continues with the next chart. The run only fails outright if every chart failed.

Can I schedule it? Yes, daily scheduled runs are the intended pattern. Rank data is only useful as a time series.

Why does toppaid return 99 rows instead of 100? Apple's paid feed itself serves 99 entries. The Actor reports exactly what Apple returned.

How do I measure rank movement? Run on a schedule and diff consecutive datasets on appId within the same country + chartType + categoryId, comparing rank across scrapedAt.

Does it include ratings or review counts? No, the RSS chart feeds do not carry them. Pair this with an App Store detail scraper if you need ratings.

Can I get iPad or Mac charts? Not currently. The Actor exposes the three iPhone chart types the plan specifies.

Can I integrate it with something else? Yes, Apify API, client libraries, webhooks, scheduled runs, dataset exports (JSON/CSV/Excel) or MCP. Output is structured JSON.

API example

curl -X POST "https://api.apify.com/v2/acts/arman-bd~app-store-rankings-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"countries": ["us", "gb"],
"chartTypes": ["topfree", "toppaid"],
"categoryIds": ["6014"],
"limit": 25
}'

JavaScript example

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/app-store-rankings-scraper').call({
countries: ['us'],
chartTypes: ['topgrossing'],
limit: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const app of items) console.log(`#${app.rank} ${app.appName}, ${app.publisher}`);