~ / guides / How to Scrape Apple App Store Data (incl. Python)

How to Scrape Apple App Store Data (incl. Python)

MA
Mira Sol
App Store data engineer · about the author
the short version
  • App metadata and ratings come from Apple's public iTunes lookup API with no auth. It returns the unrounded average rating (for example 4.69061), not the rounded star on the page.
  • App search uses the iTunes Search API with media=software&entity=software. Apple asks callers to stay near 20 calls per minute per source.
  • App reviews come from the public iTunes RSS customer-reviews feed, 50 per page, capped at 10 pages. I hit the wall myself: page 11 returned HTTP 400, so the feed tops out near 500 reviews per country.
  • The app-store-scraper npm package still works; the Python one (0.3.5) no longer imports on Python 3.13. For review volume past that 500 ceiling, or many apps and countries, I hand the App Store call to a managed API.

I scraped Apple App Store data several ways for this guide, and I ran every snippet before publishing. The three public routes that need no account are the ones almost everyone starts with: the iTunes lookup API for app metadata and ratings, the iTunes Search API for app search, and the RSS customer-reviews feed for recent reviews. Then I checked the app-store-scraper library on both Python and npm, because that is where most tutorials point.

Below is what each Apple method returned, the exact Python and curl code, the rate limits and page caps I hit, and where each one stops being enough. This guide covers the Apple iOS App Store only. For the Google Play side, I keep a separate walkthrough linked at the end.

What Apple App Store data can you scrape?

You can scrape four kinds of Apple App Store data from public endpoints: app metadata, exact ratings, search results, and recent reviews. Each has its own Apple endpoint, and none of them needs an Apple developer account or a login.

The one thing these public routes do not give you is the complete review history of an app, and they do not give you write access to anything. Full review history for an app you own lives behind Apple’s authenticated App Store Connect API, which I cover further down. Everything else on this page reads pages any visitor can see. The cleanest place to start is metadata, because a single lookup call returns the exact rating that the page hides behind a rounded star.

How do you scrape Apple App Store metadata with the iTunes lookup API?

To scrape Apple App Store metadata, call the public iTunes lookup API with the app’s numeric ID and read the JSON it returns. It needs no auth, no key, and one request. The ID is the number in an apps.apple.com URL, for example 389801252 for Instagram.

import requests

r = requests.get(
    "https://itunes.apple.com/lookup",
    params={"id": "389801252", "country": "us"},
    timeout=15,
).json()

app = r["results"][0]
print(app["trackName"], app["averageUserRating"],
      app["averageUserRatingForCurrentVersion"],
      app["userRatingCount"], app["formattedPrice"])

When I ran this, the lookup returned, in under a second, the app name (Instagram), the bundle ID (com.burbn.instagram), the current version, the primary genre (Photo & Video), the price (Free), and two rating fields worth calling out. Ratings and counts drift over time, so treat the exact figures as a snapshot, not a constant.

The rating fields are the reason I reach for the lookup API first. averageUserRating came back as 4.69061, a full decimal, while the App Store page shows a rounded 4.5-star badge. The lookup also splits out averageUserRatingForCurrentVersion, the score for the current release. That decimal precision is the difference between noticing a rating slip from 4.69 to 4.61 and seeing nothing move on the rounded star. The iTunes lookup API is part of the iTunes Search API and returns the same shape the App Store search box uses under the hood. It covers ratings, version, developer fields, screenshots, and genre, but not review text, which is the gap the reviews feed fills. Before reviews, though, the same Search API answers a different question: which apps match a term.

How do you scrape Apple App Store search results?

To scrape Apple App Store search results, call the iTunes Search API with media=software and entity=software, and it returns matching apps as JSON. This is the app-search sibling of the lookup call, and it takes a text term instead of an ID.

import requests

r = requests.get(
    "https://itunes.apple.com/search",
    params={"term": "photo editor", "country": "us",
            "media": "software", "entity": "software", "limit": 5},
    timeout=15,
).json()

print(r["resultCount"], "results")
for app in r["results"]:
    print(app["trackId"], "-", app["trackName"], "-",
          app.get("averageUserRating"))

This returned a resultCount and a results list, each entry carrying trackId, trackName, artistName, averageUserRating, userRatingCount, primaryGenreName, and formattedPrice. The entity value is what scopes the search to iOS apps: use software for iPhone apps, iPadSoftware for iPad, or macSoftware for Mac. The limit accepts 1 to 200 and defaults to 50.

The one number to respect here is the rate. Apple’s own iTunes Search API documentation states that “the Search API is limited to approximately 20 calls per minute (subject to change).” From a single IP, a tight search loop crosses that line fast and starts drawing 403 responses, which is the first wall you hit when this scales past a handful of queries. Search and lookup cover the listing surface. Reviews are a separate feed with its own hard cap.

How do you scrape Apple App Store reviews without an account?

To scrape Apple App Store reviews without an account, request the public iTunes RSS customer-reviews feed for the app’s numeric ID and read the review JSON it returns. No login, no key. Here is the page-1 request against Instagram:

