Skip to main content
Both stores are live and equally supported. What differs is which fields each store indexes for search, and one of Apple’s indexed fields cannot be read from the public listing at all. On the App Store, asobeast reads iPhone search, so it tracks listings that are available on iPhone. An app sold only on iPad, the Mac App Store, Apple Watch or Apple Vision Pro never appears in that search, so it is refused on import and as a competitor. Apple keeps a separate iPad catalogue that lists iPad only apps, and asobeast does not read it. An app imported before this rule shows a notice on its pages, because its positions cannot be found.

What does each store index?

Google Play search therefore reads three surfaces: the title, the 80 character short description and the 4000 character long description. There is no subtitle and no keyword field on Google Play, so those two stay Apple only concepts everywhere in asobeast, including the types, the metadata lints and the audit rubric. In a storefront that defaults to English, asobeast also captures the native localization. See Countries and markets. In practice, App Store search combines the words of the title, subtitle and keyword field into phrases within one localization, never across two, and the order of the words does not matter. Apple does not document either behaviour; both are the consistent observation of ASO practitioners.

Is screenshot text indexed?

Apple has not documented screenshot text as an indexed field, and Google has not either. The App Store column of the table above therefore lists three fields, not four. Since early June 2025, ASO practitioners have reported that apps rank for words that appear only in their screenshot captions on the App Store. Appfigures measured it first, and Phiture and AppTweak repeated the report. Apple has been reported to deny it, and the one controlled test published, by ConsultMyApp, found 1 of 64 caption phrases ranking without an explanation in the title, subtitle or keyword field. asobeast treats screenshot text as a weak, unconfirmed signal: it reads it on the App Store, shows it beside keyword coverage and records its changes, but never counts it as an indexed field. Google Play screenshots are not read at all. See Read screenshot captions.

Why is the iOS keyword field private?

The 100 character iOS keyword field never appears on the public store page, so no amount of collection can read it. It exists only in App Store Connect. asobeast handles this by asking you for it. Type or paste the field on the metadata page, one localization at a time, and asobeast stores those keywords with the source KEYWORD_FIELD, which lets coverage checks, the audit rubric and the Action Center reason about a surface they cannot otherwise see. Leaving it empty is not neutral. Coverage will report the field as uncovered because asobeast has no evidence that it contains anything.

How do you read and write the keyword field?

Each App Store localization has one field. The per-localization routes take the localization in the path and the markets to track in the body, and they are what the web app calls. The storefront shaped routes take the storefront and the localization as optional query parameters, and without them they read and write the default localization of the home storefront. They are unchanged. The two families store the same fields. The two storefront shaped reads answer the KeywordFieldResult shape and the list answers one per localization. The new routes answer AppLocalizationsResult, AppLocalizationItem, LocalizedKeywordFieldResult, KeywordFieldSavePreview, MarketKeywordFields and LocalizationDetectionResult, all described in the API reference. Nine things the schema cannot tell you.
  • The value is the saved set, not your string. asobeast normalizes each phrase, drops the empties and removes the duplicates before it tracks anything, so Focus Timer, POMODORO ,pomodoro reads back as focus timer,pomodoro. Spacing and casing can differ from what you submitted, a repeated phrase stays where it first appeared, and the character count is the count of the normalized set. Accented letters are stored in their composed form, so zażółć pasted as decomposed text, which macOS copy and paste can produce, is tracked and counted the same as zażółć typed directly. The phrases keep the order of the latest submission. phrases is the whole field in that order; tracked is those of its phrases tracked and active in country.
  • A save is held to the 100 character limit. App Store Connect counts the keyword field in characters, not bytes. asobeast counts Unicode code points, so a letter such as ą and a Chinese, Japanese or Korean character each count once, including the rarer Han characters outside the Basic Multilingual Plane such as 𠮷. Apple does not document how App Store Connect counts an emoji sequence or a letter written with combining marks, so asobeast counts each of their code points: a flag is two and a family emoji joined by zero width joiners is five. The limit is measured on the normalized set, the same count charactersUsed reports, so spacing and duplicates in the submitted text do not count against it. A save whose normalized set runs past 100 characters answers 400 and changes nothing. A single tracked phrase is held to 100 characters counted the same way, so a phrase of 51 such Han characters can be tracked.
  • A field belongs to a localization, and you choose where its phrases are tracked. The per-localization save takes text and trackIn, the markets in which to track every phrase of the field. trackIn may name only markets of the app whose storefront reads the localization, or the request answers 400 naming the country, and it may be empty, which stores the field and tracks nothing. A phrase dropped from the field stops being tracked as KEYWORD_FIELD in every market that reads the localization, whatever trackIn says, unless another field read there still holds it. The storefront shaped save keeps its old meaning: localization must be one the country storefront reads, or the request answers 400 naming the ones it reads, omitted it is the storefront’s default, and the phrases are tracked in country only. The German field saved from Austria is the same field Germany reads. See How does asobeast keep a keyword field per localization?
  • A preview writes nothing. POST .../preview takes text and answers, for every market of the app that reads the localization, the phrases it would add, the keyword markets it would open and the daily store requests they cost, plus the phrases that join or leave the field and your plan’s keyword market quota. It creates no keyword, spends no on demand allowance and works with a read only token. It answers the same 400 a save would for invalid input.
  • A save records the localization as shipped. Both save routes add a non-empty field’s localization to the list GET /apps/{id}/localizations reads. See Which localizations does an app ship?
  • duplicatesRemoved is 0 on a read. It reports what the last submission discarded, and a read submits nothing.
  • A save never untracks a keyword something else tracks. A phrase already tracked from the title, the subtitle, the short description or a manual add joins the field without losing that source, and the API reports it as KEYWORD_FIELD while it is in the field. A later save that leaves it out only takes it out of the field, so it stays tracked under its own source. A phrase that only a field tracks is deactivated, in every market that reads the localization, when a save leaves it out and no other field read there holds it. Adding such a phrase manually or reactivating it makes it a manual keyword, and a snapshot that finds it in the title, subtitle or short description gives it that source.
  • Untracking a keyword leaves the field alone. The field is what you submitted in App Store Connect, so DELETE /apps/{id}/keywords/{keywordId} stops tracking the phrase in that market and keeps it in phrases, and charactersUsed still counts it.
  • The last save wins. Saves to one app are written one at a time, so two saves that overlap never merge: the field holds the phrases of whichever save was written last. Each save answers with the field as it was stored when that save finished, so a save that overlapped another may be answered with the other save’s phrases.
