Automating App Store Optimization with an AI Agent and asc CLI

Storyie Engineering Team
9 min read

How the Storyie team offloaded ASO keyword research, multi-locale metadata drafting, and monthly review cycles to an OpenClaw AI agent paired with the asc App Store Connect CLI — without giving up human sign-off.

ASO is the task indie developers know they should do and almost never make time for. Keyword research, multi-language metadata, periodic refresh when the app changes — each step is well-defined, repetitive, and deeply unglamorous compared to shipping features. For Storyie, we already had an OpenClaw AI agent running in the codebase handling development tasks. This post is about extending that same setup to cover ASO: using asc CLI as the interface to App Store Connect and the agent as the reasoning layer on top.

TL;DR

  • Organic search drives the majority of App Store installs for a zero-ad-budget indie app. ASO is not optional.
  • asc is a Go CLI for App Store Connect with JSON-first output — well-suited to agent use.
  • The agent reads the app's locale files directly, so keyword and metadata suggestions reflect what the app actually does.
  • A --dry-run gate before every submission keeps a human in the loop without slowing the draft cycle down.
  • We automated research, drafting, and scheduling. Final sign-off stays with a person.

Automation layer

Tool

What it does

Metadata fetch

asc localizations list

Pulls current title / subtitle / keywords / description for all locales

Keyword research

OpenClaw + web search

Generates candidates from locale files and competitor signals

Draft generation

OpenClaw

Writes locale-specific copy respecting Apple's character limits

File structure

OpenClaw

Produces the metadata directory tree asc expects

Submission preview

asc release run --dry-run

Shows the diff before anything changes

Submission

asc release run --confirm

Applies after human review

Monthly review

Cron job

Re-runs the whole cycle, compares against codebase changes

Why ASO matters for indie apps

The App Store has millions of apps. Research consistently puts the share of installs coming from search at well above 60%. For an app with no ad spend, organic search is the entire acquisition funnel. The frustration is that meaningful ASO involves tasks that feel like admin work:

  • Finding keywords with decent volume that large apps haven't already locked up.
  • Writing distinct copy for every supported locale — not just translated, but optimized for how users in that market actually search.
  • Revisiting all of the above whenever a feature ships.

The third point is the one that almost never happens in practice. You optimize at launch, and then the metadata drifts while the product moves on.

What asc CLI is

asc is an unofficial CLI for the App Store Connect API. Install via Homebrew or the install script:

# Homebrew
brew install asc

# Install script
curl -fsSL https://asccli.sh/install | bash

It covers most of what the App Store Connect web UI can do: TestFlight, builds, submissions, signing, analytics, screenshots, subscriptions. For ASO the relevant surface is metadata and localizations — fetching the current state, and updating it.

The design characteristic that makes it useful for agent workflows: in non-interactive contexts (pipes, CI) it defaults to JSON output. No screen-scraping required.

# Explicit JSON output
asc apps list --output json

Set up authentication once with your App Store Connect API key:

# App Store Connect > Users and Access > Integrations > API Keys
# Key type: Individual, Role: App Manager or higher

asc auth login \
  --name "Storyie" \
  --key-id "XXXXXXXXXX" \
  --issuer-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  --private-key ./AuthKey_XXXXXXXXXX.p8

After that, asc apps list just works, and the agent can call any asc command without re-authenticating.

Architecture: agent + CLI

The setup is deliberately simple:

┌────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│   OpenClaw     │────▶│  asc CLI         │────▶│  App Store      │
│   AI Agent     │     │  (asc commands)  │     │  Connect        │
│                │◀────│                  │◀────│  (metadata)     │
└────────────────┘     └──────────────────┘     └─────────────────┘
        │
        ▼