import requests

APP_ID = "389801252"   # Instagram, the id in the apps.apple.com URL
url = (f"https://itunes.apple.com/us/rss/customerreviews/"
       f"page=1/id={APP_ID}/sortby=mostrecent/json")
data = requests.get(url, headers={"User-Agent": "Mozilla/5.0"},
                    timeout=15).json()

entries = data.get("feed", {}).get("entry", [])
revs = [e for e in entries if "im:rating" in e]   # filter to real reviews
print(len(revs), "reviews on page 1")
for e in revs[:3]:
    print(e["im:rating"]["label"], "-", e["title"]["label"][:50])

When I ran this, the feed returned HTTP 200 and exactly 50 review entries, each with a star rating (im:rating), the reviewed app version (im:version), the author handle, the title, and the body text. I guard the read with .get("feed", {}).get("entry", []) and filter on im:rating for two reasons: some country stores return an empty entry array for the same app, and the schema occasionally leads with an app-summary element that has no rating field. Star-only ratings with no written text never appear, because the feed only carries reviews that have body content.

What is the 500-review limit on the RSS feed?

The RSS reviews feed is hard-capped at 10 pages of 50 reviews, so it returns roughly the 500 most recent reviews per country store. I tested the boundary directly: pages 1, 5, and 10 each returned 50 reviews with HTTP 200, while page=11 and page=12 both returned HTTP 400 Bad Request. Apple does not publish a documented quota for this feed, and developers report the same limit on the Apple developer forums.

Two consequences follow from that cap. To collect more than 500, you loop the same feed across country codes (/us/, /gb/, /de/, and so on) and merge the results, since each store has its own review set. To get the complete review history for an app you own, you move to the App Store Connect API. Before that, it is worth knowing that a popular library wraps this exact feed, and whether it still works depends on which package you install.

Can you use the app-store-scraper library for Apple?

You can use the app-store-scraper library for Apple, but only the npm package works in 2026 - the Python package of the same name no longer imports on current Python. Two unrelated projects share the string app-store-scraper, and a tutorial written for one will not run on the other.

The Python app-store-scraper (version 0.3.5, last published November 2020) pins requests==2.23.0. On Python 3.13 that pin installs an old urllib3 whose six.moves shim no longer exists, and the import dies before you can construct anything:

from app_store_scraper import AppStore
# ModuleNotFoundError: No module named 'urllib3.packages.six.moves'

You can clear the import by isolating the install and upgrading urllib3, but even then the library targets Apple’s amp-api.apps.apple.com review endpoint, which answered HTTP 401 Unauthorized for me because it wants a bearer token the App Store web client mints for itself. So the Python package returns no reviews on a current stack.

The npm app-store-scraper (version 0.18.0) worked. Its reviews() call reads the same RSS feed as the manual request above, so it inherits the same 50-per-page, 10-page ceiling:

const store = require("app-store-scraper");

store.reviews({
  id: 389801252,            // Instagram
  country: "us",
  sort: store.sort.RECENT,  // or store.sort.HELPFUL
  page: 1,                  // 1 to 10
}).then((reviews) => console.log(reviews.length, "reviews"));

That returned an array of 50 reviews for me. Requesting page: 11 throws Page cannot be greater than 10, the library’s guard against the same feed cap I hit by hand. One caveat for anything long-lived: the npm package depends on the request HTTP library, deprecated since 2020, so I keep it for one-off pulls rather than production pipelines. For the full package-by-package breakdown, including the exact dependency versions pip installed, I keep a longer app-store-scraper library guide. The library reads the public feed, so it stops at the same 500-review wall - which is where Apple’s own authenticated API becomes the alternative.

iTunes RSS feed vs App Store Connect API: which should you use?

The public RSS feed and the official App Store Connect API solve different problems, and the deciding factors are ownership and how far back you need to read. Use the feed to monitor any app; use the Connect API for the complete history of an app you own.

FactoriTunes RSS feedApp Store Connect API
AuthNoneJWT (private key, issuer ID)
Works forAny public appApps you own
Reviews available~500 most recent, per countryFull review history
OutputJSON or XMLJSON (JSON:API style)
Star-only ratingsExcludedIncluded via rating summaries
Endpointitunes.apple.com/{cc}/rss/customerreviews/GET /v1/apps/{id}/customerReviews

The App Store Connect route is documented under Apple’s Customer Reviews reference. It needs a signed JWT (tokens expire after 20 minutes) and returns 50 reviews by default, up to 200 with the limit parameter. It is the right tool when you own the app and want every review. For monitoring apps you do not own, the public feed is the only sanctioned door, and the 500-review cap is the price of skipping auth. That cap, plus the 20-calls-per-minute search limit, is exactly where the free methods stop scaling.

How do you scrape Apple App Store data at scale?

To scrape Apple App Store data at scale, you move the IP rotation, the country looping, and the parser maintenance off your machine and hand the app ID to a managed API. The free routes above are fine for small, occasional pulls. They break in predictable places once volume climbs.

