| name | app-store-optimization |
| description | App Store Optimization (ASO) for iOS App Store and Google Play — keyword research and placement, metadata writing within exact character limits, screenshot/icon/preview conversion, review tactics, competitor intelligence, localization, A/B testing, and store-policy compliance, with App Store Connect API (asc CLI) and iTunes Search API recipes. Use when asked to improve app discoverability, rank for keywords, optimize a title / subtitle / keywords field, audit a listing, or raise install conversion. Triggers: "ASO", "keyword research", "rank in the app store", "optimize my app listing", "app store keywords", "screenshot conversion", "increase installs", "will this get rejected". |
App Store Optimization (ASO)
ASO is search-engine + conversion-rate optimization for app stores. Two
levers move installs:
- Discoverability — getting your listing to appear for the searches
real users type. Driven by indexed metadata fields and keyword choice.
- Conversion — turning an impression into an install. Driven by icon,
title, subtitle, the first three screenshots, rating, and social proof.
Optimizing the wrong field wastes effort. The single most important fact in
all of ASO: on iOS the description is NOT indexed. Never put keyword
work there — it does nothing for ranking. (On Google Play the full
description is indexed; see below.) This asymmetry drives almost every
platform-specific rule.
This skill works in two modes:
- Local / pre-submission: run inside an app project, auto-detect
Fastlane metadata, Xcode, or Gradle, and audit/optimize the metadata you
are about to ship.
- Remote / live: pass an app ID or store URL to fetch and audit a live
listing — your own app, or a competitor's.
The golden rules (violate any one and you waste real money)
These are absolute. Never recommend a change that breaks one.
- iOS Name + Subtitle + Keywords are one shared index pool. Apple
indexes all three independently, then de-duplicates. Never repeat a
word (or its stem) across these three fields — a repeat wastes premium
character budget for zero extra ranking. (
couple in the subtitle AND
in the keywords field = one word's worth of budget thrown away.)
- Character budget = money. Use it all. Fill Name to ≥15 chars
(CJK exempt — each character carries more meaning), Subtitle to ≥20,
and the iOS keyword field to 95–100 of its 100. Empty space is lost
ranking surface.
- iOS description is not indexed — optimize it only for conversion.
Lead with the value proposition; the first ~3 lines show before the
"more" tap. Stuffing keywords here is pure waste.
- Same language, different storefronts each get their own 100 chars.
en-US / en-GB / en-AU / en-CA are four independent keyword fields.
Use four different keyword sets — never copy the same string into all
four. The same applies to fr-FR/fr-CA, es-ES/es-MX, zh-Hans/zh-Hant,
pt-BR/pt-PT.
- "Category match ≠ function match." This is the most-missed trap. A
keyword whose top-ranked apps are in your category but serve a
different function is poison: users search it, land on you, see the
wrong thing, and bounce. Low conversion on a term tells Apple's
algorithm the term is a bad fit and demotes your whole listing, not
just that term. Prefer an empty keyword slot over a function-mismatch
word. (Detection method in references/keyword-research.md.)
- Avoid category-giant monopoly words. Single high-volume words
(
face, dating, generator, avatar, ring) are owned by giants
with millions of ratings. A vertical app gets zero impressions for them
and burns the characters. Go long-tail and specific.
- Transliteration traps drain non-English budget. English loanwords
transliterated into another language (
vintage, retro, romantic)
have near-zero local search volume. Use native search terms instead
(table in references/localization-aso.md).
- Screenshot caption text is a conversion asset first. Some markets
may extract caption text as a secondary discovery signal, but treat
captions as primarily for conversion — clear, benefit-led, localized —
unless you have current store evidence that captions move discovery in
your market. (A June-2025 caption OCR-indexing change is widely reported; if
confirmed in your market, captions become a second keyword surface and Apple
reportedly OCRs the top/bottom of the shot — but keep this hedge intact.)
- Verify after every write. App Store Connect can accept a malformed
update (HTTP 200) yet store nothing, or you can re-introduce a
cross-field conflict by keeping an old field while writing a new one.
Always re-run the audit immediately after pushing metadata.
Recent platform shifts (dated)
- New-app boost eliminated — Apple removed the artificial first-1–2-week
visibility lift for new apps. External traffic (paid/social/PR) from day 1
is now required to seed relevance; you can't coast on a launch bump.
- Custom Product Pages: up to 35 per app, organic-keyword-assignable since
2024 (previously paid Apple Search Ads only) — each CPP can target a
different long-tail cluster. Details in references/category-playbooks.md.
- Caption OCR-indexing (June 2025, reported) — see golden rule #8; treat as a
dated data point, not a license to keyword-stuff captions.
Running ASO with an LLM — avoid self-contamination
When one model both researches and decides ASO, its own prior conclusions /
session memory / "regional flavor" intuitions are the dominant pollution
source — it fabricates plausible-but-wrong keywords. Countermeasures:
- Isolate research from decision. Run keyword/feature analysis as an
independent pass that is forbidden from reading any prior ASO report (move
old
ASO_*.md / *Market_Research*.md / .aso/ files out of reach first);
let the orchestrating model only do mechanical execution + data passing.
- Never trust model intuition for locale words. Any candidate not validated
via iTunes Search (or marked
untested after a throttle) must be validated
before shipping — never extrapolated. Real failure: a model invented
boho/winter/cottage/maple for en-AU/en-CA; iTunes testing showed all
were function-mismatches.
Platform metadata quick reference
iOS App Store
| Field | Limit | Indexed? | Update needs review? | Use for |
|---|
| App Name | 30 | YES — highest weight | Yes | Brand + #1 keyword |
| Subtitle | 30 | YES — high weight | Yes | #2–#3 keywords / benefit |
| Keywords field | 100 | YES — medium weight | Yes | All remaining unique terms, comma-separated, no spaces |
| Description | 4,000 | NO | Yes | Conversion copy only |
| Promotional Text | 170 | NO | No — instant | Seasonal / limited-time messaging |
| What's New | 4,000 | NO | Per-version | Update notes |
| IAP display names | — | YES — low weight | Per-IAP | Bonus keyword coverage |
Limits count Unicode codepoints, not bytes — one CJK character = 1, one
emoji can be 1–2. Keyword field format: kw1,kw2,kw3 — no space after
commas (each space wastes a character).
Google Play
| Field | Limit | Indexed? | Use for |
|---|
| Title | 30 | YES — highest weight | Brand + primary keyword (natural language) |
| Short Description | 80 | YES — medium-high | Secondary keyword + benefit |
| Full Description | 4,000 | YES — high weight | Primary keyword in 1st sentence, 2–3% density |
| Developer Name | — | YES — low | Branding |
| What's New | 500 | NO | Update notes (shorter than iOS) |
Google uses NLP/semantic matching and penalizes unnatural keyword
stuffing. Additional Play ranking signals grep can't see in the listing:
user-review text (indexed), backlinks to the Play page, and
Android Vitals (ANR <0.47%, crash rate <1.09%) — poor vitals directly
reduce visibility.
Full field specs, indexing nuances, and per-device visual sizes live in
references/metadata-specs.md.
Auto-detection (local mode)
When no app ID is given, detect the project first. Look for, in priority
order:
| Source | Detects | Files |
|---|
| Fastlane iOS | per-locale name, subtitle, keywords, description | fastlane/metadata/<locale>/{name,subtitle,keywords,description,promotional_text}.txt |
| Fastlane Android | per-locale title, short/full description | fastlane/metadata/android/<locale>/{title,short_description,full_description}.txt |
| Xcode | bundle ID, app name | *.xcodeproj/project.pbxproj, Info.plist |
| Gradle | application ID, app name | app/build.gradle, AndroidManifest.xml, res/values/strings.xml |
Fastlane metadata is richest (all fields available). Xcode/Gradle give only
identifiers — extract the app ID and optionally fetch the live listing.
For iOS shops using App Store Connect directly (no Fastlane), pull current
metadata with the asc CLI — see references/app-store-connect-cli.md.
Audit orchestration flow
When asked to audit a listing (/aso audit <app-id> or a local project),
run this pipeline:
-
Fetch / detect the listing data → structured per-locale metadata.
-
Classify category (gaming, SaaS/productivity, health/fitness,
e-commerce, social, fintech, …) to load the right benchmarks and
templates from references/category-playbooks.md.
-
Run mechanical checks (these are free and deterministic — see the
audit logic in references/keyword-research.md):
- character budget per field (codepoint count vs limit)
- cross-field stem overlap (Name+Subtitle vs Keywords)
- cross-locale duplication (same-language storefront pools)
- transliteration-trap words per locale
- keyword field format (no spaces after commas, no app-name repeats)
-
Run analytical passes — keyword coverage, metadata quality, visual
assets, reviews/ratings, competitor gap, conversion signals, technical
health, localization. For a big listing these are independent and can be
dispatched as parallel sub-agents (one per dimension), each returning a
scored sub-report.
-
Score a weighted ASO Health Score (0–100):
| Dimension | Weight |
|---|
| Keyword optimization | 20% |
| Metadata quality | 20% |
| Visual assets | 15% |
| Reviews & ratings | 15% |
| Competitive position | 10% |
| Technical health | 10% |
| Conversion signals | 10% |
-
Generate two outputs:
- Audit report — score, platform, category, top issues, per-dimension
findings.
- Action plan — prioritized Critical → High → Medium → Low (severity
mapping in references/quality-gates.md).
Keyword research — the validation loop
You do NOT need a paid tool (AppTweak / Sensor Tower) to do real keyword
research. The free, current stack:
-
iTunes Search API (public, no key) — returns the real top-ranked
apps for any term in any storefront. This is how you detect the
"category-match ≠ function-match" trap (golden rule #5): look at what
the top 5 apps for a candidate keyword actually do, and compare to
your app's function.
curl -s "https://itunes.apple.com/search?term=<KEYWORD>&country=us&entity=software&limit=5" \
| python3 -c "import json,sys;[print(a['trackName'],'—',a.get('primaryGenreName')) for a in json.load(sys.stdin)['results']]"
-
Apple Search Suggestions — Apple's own autocomplete (the strongest
App-Store demand signal): search.itunes.apple.com/.../hints?clientApplication=Software&term=<partial>
(see references/competitor-intelligence.md).
-
Google Suggest — keyless cross-platform corroboration:
https://suggestqueries.google.com/complete/search?client=firefox&q=<term>&hl=<lang>&gl=<country>
— data[1] is the completions list; completion-count is the reliable proxy
(Google Trends/pytrends is reliably 429-throttled — best-effort only).
-
App Store Connect Analytics — your own actual traffic-driving
search terms (the ground truth for what's already working).
Throttle caveat: the iTunes Search API trips 403/429 under parallel load
(N sub-agents from one IP). When throttled, mark a candidate untested and
validate later — never extrapolate or invent regional words.
Apple Search Ads (ASA) API does NOT expose a public keyword-popularity /
search-volume endpoint (verified 2026; the searchPopularity field only
exists inside ASA Custom Reports, whose GET has returned 403 since
2026-03-16 as Apple migrates to the Insights API). Do not promise users a
volume number from the ASA API — use the free signals above instead, and if
they run ASA campaigns, the in-console Search Match / keyword recommendations
are the practical popularity proxy.
Full keyword methodology — the three-layer candidate gate, the
function-mismatch procedure, the Opportunity Score ranking, the runnable
mechanical audit (scripts/aso_audit.py), script-aware tokenization, and
the monopoly/giant word lists — is in references/keyword-research.md. Deeper
competitor/review research (reviews RSS, ratings histogram, Apple Suggest) is in
references/competitor-intelligence.md.
Conversion rate optimization
Conversion benchmarks (2025–2026): iOS ~25%, Google Play ~27% average, but
category variance is huge (10–115%+). Audit the first impression —
everything a user sees before scrolling or tapping "more":
- iOS search result: icon, name, subtitle, rating, first 3 screenshots,
Get button.
- Play search result: icon, title, developer, rating, Install button.
Score conversion 0–100 weighting: first-3-screenshots 25%, title clarity
20%, rating strength 20%, social proof 15%, subtitle/short-desc 10%, icon
appeal 10%. Psychology levers to evaluate: social proof, authority (awards,
Editor's Choice), specificity (concrete numbers beat vague claims), benefit
framing (outcomes, not features). Detailed scoring rubric, screenshot
narrative arc, and icon rules: references/conversion-and-visuals.md.
A/B testing
iOS Product Page Optimization tests visuals only (icon, screenshots,
preview video — NOT title/subtitle/keywords/description), max 3 treatments + original,
7–90 days. Google Play Store Listing Experiments also test text (short/full
description), up to 5 localized + 1 main, 7-day minimum. Change ONE element per
test, make it meaningful, aim for ~1,000+ views/variant and ≥90% confidence;
primary metric is install conversion rate; test screenshots first, then icon.
Full table, hypothesis template, and roadmap: references/conversion-and-visuals.md.
Localization
Don't localize every storefront — prioritize by iOS penetration and spend.
Per-locale keyword research, not translation — translating your en-US
keywords gives words nobody searches. Exploit the cross-indexed locale
matrix (e.g. a US storefront also indexes several other locales' keyword
fields) to pack overflow terms for free. Watch for transliteration traps
and cultural fit. Market tiers, the cross-index matrix, transliteration
tables across 8+ languages, and ASC-unsupported locales:
references/localization-aso.md.
Compliance — will this get rejected?
Run a policy pass on any metadata you recommend, both your current values
and proposed changes. The high-frequency rejection causes:
- Google Play title banned words:
#1, best, top, free, new,
sale, download now, install now, etc. No emojis, no ALL CAPS.
- Both stores: no competitor brand names in any field (Apple
strengthened this in Nov 2025 — no competitor icons/brands/names);
no other-platform names ("Android" on iOS); no pricing terms.
- Screenshots: must show actual app UI; no promo text overlays
("#1", "Best", "Sale") on Play.
- Category gates: health apps need disclaimers + no unvalidated
sensor measurements; finance apps must complete Google's financial-
features declaration (mandatory since Oct 2025); AI apps must disclose
third-party AI data sharing (Apple, Nov 2025) and offer in-app reporting
of generated content (Google, Jul 2025).
Full policy matrix with guideline references and the complete banned-words
list: references/store-policies.md.
Scope note: this skill covers discoverability and conversion metadata,
including screenshot framing/rendering (references/screenshot-rendering.md
— chrome decision, bezel install, aspect-ratio crop, captions, the
scaffold→AI-enhance pipeline). For the binary submission, build upload, and the
full pre-submission review checklist, see the companion app-review-preflight
skill — don't duplicate that work here.
App Store Connect write workflow (asc CLI)
To push optimized metadata to a live iOS listing, use the asc CLI. The two
gotchas that silently fail:
- Multi-line fields (description, What's New) must use
asc raw PATCH
with a JSON body file — passing \n through shell args returns HTTP 200
but stores empty content.
- A FAILED screenshot upload blocks submission ("screenshots still
uploading") until you
raw DELETE it.
Pull → edit → push → re-audit recipes, plus the exact localizations update, metadata pull/push, screenshot upload, and resource-ID lookup
commands: references/app-store-connect-cli.md.
Output conventions
- Audit report and Action Plan as separate markdown files; action
items grouped Critical/High/Medium/Low with the offending field and the
exact recommended value.
- Keyword maps show the proposed per-field strings with live codepoint
counts (e.g.
Name: "Snap — AI Couple Photos" (24/30)).
- Always state which fields require app review (1–3 days on iOS) vs which
are instant (iOS promotional text, all Play text).
Reference files (load on demand)
| File | Contents |
|---|
| references/metadata-specs.md | Full iOS + Android field specs, indexing rules, visual-asset sizes per device |
| references/keyword-research.md | Seed expansion, intent, the function-mismatch detection method, mechanical audit checks, giant/monopoly word lists |
| references/quality-gates.md | Hard thresholds, Critical→Low severity mapping, density bands, scoring labels |
| references/localization-aso.md | Market tiers, cross-indexed locale matrix, transliteration + face-swap tables, full 39-locale set, ASC-unsupported locales |
| references/store-policies.md | Apple + Google policy matrix with guideline refs, banned-words list, category-specific gates |
| references/category-playbooks.md | Per-category keyword themes, benchmarks, 4-phase roadmap, launch checklist, seasonal calendar, In-App Events + Custom Product Pages, review/rating-prompt tactics |
| references/conversion-and-visuals.md | Conversion scoring, screenshot narrative, icon rules, A/B test design, launch-velocity tactics |
| references/screenshot-rendering.md | How to render/frame screenshots: chrome decision, bezel install, aspect-ratio crop, file prep, panoramic, captions/fonts, scaffold→AI-enhance, source-capture QA |
| references/competitor-intelligence.md | Off-device iTunes/App Store API toolkit: reviews RSS, ratings histogram, Apple Suggest, chart feeds, bundle/developer lookup, storefront/genre IDs |
| references/app-store-connect-cli.md | asc CLI pull/push recipes + env-var auth / auth doctor / capabilities, raw PATCH for multi-line fields, screenshot upload, pre/post-write verify |
scripts/aso_audit.py | Runnable mechanical audit (budget, cross-field stem, CJK substring, cross-locale dup, traps, format); offline JSON or live asc; exits non-zero on ERROR |
scripts/itunes_search_check.py | iTunes Search competition check — result-count bands + top-5 + aggregate ratings |
scripts/google_signals.py | Google Suggest (+ best-effort Trends) demand corroboration |