HomeBlog › How We Mined 21,746 App Store Keywords f

Last updated 29 July 2026

How We Mined 21,746 App Store Keywords for Free, With No ASO Tool

Every ASO tool charges monthly for the same thing Apple already streams for free: real, ranked keyword suggestions from its own Search tab. We found the two network calls the App Store app itself makes and used them to mine 21,746 real keywords across 50 storefronts for zero cost.

Short answer: Apple runs two undocumented but unauthenticated endpoints behind App Store search. MZSearchHints.woa returns ranked autocomplete suggestions per country, and MZSearch.woa returns the real ranked results plus each app's subtitle. Both are callable with plain curl, no API key, though Apple could change or block them at any time.

Free app store keyword research is possible because Apple's own autocomplete has no login wall

Open the App Store, tap Search, and start typing. The dropdown that appears is not decoration, it is Apple's own keyword research, generated from real query volume and served instantly to every phone on the planet. That dropdown is powered by a plain network request, and the request needs no authentication beyond a storefront identifier.

We watched the App Store app's own traffic to find the call, then confirmed it works from a bare terminal with no App Store account, no cookies and no API key.

MZSearchHints returns Apple's real, ranked autocomplete suggestions for any term

The endpoint is:

https://search.itunes.apple.com/WebObjects/MZSearchHints.woa/wa/hints?clientApplication=Software&q=<term>

It needs one header, X-Apple-Store-Front, set to a storefront ID followed by a fixed suffix, -1,29. The storefront ID picks the country. The suffix is boilerplate Apple's own client always sends, and we have never seen it documented anywhere.

Terminal

curl -s 'https://search.itunes.apple.com/WebObjects/MZSearchHints.woa/wa/hints?clientApplication=Software&q=imposter' \

  -H 'X-Apple-Store-Front: 143441-1,29' -o hints.plist

The response is a plist, not JSON. Apple's own frameworks read plists natively, which is presumably why nobody wrapped this in JSON for an API that was never meant to be public. From Python, plistlib parses it straight into native lists and dicts:

Python

import plistlib, urllib.request

 

def autocomplete(term, storefront_id):

  url = ("https://search.itunes.apple.com/WebObjects/MZSearchHints.woa/wa/hints"

    f"?clientApplication=Software&q={term}")

  req = urllib.request.Request(url, headers={"X-Apple-Store-Front": f"{storefront_id}-1,29"})

  with urllib.request.urlopen(req) as resp:

    return plistlib.load(resp)

 

print(autocomplete("imposter", 143443)) # Germany storefront

Inspect the structure yourself once it lands. Apple documents nothing about this schema and it carries no version number, so treat the exact shape as something to check each time you rely on it, not something to hard-code and forget.

A term appearing at all is proof of demand, and its position is a popularity proxy

Apple does not suggest random strings. The hints list is built from what people actually type into App Store search, so if your term shows up, real users are searching it. If it never shows up, either nobody searches it or the volume is too thin to surface at all.

Position matters too. The list is ordered, and a higher entry correlates with more query volume. It will not hand you a number like "1,200 searches a month" the way a paid tool implies its estimates are precise, but it is a real, Apple-sourced ranking you cannot get any other way for free.

MZSearch returns the real ranked results for a term, plus the subtitle the public API hides

The second endpoint answers a different question: given a search term, what does the App Store actually show, in what order, and how is each competitor positioned. It is:

https://search.itunes.apple.com/WebObjects/MZSearch.woa/wa/search?clientApplication=Software&term=<term>

Same header, same storefront trick. The ordered app IDs live at pageData.bubbles[0].results in the JSON body:

Python

import json, urllib.request

 

def ranked_results(term, storefront_id):

  url = ("https://search.itunes.apple.com/WebObjects/MZSearch.woa/wa/search"

    f"?clientApplication=Software&term={term}")

  req = urllib.request.Request(url, headers={"X-Apple-Store-Front": f"{storefront_id}-1,29"})

  with urllib.request.urlopen(req) as resp:

    data = json.loads(resp.read())

  return data["pageData"]["bubbles"][0]["results"]

 

