App Store Rank Tracker - Apple Keyword & Category Ranking (ASO)
Pricing
$4.00 / 1,000 app rank record returneds
App Store Rank Tracker - Apple Keyword & Category Ranking (ASO)
Track an iOS app key word ranking position, category rank, rating and version with run-over-run deltas. Zero-auth Apple iTunes Search + RSS + Lookup APIs.
Pricing
$4.00 / 1,000 app rank record returneds
Rating
0.0
(0)
Developer
CQ
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
App Store Rank Tracker — Apple Keyword & Category Ranking (ASO)
Track exactly where your iOS app ranks in the Apple App Store — for the keywords that matter to you, in its category top charts, with run-over-run deltas so you can see whether your ASO work is actually moving the needle.
Built for app teams and ASO agencies who need a cheap, reliable, scriptable rank tracker without standing up scrapers or paying enterprise ASO-tool prices.
What it does
For each app you give it, every run reports:
- Keyword ranking position — the app's 1-based position in App Store search results for each keyword you track, plus the apps Apple ranks above you (your direct ASO competitors for that term).
- Category rank — the app's position in its primary-genre top charts (top free / top paid / top grossing).
- Rating & version snapshot — current average rating, rating count, current-version rating, current version string and its release date, and price.
- Deltas since last run — every keyword position and category position is compared to the previous run: did it move up, down, stay flat, go lost (dropped out of results), or is it new? Rating and version changes are tracked too.
State is persisted in the Actor's key-value store, so as long as you run it on a schedule (daily/weekly), each run shows movement vs. the previous one.
Data source — 100% real, zero-auth Apple APIs
This Actor hits Apple's own official public endpoints — the same ones apps.apple.com uses. No headless browser, no proxies, no third-party scraper, no mock data. Output is fully input-dependent: different apps / keywords / countries return different real rankings.
| Signal | Apple endpoint |
|---|---|
| Keyword position | itunes.apple.com/search?term=...&entity=software&country=... |
| Category rank | itunes.apple.com/<cc>/rss/topfreeapplications/limit=200/genre=<id>/json |
| Rating / version / price | itunes.apple.com/lookup?id=...&country=... |
These endpoints are free and require no authentication or API key.
Input
| Field | Type | Description |
|---|---|---|
appIds | array | App Store numeric IDs or full app URLs to track. |
keywords | array | Keywords/phrases to look up each app's ranking position for. |
searchTerms | array | (Optional) App names to auto-resolve to IDs when you don't have the numeric ID. |
country | string | 2-letter storefront code. Rankings are storefront-specific. Default us. |
charts | array | Category charts to check: topfree, toppaid, topgrossing. Default ["topfree"]. |
includeCategoryRank | boolean | Include category top-charts rank. Default true. |
searchLimit | integer | Search depth per keyword, 10–200. Default 100. |
categoryChartLimit | integer | Category chart scan depth, 50–200. Default 200. |
Example input
{"appIds": ["281796108"],"keywords": ["notes", "note taking", "todo list", "evernote"],"country": "us","charts": ["topfree"]}
Output
One dataset item per tracked app. Each record contains app metadata, a per-keyword ranking array, a per-chart category ranking array, and run-over-run deltas.
Top-level fields:
| Field | Type | Description |
|---|---|---|
appId | string | Apple App Store trackId of the app. |
found | boolean | true for a normal record; false on a marker record (app could not be resolved in the storefront). |
error | string | null | Reason code when found is false (e.g. app_not_found_in_storefront, no_valid_targets). null otherwise. |
trackName | string | App name. |
sellerName | string | Publisher / seller name. |
country | string | Storefront country code used for this run. |
primaryGenre | string | App's primary genre name. |
primaryGenreId | integer | Apple primary genre id. |
averageUserRating | number | Average user rating across all versions. |
userRatingCount | integer | Total number of ratings. |
currentVersionRating | number | Average rating for the current version. |
currentVersion | string | Current version string. |
currentVersionReleaseDate | string | Release date of the current version. |
price | number | Numeric price in storefront currency. |
formattedPrice | string | Localized formatted price (e.g. Free). |
isFree | boolean | true when price is 0. |
trackViewUrl | string | App Store product page URL. |
keywordsTracked | integer | Number of keywords requested. |
keywordsRanked | integer | Number of tracked keywords the app ranked for within searchLimit. |
bestKeyword | object | null | The keyword with the best (lowest) position this run: { keyword, position }. |
avgKeywordPosition | number | null | Mean position across ranked keywords. |
keywordsImproved | integer | Keywords that moved up vs last run. |
keywordsDropped | integer | Keywords that moved down vs last run. |
keywordsLost | integer | Keywords that dropped out of results (not_ranked) vs last run. |
keywordRanks | array | Per-keyword result (see below). |
categoryRanks | array | Per-chart category result (see below). |
ratingDelta | object | null | Rating / version movement vs the previous run; null on the first run. |
isFirstRun | boolean | true when no prior state exists for this app + storefront. |
scrapedAt | string | ISO timestamp of the record. |
Each keywordRanks[] entry: keyword, found, position (1-based, or null if outside the top searchLimit), totalResults, topCompetitors[] (up to 5 apps ranked above you: { position, appId, trackName }), and a delta.
Each categoryRanks[] entry: chart, genreId, genre, found, position (or null if outside the scanned chart depth), chartSize, and a delta.
ratingDelta: { averageUserRatingChange, userRatingCountChange, versionChanged, previousVersion }.
{"appId": "281796108","found": true,"trackName": "Evernote - Notes Organizer","country": "us","primaryGenre": "Productivity","averageUserRating": 4.4,"currentVersion": "10.x","keywordsRanked": 3,"bestKeyword": { "keyword": "evernote", "position": 1 },"avgKeywordPosition": 12.3,"keywordRanks": [{"keyword": "evernote","found": true,"position": 1,"totalResults": 22,"topCompetitors": [],"delta": { "current": 1, "previous": 2, "change": 1, "improved": true, "status": "up" }}],"categoryRanks": [{ "chart": "topfree", "genre": "Productivity", "genreId": 6007, "found": true, "position": 37, "chartSize": 200,"delta": { "current": 37, "previous": 41, "change": 4, "improved": true, "status": "up" } }],"ratingDelta": { "averageUserRatingChange": 0.0, "userRatingCountChange": 120, "versionChanged": false, "previousVersion": "10.x" },"isFirstRun": false,"scrapedAt": "2026-06-22T..."}
In every delta, change is positive when the app moved up (toward #1). status is one of up / down / flat / new / not_ranked.
Not-ranked and not-found are still recorded. If an app doesn't rank for a keyword, that keyword entry has found: false / position: null — the app's record is still written. If an app can't be resolved in the storefront at all (bad ID, region-restricted, or an Apple outage that survives all retries), a marker record with found: false and an error code is written instead. The Actor never finishes with an empty dataset and never hard-fails on a transient Apple error.
Scheduling
Run it on Apify's scheduler (e.g. daily at 9am). Because state persists between runs in a named key-value store, every scheduled run gives you a clean "what moved since the last run" view of your keyword and category rankings. On the very first run there is no prior state, so deltas are new/null (isFirstRun: true).
Pricing
Billing follows the Actor's configured Apify pricing model and your platform plan. The workload is lightweight — plain HTTP calls to Apple's public endpoints, no browser and no proxies — so runtime and resource usage stay low. Cost scales with how many apps, keywords, and charts you track per run (roughly one dataset record per tracked app).
Limitations
- Ranking depth is capped. Keyword rank is found only within
searchLimit(10–200; Apple's search endpoint caps results at 200). An app ranked below the scanned depth reportsfound: false/position: null, not its true deep position. - Category charts cap at 200. Apple's storefront RSS top charts return at most 200 entries; an app ranked below
categoryChartLimit(50–200) in its genre shows as not in chart (found: false). - One storefront per run. Rankings are storefront-specific and the run tracks a single
country. To cover multiple storefronts, run once per country. There is no separate language axis — results follow the storefront's locale. - Point-in-time snapshot. Each record reflects rankings at
scrapedAt. Deltas are computed against the previous run's persisted state only; there is no historical time series inside a single record. - Static fetch, no personalization. The Actor reads Apple's public JSON endpoints only — no headless browser, no logged-in/device-personalized ranking. Public storefront search can differ slightly from what an individual device shows due to Apple-side personalization and A/B variation.
- Per-store rate limits. The Actor self-throttles (~50 req/min) and backs off on Apple
429/503, so large keyword sets take longer rather than failing. Sustained Apple rate-limiting or outages can cause individual lookups to return not-found for that run. - Category rank needs a resolvable primary genre. If Apple Lookup doesn't return a
primaryGenreIdfor an app, category ranking is skipped for it (keyword ranking still runs).