Apple publishes the iOS App Store top charts as a public feed, per country, with no key and no account. One GET returns the chart as JSON:
curl -s "https://itunes.apple.com/us/rss/topfreeapplications/limit=100/json" \
| jq '.feed.entry | length, .[0]["im:name"].label'
The URL is https://itunes.apple.com/{country}/rss/{feed}/limit={n}/genre={id}/json, with genre left out for the overall chart.
| Feed | What it ranks |
|---|---|
topfreeapplications, toppaidapplications, topgrossingapplications
|
iPhone Top Free, Top Paid, Top Grossing |
topfreeipadapplications, toppaidipadapplications, topgrossingipadapplications
|
the same three for iPad |
newapplications, newfreeapplications, newpaidapplications
|
what just launched, not what is winning |
Category ids: Games 6014, Business 6000, Education 6017, Entertainment 6016, Finance 6015, Food & Drink 6023, Health & Fitness 6013, Lifestyle 6012, Medical 6020, Music 6011, Navigation 6010, News 6009, Photo & Video 6008, Productivity 6007, Reference 6006, Shopping 6024, Social Networking 6005, Sports 6004, Travel 6003, Utilities 6002, Weather 6001, Books 6018, Developer Tools 6026, Graphics & Design 6027.
curl -s "https://itunes.apple.com/jp/rss/topgrossingapplications/limit=10/genre=6014/json" \
| jq -r '.feed.entry[] | .["im:name"].label'
Each entry carries the name, developer (im:artist), price (im:price.attributes.amount and currency), category, release date, icon, and in id.attributes both the numeric app id and the bundle id. Five things to know before you build on it, each measured on 2026-10-26:
1. The United Kingdom is gb, and uk is an error
/uk/rss/... answers HTTP 400. Storefront codes are ISO two-letter and lowercase, and the UK's is gb. A loop over "the countries we care about" that has uk in it loses that market with a status code that looks like a malformed URL.
2. limit stops at 100
limit=200 returns 100 entries and no error. 100 is all the feed serves.
3. The three "new" feeds ignore limit
newfreeapplications/limit=10 returned 110 entries. If you bill, store or display per row, truncate after parsing rather than trusting the URL.
4. One entry comes back as an object, not a list
limit=1 returns feed.entry as a single object instead of an array of one. In Python, iterating entry then walks the object's keys, without an error. Normalise it: entries = [e] if isinstance(e, dict) else e.
5. There is no rank field, and no history
The rank is the position in the array. And the feed is now: yesterday's chart is gone. If you want to know who climbed, store each read with a timestamp and diff it against the last one; nothing upstream keeps it for you.
The Mac App Store has the same format for Top Free (topfreemacapps), but its Top Paid and Top Grossing feeds came back empty.
Google Play has no such feed
Google publishes nothing equivalent; the Play Store's charts are read from the data its own pages use. That one is written up separately: Google Play top charts API.
Hosted
I run this as App Store Top Charts Scraper on Apify: any storefronts, charts and categories in one run, the traps above handled, star ratings and rating counts added from Apple's lookup on request, and rankChange against your previous run so a daily schedule becomes a rank tracker. A quick start with curl, Python and MCP is on GitHub: danielhagever/app-store-top-charts.
Top comments (0)