A localization that has no saved field reads as an empty result with 0 characters used rather than a 404, because an empty field is a normal state. A localization tag outside the 50 answers 400 naming it. Removing a localization that is not on the list answers 404, and removing the home localization answers 409. A Google Play app refuses every operation on this page with 400.

Developer replies

Each store shows one public developer reply under a review, and the developer can edit it. A review is replied when the store shows a reply, when you posted one from the reviews page, or when you marked it as replied there. On the App Store asobeast cannot read a reply posted in App Store Connect, so only a post from asobeast or the mark counts. A Google Play review edited after the reply the store shows is updated after reply instead, because the reviewer changed it once the reply was public. The counter in the composer counts characters the way the stores count them, so a letter such as ą or a Chinese, Japanese or Korean character counts once. See Reply to reviews.

Why is the Google Play short description its indexed surface?

The 80 character short description, called summary in the store payload, is Google Play’s equivalent of the surfaces Apple splits across a subtitle and a keyword field. asobeast treats it accordingly.
  • Its keywords are tracked automatically with the source DESCRIPTION.
  • The metadata workbench lints it against the 80 character limit.
  • Keyword coverage counts it as an indexed field.
The store page escapes some characters in the short description, so Math & Music arrives as Math & Music. asobeast stores the short description as the plain text a user reads, keeps the payload exactly as received in raw, and counts characters the way Google Play does. An upgrade decodes short descriptions already stored and pauses the auto tracked keywords an escape produced, such as amp music, keeping their history.

How are auto tracked keywords chosen?

