App Store Keyword Rank Tracker avatar

App Store Keyword Rank Tracker

Pricing

from $0.84 / 1,000 results

Go to Apify Store
App Store Keyword Rank Tracker

App Store Keyword Rank Tracker

Tracks iOS App Store search-ranking positions for any keyword, via Apple's own public Search API. Returns the full ranked result list per keyword/country plus, optionally, the exact rank of specific apps you track by bundle ID.

Pricing

from $0.84 / 1,000 results

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

App Store Keyword Rank Tracker (ASO)

Tracks iOS App Store search-ranking positions for any keyword, via Apple's own public Search API. Public data only. No login, no cookies, no browser, no reverse engineering — this is the one actor in this portfolio built entirely on a vendor-documented endpoint.

The one thing you need to know before using this

There is no WAF, no rate limit hit, and no bypass work here: search.itunes.apple.com is meant for third-party consumption (Apple's own docs). The product this actor sells is ASO (App Store Optimization) rank tracking — turning Apple's search-result order into a reportable ranking signal for a keyword, not the difficulty of reaching the data. Android/Google Play is intentionally not covered — see CRAWLING_METHOD.md §4 for why.

What you get

Four record types share one dataset, told apart by recordType.

APP — one row per ranked result

rank is the result's 1-based position in Apple's own returned order — that ordinal position is the ranking signal, not a score Apple exposes as a field. app carries Apple's full result object verbatim (price, rating, rating count, icon, genres, seller, screenshots, release notes, …).

RANK_TRACK — one row per (keyword, tracked app), only when Track specific apps' rank is set

Identify an app by bundle ID (most precise), numeric track ID, or name (least precise — case-insensitive substring match). Reports the app's exact rank if it's within the fetched results, or foundInResults: false if it isn't — a real, reportable ASO outcome, not a failure.

SEARCH_SUMMARY — one row per (keyword, country, entity) query

Apple's own resultCount for that query (capped at 200 server-side, confirmed live — not a client-side guess).

ERROR — one row per input that failed

So every entry in Keywords maps to at least one output row.

Input

FieldWhat it does
Keywordsfree-text App Store search terms — one search per entry
App Store countrytwo-letter storefront code (us, gb, id, …), applies to every keyword
App typeiPhone/universal, iPad-only, or Mac — each a genuinely different result set (verified live)
Track specific apps' rankbundle ID / track ID / name — adds a RANK_TRACK row per keyword
Results per keywordup to 200 (Apple's own hard cap) — also the depth searched for tracked-app matches

Example

{
"keywords": ["todo list", "habit tracker"],
"country": "us",
"trackedApps": ["com.todoist.ios"],
"limit": 100
}

Notes on reliability

  • A bogus country code is refused by Apple with a clean HTTP 400 — reported as an ERROR row, never silently substituted with a default storefront.
  • A nonsense keyword is NOT a hard zero — Apple's search does its own fuzzy/relevance matching and can return a small number of loosely related apps even for made-up terms. This is documented Apple behaviour, not a bug this actor works around.
  • A wrong bundle-ID guess for a tracked app is honestly reported as foundInResults: false, never a false-positive match — matching only happens on an exact bundle ID, exact numeric track ID, or a genuine substring of the real app name.
  • Apple caps results at 200 regardless of what's requested — verified live (limit=201 returns the identical set as limit=200).

Output envelope

Every record carries _input, _source and _scrapedAt. Upstream field names pass through verbatim under app (and matchedApp on RANK_TRACK rows) — no renaming.

See CRAWLING_METHOD.md for the recon trail, including why Google Play was left out of v0.1.