App Store Rank & Rating Scraper
Pricing
Pay per event
App Store Rank & Rating Scraper
Daily App Store keyword ranks and an alert when new ratings turn bad. Apple public endpoints only — ranks you cannot back-fill, kept as a series.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Northbell
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Track where your app ranks for the keywords you care about, and get told when new ratings turn against you — every morning, without opening a dashboard.
Apple's public endpoints only. No HTML scraping, no private APIs, no personal data.
Why this exists
Ranks cannot be back-filled. Apple does not publish yesterday's search results. If you did not record your position on a given day, that day is gone forever. This Actor records it and keeps the series, so three months from now you can answer "did that ASO change actually do anything?"
That is the whole product. Everything else is plumbing.
What you get
Run it daily on a schedule. Each run appends to your dataset:
rank rows — one per tracked app per keyword per storefront.
| field | meaning |
|---|---|
rank | position in Apple's results, or null if outside searchLimit |
previousRank | where it was last run — null on the first run |
rankChange | positive means it moved up |
outOfRange | true when a tracked app fell out of the searched depth |
isNewToKeyword | first time this app appears for this keyword |
reviewSummary rows — one per tracked app per storefront.
| field | meaning |
|---|---|
newRatings | how many ratings arrived since the last run |
newRatingsAverage | the average star rating of just those new ones |
newRatingsErrorBound | how far off that figure could be — always reported |
newRatingsReliable | false when the error bound is too wide to act on |
ratingDrop | true when the new ratings are at least a full star below the app's standing average, even after allowing for the error |
versionChangedSinceLastRun | you shipped since the last run — the context for any drop |
averageRating, ratingCount | Apple's current aggregates |
review rows — individual new reviews, when review text is available (see below).
error rows — anything that failed, in the dataset where you will actually see it.
Reading the ratings, not the reviews
Most people who rate an app never write a word. A tool that scrapes review text is blind to all of them.
This Actor works from Apple's aggregate figures instead. Two observations are enough to recover what happened in between: total ratings × average is a running sum, so the difference between two runs divided by the number of new ratings gives the average of just the new ones. Twenty ratings at 1.4 stars is a bad night, and you see it whether or not anyone wrote a review.
Apple rounds the average it reports, so the recovered figure carries a margin. That margin widens as the app gets larger and the number of new ratings gets smaller — on an app with 700,000 ratings, five new ones tell you nothing. The margin is always reported, newRatingsReliable says whether it is narrow enough to act on, and an alert only fires when the drop survives the margin. A number without its error is a number that will eventually lie to you.
About review text
Review text usually comes through, but not always. Apple sometimes answers the customer-review feed with a valid, correctly-formed, completely empty response — indistinguishable from "this app has no reviews" unless you look closely. Measured from Apify: it failed on two consecutive runs one hour, then succeeded five out of five the next.
This Actor tells the two apart. Every reviewSummary row carries reviewTextStatus: ok when the feed answered, blocked when it came back empty. A blocked feed does not fail the run and does not affect ranks, ratings, averages, or drop alerts — those come from a different endpoint that has never gone quiet.
That is the reason the rating maths above exists. A feature that depends on someone else's goodwill needs a floor underneath it.
Three things it gets right
It respects Apple's rate limit, across runs. Apple documents 20 calls per minute. The Actor uses a token bucket that persists between runs, so two overlapping schedules do not stack up and get you throttled. Default is 18/min to leave headroom.
It fails loudly instead of quietly. Apple returns HTTP 200 with an empty feed in at least two situations that look exactly like "no data": when page= is missing from a review URL, and when the request comes from a datacenter IP. The Actor asserts the response shape, writes an error row into the dataset, and marks the run failed if a whole requested feature produced nothing. A green run with an empty dataset is the worst possible outcome for something you check once a month.
A tracked app that disappears still produces a row. If your app drops out of the top 200 for a keyword, you get a row with outOfRange: true — not silence. Silence is indistinguishable from a broken run.
Every derived number carries its error. See "Reading the ratings, not the reviews" above.
Input
{"keywords": ["habit tracker", "focus timer"],"appIds": ["1438388363"],"countries": ["us", "gb"],"trackReviews": true,"reviewPages": 2,"searchLimit": 200,"maxCallsPerMinute": 18}
App IDs are the number in the App Store URL: apps.apple.com/us/app/x/id1438388363 → 1438388363.
Leave appIds empty to record the top 20 for each keyword instead of specific apps.
Sizing a run
Calls per run = keywords × countries + appIds × countries × (reviewPages + 1).
At 18 calls/minute, 10 keywords and 3 apps across 2 storefronts is about 2.5 minutes.
What you pay for
Pay per event. You are charged for observations that produced a result:
| event | when |
|---|---|
| Actor start | once per run |
| Rank check | one keyword, one storefront, rank recorded |
| Rating check | one app, one storefront, ratings recorded |
A failed observation is never charged. If Apple times out, or an app ID does not exist in that storefront, you get an error row and no charge for it. You are paying for data, not for attempts.
Ten keywords and three apps in one storefront, run daily, is 30 starts + 300 rank checks + 90 rating checks a month.
Limits worth knowing
- Search results are cached by Apple for about 24 hours per keyword and storefront. Running more than once a day returns the same ranking. This is a daily instrument.
- Search depth caps at 200. Below that, an app is reported as out of range rather than ranked.
- Reviews cap at 10 pages (500) per app per storefront, newest first.
- The rate-limit bucket is shared through a key-value store. Two runs starting at the same instant can each read the same balance, so the default leaves headroom rather than spending all 20.
On data and privacy
Reviewer names are never fetched or stored. They are not needed to decide anything about an app, and holding them would mean holding personal data.
Review titles and bodies, when available, pass through to your dataset but are never written to the Actor's own history. The persistent store holds numbers only: ranks, rating counts, and averages.
Icons and screenshots are not redistributed.
Storage
History lives in a named key-value store, aso-history, so it survives between runs. Deleting that store resets the baselines — ranks start over at previousRank: null, and spike detection goes quiet until it has enough samples again.
Running locally
npm installnpm test # unit tests, no networknpm run smoke # end-to-end against Apple, twice, to prove the diff works
For AI agents
This Actor works well as an agent tool: the input schema is small and fully described, every run returns structured rows, and failures come back as data rather than silent gaps. Use it when you need to:
- track App Store keyword rankings for an app over time
- monitor iOS app rating changes and detect rating drops
- get the average rating of new App Store reviews since a previous run
More no-login scrapers by northbell
Every one of these reads only public pages — no login, no cookies — and most of them record the numbers that cannot be back-filled if you don't capture them today.
LinkedIn jobs
- LinkedIn Jobs Scraper with Applicant Counts — jobs plus how fast applicants are arriving
- LinkedIn Jobs Scraper — Filters That Actually Work — the experience/workplace filters LinkedIn silently ignores, applied for real
- LinkedIn Jobs Salary Data — Filter by Pay — salary parsed into numbers so you can filter by yearly pay
- Fast LinkedIn Jobs Scraper — bulk job listings, cheap and quick
- LinkedIn Company Jobs Scraper — every open role at a company you name
LinkedIn companies
- LinkedIn Company Scraper with Headcount Growth — the real headcount and how fast it's growing
- LinkedIn Company Posts + Engagement — a company's posts with exact reaction and comment counts
App stores
- App Store Rank & Rating Scraper — iOS keyword rank and rating changes over time
- Shopify App Reviews Scraper — Filter & Sort by Rating — exact per-star review counts, filter and sort
- Google Play Rating & Review Tracker — an Android app's rating tracked day by day