On import and on every refresh, asobeast reads the words of the title and of the subtitle (App Store) or the short description (Google Play), and tracks up to 15 phrases of one to three words. Title phrases come first, then longer phrases before shorter ones. Stopwords such as app, free and best are skipped, and so are words of one character. A listing outside the English storefronts also skips the function words of its own language, as described below. A word with an apostrophe is read as the word it contracts. The ending of you've, it's, we'll and I'm is dropped, so RPG you've been waiting for! gives rpg waiting and never ve, and a possessive such as Kid's Games gives kid games. A negated auxiliary such as don't or can't is dropped like a stopword. A number written with a separator between its digits, such as 10,000, 1.000, 2.0, 24/7, 10:30, or 10 000 with a non breaking space, is a quantity and not a keyword. It is dropped together with a unit of up to three letters written right after it, as in 3.5mm or 2.4GHz, and ends the phrase before it, so 10,000+ magazines in one app never gives 10 or 000. A longer word written right after it stays a keyword, so 10,000Songs gives songs. A number that is part of a word keeps that word, so Web3.0 gives web3. A number without a separator, such as 2048, 3D or 100+, is kept. A plain space between digit groups is not read as a separator, so 10 000 typed with a plain space still gives 10 and 000. Function words are skipped in the languages of the storefront. Next to English, asobeast reads the Spanish, Portuguese, French, German, Italian, Dutch, Swedish, Norwegian, Danish, Finnish, Polish, Turkish, Indonesian, Romanian and Czech lists, and it applies a list only to the storefronts that read that language. A language without a list is not filtered. That includes Russian, Ukrainian, Arabic, Hebrew, Greek and Hindi, so a Russian storefront and a Russian review keep their function words. A Mexican, Argentine or Colombian storefront skips de, la, el, en, para and tu, a Swedish one skips och, det and att, and a Swiss or Belgian storefront skips the words of each language it is read in.
  • The language comes from the storefront, not from the text. us, gb, au and the other English storefronts keep reading English only. On the App Store, Canada, Belgium, Switzerland and Luxembourg read each of their languages. A stored native localization, such as the French listing of ca, is read in its own language, and the default listing in the languages that have no localization of their own, so the English default of an app with a French listing in Canada is read as English. On Google Play a storefront reads the one language asobeast asks the store for, so Canada and Belgium read English and Switzerland reads German. A storefront asobeast has no language for reads English only.
  • A skipped word leaves the phrase, as an English stopword does. Juegos de Trivia gives juegos trivia, juegos and trivia, and never de, juegos de or de trivia.
  • Only function words are skipped. Articles, prepositions, conjunctions, pronouns, possessives and the common forms of to be and to have. A word that is also a name stays, so IO, UNO, Contra, Pro, ELLE and NU.nl are kept, and so is the first person possessive that opens a name such as Mi Claro, Mein Vodafone or Mijn KPN. A function word that is also an English keyword, such as men or care, stays too, because many listings in these storefronts are written in English.
  • Review text skips a few more. A name never appears in a review, so keyword ideas and review themes also skip the French mon, ma, mes and sans and the German hat and war, which a listing keeps for names such as Mon Orange and for English keywords such as war. See Mine reviews for keyword ideas.
  • A review is read in its own language too. asobeast guesses the language of each review from its script and its words, and skips that language’s function words next to the storefront’s. When a short review matches two languages equally, such as Spanish and Portuguese on como and que, it skips both lists, so Que mal servicio offers mal servicio and never que. A review that matches no word of any list is read with the storefront’s languages only, and a language without a list is not filtered, as the paragraph above says.
  • An accent makes a different word. te is skipped and té, tea, is kept.
  • An elided article is skipped with its word. qu'il is read as qu and il, and dell'Italia as dell and Italia, so qu, il and dell are skipped and italia stays.
Japanese, Chinese, Thai, Lao, Khmer and Burmese have no spaces between words, so asobeast splits them with the word segmenter that ships with the runtime, Intl.Segmenter, and joins the words of a phrase without spaces, the way a person types it in the store.
  • In these scripts a phrase never crosses a space, a dash or a punctuation mark. メルカリ and フリマアプリ in a title are two keywords, never one joined keyword.
  • Store noise words at the start and end of a run are removed first. 無料アプリ gives no keyword at all, and 無料ゲーム gives ゲーム.
  • A hiragana run of five characters or fewer stays whole. The segmenter cuts hiragana into pieces it cannot tell from grammar, so ふりま and ぐるなび are kept as one keyword each, and しまむら公式アプリ gives しまむら. Any other short run is split like a long one, so 天気予報 gives 天気予報, 天気 and 予報, and 猫のゲーム gives only ゲーム. A short Chinese title with a word such as 我的 in it is kept whole as well, so 我的世界 is a keyword next to 世界.
  • A grammar word ends a phrase. Hiragana only fragments, single character Chinese particles such as 的 and 和, and a short list of Japanese, Chinese and Thai noise words are dropped, and a phrase is never built across them. The Chinese particles apply only to text without kana, so a Japanese title keeps 東京都 and 就活. A word written in hiragana inside a longer run is dropped with them, because the segmenter cannot tell it from grammar, so ひまつぶしゲーム gives only ゲーム.
  • Thai is split with a word list first. The segmenter cuts many Thai words into syllables, so สนามบิน (airport) would come out as สนาม and บิน and a phrase could start or end inside a word. asobeast splits Thai with the word list of the PyThaiNLP project, about 62,000 words dedicated to the public domain under CC0, together with a few store words the list lacks, such as แอป, ช้อป and เดลิเวอรี่. The segmenter only splits the text the list does not know. A compound the list knows is one keyword, so แอปสั่งอาหาร gives สั่งอาหาร and not สั่ง and อาหาร.
  • A Thai function word ends a phrase, and a Thai prefix starts a word. Words such as ด้วย, ไป and กับ are dropped like stopwords, and การ, ความ, นัก and ผู้ join the word after them. So จองการเดินทางไปสนามบินล่วงหน้า gives the phrases จองการเดินทาง and สนามบินล่วงหน้า and the words จอง, การเดินทาง, สนามบิน and ล่วงหน้า, and never จองการเดิน or สนามบินล่วง.
  • A single Chinese or Japanese character stays with its neighbours. Two or more in a row form one word, as in 畅聊. A lone one never stands alone and can end a phrase, so 家計簿 is kept and 簿 is not offered. It starts a phrase only at the very start of a run, as in 新機能 and 筋トレ, and not after a Latin word, so iPhone用カメラ gives カメラ. Brand names the segmenter cuts into single characters are joined back this way, so 微信, 淘宝 and 小红书 stay whole.
  • A phrase of two or three words is at most 10 Chinese or Japanese characters, or 20 letters in Thai, Lao, Khmer and Burmese. A letter counts together with its vowel and tone marks, so สั่งอาหารออนไลน์ is a phrase. A single word is never cut, so a long loanword stays whole.
  • A katakana word that the segmenter splits is joined again. A piece of one or two characters, or one that starts with a small kana, ン or ー, joins the katakana before it. A piece that ends in ッ, a two character piece that ends in ー, a single character at the start of a katakana run, and a piece joined from such pieces that is still two characters or fewer join the katakana after them. So スマホ is not offered as スマ, ネットフリックス and ユーチューブ stay whole, and プリティーダービー gives プリティー and ダービー and never プリ or ティー. A two character word the segmenter returns whole, such as ヨガ in ヨガレッスン, stays a keyword of its own.
  • Latin words in the same listing form phrases as usual. A Latin brand next to Japanese text is its own phrase.