MethodGood forBreaks when
iTunes lookup APIMetadata, exact ratingsMetadata only, no review text; ~20 req/min per IP
iTunes Search APIApp search403s past ~20 calls/min from one IP
iTunes RSS feedLatest reviews, no authHard 500-review cap (page 11 = HTTP 400); one country per request
app-store-scraper (npm)A few hundred recent reviewsSame 500 cap; deprecated request dependency
App Store Connect APIYour own app’s full historyApps you own only; JWT signing setup

I point pipelines at ChocoData because the request shape is one pattern across metadata, search, and reviews, and the proxy rotation and the 500-review workaround run server-side. The metadata call mirrors the lookup I ran by hand:

# App metadata, mirroring the iTunes lookup above
curl "https://api.chocodata.com/api/v1/appstore/app?id=389801252&api_key=$CHOCO_API_KEY"

# App Store reviews, parsed and paged server-side (no 500 cap to manage)
curl "https://api.chocodata.com/api/v1/appstore/reviews?id=389801252&country=us&sort=recent&api_key=$CHOCO_API_KEY"

# App Store search results
curl "https://api.chocodata.com/api/v1/appstore/search?term=photo%20editor&country=us&api_key=$CHOCO_API_KEY"

The Python version is the same GET with your key as a query parameter, loaded straight into pandas:

import requests
import pandas as pd

resp = requests.get(
    "https://api.chocodata.com/api/v1/appstore/reviews",
    params={"id": "389801252", "country": "us", "sort": "recent",
            "api_key": "YOUR_CHOCO_API_KEY"},
    timeout=30,
)
reviews = resp.json()["data"]["reviews"]
df = pd.DataFrame(reviews)
df.to_csv("instagram_appstore_reviews.csv", index=False)
print(df.head())

This is the same App Store data the DIY routes return, with the proxy rotation, the country looping, and the JSON parsing handled for you, and without the 500-review ceiling. For a one-off pull of a few hundred reviews, the public endpoints above are free and enough. For continuous collection across many apps and countries, grab a key and skip the rate-limit babysitting. If you want a scored comparison of the hosted options first, I benchmark them in the best App Store scrapers of 2026.

Scraping public Apple App Store data is generally treated as lawful in the US, but that is not blanket permission. US courts have read the anti-hacking CFAA narrowly for public pages, most visibly in hiQ v. LinkedIn, where scraping publicly available data was found not to violate that statute. That ruling is about one law, not about every obligation you carry.

Three things still apply. Apple’s Media Services terms govern the store, so automated access remains a contract question under those terms even when it is not a hacking one. Copyright covers app descriptions, icons, and screenshots, which are Apple’s or the developer’s work, not yours to republish. And personal-data rules such as the GDPR apply to review text that names people, so have a lawful basis for what you store and avoid collecting more than you need. Treat listings and reviews as public business information, stay on public endpoints, and keep your request rate reasonable. This is general information, not legal advice. For the same ID-to-data workflow on the Android side, I keep a separate how to scrape Google Play Store data guide.

Sources

FAQ

Can I scrape Apple App Store data without an Apple developer account?

Yes. The iTunes lookup API, the iTunes Search API, and the RSS customer-reviews feed are all public and key-free, so you can pull app metadata, search results, and recent reviews with no Apple developer account and no App Store Connect access. You only need an authenticated account (App Store Connect) for the full review history of an app you own.

How do I get the exact App Store rating instead of the rounded star?

Call the iTunes lookup API and read averageUserRating, which comes back as a full decimal such as 4.69061. The listing page rounds that to the nearest half-star, but the lookup response carries the precise number, plus averageUserRatingForCurrentVersion for the current release. That precision is what you need to track small rating movements over time.

How many App Store reviews can I scrape per app?

About 500 per country store through the public RSS feed. The feed serves 50 reviews per page across 10 pages, and page 11 returns HTTP 400. To go past ~500 you loop the same feed across country codes (/us/, /gb/, /de/) and merge, or move to a hosted API. The complete review history for an app you own is only available through the authenticated App Store Connect API.

Why does app-store-scraper fail to import on Python 3.13?

Version 0.3.5 pins requests==2.23.0, which drags in urllib3 1.25.11 and its urllib3.packages.six.moves import, a shim removed from modern Python. On Python 3.13 the import raises ModuleNotFoundError: No module named 'urllib3.packages.six.moves' before you can call a method. Upgrading urllib3 clears the import, and then the review endpoint answers 401.

Does Apple have an official App Store data API?

For metadata and search, yes: the iTunes Search API and lookup endpoint are official and public. For reviews of an app you own, the authenticated App Store Connect API exposes the full set at GET /v1/apps/{id}/customerReviews. There is no official public API that returns the complete review history for apps you do not own, which is why the RSS feed and scraping fill that gap.

MA
Mira Sol
I've built App Store data pipelines for years. On appstorescraperapi.com I run App Store scraping methods against live pages and publish what actually holds up.