┌────────────────┐
│  Codebase      │
│  (locales/*)   │
└────────────────┘

The part that makes this better than a generic ASO tool: the agent can read the codebase. It sees the actual feature set, the terminology used in-product, and the in-app translations — all before writing a single word of store copy.

Keyword research without a paid tool

The standard approach to ASO keyword research is subscribing to App Annie or Sensor Tower at somewhere between $100 and $500 a month. That is not a realistic line item for an indie project.

The alternative: generate candidates from the product itself.

Grounding candidates in the codebase

OpenClaw can read the app's locale files directly. Storyie's English locale lives in apps/expo/locales/en.ts:

// apps/expo/locales/en.ts
export default {
  translation: {
    // biometric auth, theme settings, export, AI features...
    // Each feature name is a keyword candidate
  },
};

Asking the agent to produce 50 keyword candidates from the feature list takes seconds and yields copy that is actually grounded in what the app does — not generic "journal app" phrasing that could describe any of hundreds of competitors.

Estimating volume without an ASO subscription

asc only covers your own app's data — it doesn't expose category rankings or competitor metadata. To layer in search volume signals, the agent uses web search to pull publicly available competitor descriptions and App Store category information. This is imprecise compared to Sensor Tower, but combined with the codebase-grounded candidates it produces a useful ranked list, especially for long-tail terms where competition is lower and precision matters less.

Managing metadata across 10 locales

Storyie supports 10 languages:

// app.config.ts
infoPlist: {
  CFBundleLocalizations: [
    "en", "ja", "zh", "es", "ar", "hi", "pt", "ru", "de", "fr",
  ],
}

That means 10 sets of title, subtitle, keywords, and description — all with Apple's character constraints (30 / 30 / 100 / 4000 respectively).

Pull the current state first

Before generating anything, the agent fetches what is already live:

# All localizations for the app
asc localizations list --app "YOUR_APP_ID"

# Full app info as JSON
asc app-info get --app "YOUR_APP_ID" --output json --pretty

This gives the agent the baseline to diff against — what has changed in the codebase since the last update, and which locales are out of date.

Localization, not just translation

The most common mistake in multi-locale ASO is running the English copy through a translation API and calling it done. The keyword field in particular needs to reflect how users in that market actually search, which is often different from a literal translation.

In Japanese, both "日記アプリ" (diary app) and "ジャーナル" (journal) see meaningful search volume. In English, "journal" outperforms "diary" by a wide margin. The agent prompt for localization makes this explicit:

Task: Optimize the following App Store metadata for {locale}.

Constraints:
- Use keywords that users in this market actually search for, not literal translations
- Title: max 30 characters
- Subtitle: max 30 characters
- Keywords field: max 100 characters, comma-separated
- Description: lead with the user's problem, then the solution — not a feature list

Current app features:
{contents of locales/en.ts}

Consistency with in-app language

Because the agent reads the locale files before writing store copy, it can flag mismatches automatically. If en.ts uses "Theme Settings" and a metadata draft says "Customization," the agent catches and corrects that before it reaches the dry-run step. This used to require a manual cross-reference; now it's implicit.

Updating metadata with asc CLI

Once the agent has generated copy it is satisfied with, it structures the output as the directory tree that asc release run --metadata-dir expects:

metadata/
├── en-US/
│   ├── name.txt
│   ├── subtitle.txt
│   ├── keywords.txt
│   └── description.txt
├── ja/
│   ├── name.txt
│   └── ...
├── zh-Hans/
│   └── ...
└── ... (10 locales)

Dry-run before every submission

This is the gate that keeps the automation safe:

# Preview exactly what would change
asc release run \
  --app "YOUR_APP_ID" \
  --version "1.2.3" \
  --build "BUILD_ID" \
  --metadata-dir "./metadata/version/1.2.3" \
  --dry-run

# Submit after human review
asc release run \
  --app "YOUR_APP_ID" \
  --version "1.2.3" \
  --build "BUILD_ID" \
  --metadata-dir "./metadata/version/1.2.3" \
  --confirm

The dry-run output shows every field that would change, per locale. A human reviews that diff before the confirm command runs. If anything looks wrong — a keyword that slipped in from the wrong locale, a description that is technically accurate but tonally off — it gets caught here without ever touching App Store Connect.

Checking submission status

asc status --app "YOUR_APP_ID"

Screenshots: still manual

asc can list existing screenshots and video previews:

asc screenshots list --app "YOUR_APP_ID"
asc video-previews list --app "YOUR_APP_ID"

We use this to audit coverage — which locales are missing screenshots for a given device class. But generating the screenshots themselves is still manual. Automated screenshot tools haven't reached a quality bar where we would trust them to represent the app in the store without human review of every frame.

Monthly review via cron

An OpenClaw cron job runs once a month and performs the full cycle:

Monthly ASO cycle:
1. asc localizations list → fetch current metadata for all locales
2. Compare against codebase locales/* → detect new features or changed terminology
3. If changes found → generate updated metadata draft
4. Send draft for human review before any submission

The trigger for a review is not the calendar — it is code changes. If no new features shipped and no terminology changed, the agent may find nothing to update. If a significant feature landed, the agent notices the gap between the codebase and the live store copy and surfaces a specific draft rather than a generic reminder.

What we decided not to automate

We did not aim for full automation. The deliberate omissions:

  1. Screenshots — The most persuasive element in a store listing. Automated generation is not there yet.
  2. Final submission — The --dry-run gate is cheap and prevents an entire class of hard-to-reverse mistakes. The cost of keeping a human in the loop at this step is negligible.
  3. A/B testing — Apple's Product Page Optimization already provides this capability natively. No reason to build a parallel system.

The division that emerged: agent handles research, drafting, structuring, and scheduling; a human handles final judgment on what ships.

What we learned

asc and AI agents are a natural fit. The CLI is non-interactive, JSON-first, and covers the full App Store Connect surface. There is no screen-scraping, no browser automation, no session management. The agent calls a command, gets structured data back, reasons about it, and calls the next command. That loop is easy to build and easy to audit.

Localization ROI is higher than it looks. Ten locales sounds like ten times the work. With an agent doing the drafting, the marginal cost per additional locale is close to zero. More locales means more keywords indexed across more markets — the total addressable keyword surface grows roughly linearly with the number of supported locales.

Long-tail keywords are where indie apps win. Competing on "diary app" or "journal" against apps with large review counts and established ranking is a losing proposition. The agent is good at generating large lists of specific candidates — "AI journal," "private diary with biometrics," "daily reflection app" — and those long-tail terms are where organic discovery actually happens for a smaller app.

ASO is a maintenance task, not a one-time setup. Shipping a new feature without updating the store description means users who would have found the app via that feature's keywords never see it. Wiring the review cycle to codebase changes rather than a fixed calendar makes it much more likely that metadata stays current.

Related Posts

Try Storyie

Storyie is available at storyie.com on the web and on the App Store for iOS. The ASO work described here is live — if you found the app through search, this pipeline had something to do with it.