Neither the segmenter nor the word list knows every word. A brand written in Thai letters still comes out in syllables, so ลาซาด้า gives ลา and ซา next to ลาซาด้า, and a katakana word cut into pieces of two characters and more, such as ダンジョン or ソーセージレジェンド, comes out in pieces too. Pause such a fragment on the keyword monitor. Arabic is written with spaces, but a conjunction and an article attach to the word after them. asobeast drops the noise words it knows, and also the same word after the conjunction و, so وأكثر goes with أكثر. It keeps every other word that begins with و, because many Arabic words do, such as وقت and واتساب, and it never strips the article ال. A keyword like وطعام therefore stays as it was written. The tatweel and the short vowel marks are ignored when a word is compared with the noise words, so وأكـثر and أَكْثَر are dropped as well, and a keyword that stays keeps the marks it was written with. Korean keeps its spaces, so a particle attached to a word, as in 메신저를, also stays attached. asobeast has no morphological analysis for Korean or Arabic. The metadata lints, the ASO audit, the review phrases and the keyword combinations card still read words between spaces, so on a Japanese, Chinese or Thai listing they treat a run of text as one word. The audit can therefore call a keyword missing from the title that the coverage table shows as covered. Keyword coverage, on the metadata workbench and on the overview, and keyword relevance find such a keyword anywhere in the listing, so a keyword tracked from a listing counts as covered by it and earns its full relevance. See Check keyword coverage and Where does relevance start? An upgrade does not change keywords already tracked. The next refresh of an app, which the daily run performs, adds the cleaner keywords next to the sentences and function words an earlier version tracked, and those stay active until you pause or remove them on the keyword monitor.

What stays Apple only?

The subtitle and the keyword field. On a Google Play app they carry audit weight 0 and are hidden in the web app rather than shown empty, and the Action Center skips rules that would recommend an impossible edit.

Are scores comparable across stores?

No. Popularity and difficulty are derived from different public evidence on each store, so an Apple difficulty of 60 and a Google Play difficulty of 60 do not mean the same thing. Compare a keyword against other keywords in the same store. See Popularity, difficulty and opportunity.

Where else do the stores differ?

What happens when a store changes its response?

A parser breaks, for every installation at once. Only the provider layer parses store responses, so the break is one module, failed jobs stay contained, and no history is lost. See Recover from a broken store parser.

Why does a Google Play job cost more?

Because one logical job fans out to many requests. A Google Play score job makes 12 to 20 sequential requests: one search, one to nine suggest probes and ten detail enrichments. An Apple score job makes 3 to 11: one search, one to nine suggest probes and one lookup of the phrase followed by a space, which counts the searches that continue it. A keyword the store never suggests costs a single probe, plus that lookup on the App Store. A depth 200 Google Play position check takes roughly eight requests against one for Apple. That is why SCRAPE_GPLAY_RPM spaces job starts rather than individual requests, and why its default of 10 is lower than the Apple default of 15. See The daily pipeline and rate limits.
Last modified on October 24, 2026