print(ranked_results("imposter", 143441)) # US storefront, real ranked order

Walk the app entries in that same response and you get each competitor's subtitle, the line under the app name in search results. The public itunes.apple.com/search API that most ASO tutorials point you to does not return subtitle at all, which is exactly why so many keyword tools are guessing at competitor subtitles from screenshots instead of pulling them directly.

We mined 21,746 keywords across 50 storefronts this way, without a single paid subscription

Once both calls work, keyword research turns into a loop instead of a manual chore. Seed a term, pull its hints, take every new suggestion as a fresh seed, and stop when the hints stop introducing anything new. Repeat per storefront, because the same English query surfaces completely different neighbours in different countries.

Run across 50 storefronts, that loop produced 21,746 real keywords for the game we built, Bluffle, at zero marginal cost. No Appfigures seat, no Apptweak seat, no Sensor Tower contract.

The biggest finding: the genre travels under its English name, so translating your list throws away most of the volume

Bluffle sits in the imposter party-game genre, and the English word "imposter" is the top autocomplete suggestion in almost every storefront we pulled, including ones where the interface language is not English. Germany's top hint is imposter spiel, not a German translation of imposter. Turkey's is imposter oyunu. Brazil's is impostor jogo.

The genre went viral worldwide under its English name before local translations ever caught up, so a straight translation pass would have missed the actual dominant query in most of these markets. You only find that by pulling each storefront's own autocomplete, not by running an English list through a translator. It is the same lesson behind how the word lists inside the imposter word game itself are written, per culture, never machine-translated from one master list.

Reproducing this takes an afternoon, not a subscription

Three things you need: a storefront ID per country, a seed list of five to ten obvious terms for your category, and the patience to let the hints loop run to exhaustion per storefront.

StorefrontCountryHeader value
USUnited States143441-1,29
GBUnited Kingdom143444-1,29
DEGermany143443-1,29

Apple's App Store Connect help pages list every storefront and its territory, but not the numeric ID behind each one. You either capture it yourself from traffic or start from a known list like the three above.

Be honest about the risk: this is an undocumented API, not a public contract

Nothing here is an official Apple developer product. There is no published rate limit, no changelog, no support channel, and no guarantee the URL, the header format or the response shape still look like this by the time you read it. We are describing what worked when we ran it, not a stable integration to wire into production infrastructure without a fallback.

Treat both endpoints as a research tool you run in bursts from your own machine, cache what you get, and re-check occasionally, not as a live dependency. If Apple ever exposed this officially it would be one of the more useful things they could ship for free ASO. Until then, this is the closest thing to it.

We run this same process for every localisation decision on Bluffle, our own pass-the-phone imposter word game. More on how the app and its word packs get built is on the about page.

Frequently asked questions

Is there a free alternative to Appfigures or Apptweak for App Store keyword research?

Yes. Apple's own App Store search runs on two endpoints you can call directly with curl: MZSearchHints.woa for ranked autocomplete suggestions, and MZSearch.woa for real ranked results and app subtitles. Both need only a storefront header, no API key and no paid subscription.

What is the MZSearchHints endpoint?

MZSearchHints.woa is the network call behind App Store search autocomplete. Given a search term and a storefront header, it returns Apple's own ranked list of related queries as a plist. A term's presence proves real search demand, and its position in the list is a popularity proxy.

Will Apple's undocumented search API keep working?

There is no guarantee. MZSearchHints and MZSearch are not published, versioned or supported by Apple, so the URL, header format or response shape could change without notice. Treat them as a research tool you re-check periodically, not a dependency to build permanent infrastructure on.

B

The Bluffle Team · Hypecent Limited

The Bluffle team builds party games for iOS, Android and the web at Hypecent Limited. We designed Bluffle's word-pair system and wrote the 5,051 word pairs that ship across its 33 languages. More about Bluffle