CLI
Command-line interface for the Sonar REST API — every endpoint is covered. Works with any API key — new accounts get 50 free credits on signup, top up with prepaid packs, or subscribe to the Full plan for tracking and history. Install via npm or run with npx.
Commands marked write scope mutate your workspace and need an API key created with the write scope (Full plan — an active trial counts). Everything else works with the default read scope.
Installation
npm install -g @sonarapp/cliOr run without installing:
npx @sonarapp/cli <command>Authentication
Login
Prompts for your API key, validates it against the API, and saves it to ~/.config/sonar/config.json.
sonar auth loginCheck status
Shows your key prefix and remaining daily API quota.
sonar auth statusLogout
Removes the saved API key.
sonar auth logoutApps
List all tracked apps
sonar apps list{
"data": [
{
"id": "6a2b1e60-fa88-4816-a0e3-c0d3c042f478",
"store": "ios",
"store_id": "com.buzzfeed.tasty",
"name": "Tasty: Recipes, Cooking Videos",
"developer": "BuzzFeed",
"is_own": false,
"latest_snapshot": {
"rating": 4.9,
"review_count": 431859,
"version": "3.39.1"
}
}
]
}Get app details
sonar apps get <app-id>{
"data": {
"id": "6a2b1e60-fa88-4816-a0e3-c0d3c042f478",
"store": "ios",
"store_id": "com.buzzfeed.tasty",
"name": "Tasty: Recipes, Cooking Videos",
"developer": "BuzzFeed",
"category": "Food & Drink",
"is_own": false,
"added_at": "2026-02-12T12:56:14.318Z",
"latest_snapshot": {
"rating": 4.9,
"review_count": 431859,
"version": "3.39.1"
}
}
}Look up any app by store ID
Stateless — works on any app, tracked or not.
sonar apps lookup com.spotify.music --store android
sonar apps lookup 1450772168 --store ios --country gbSearch apps in a store
sonar apps search "meditation" --store ios --num 25ASO audit score
0-100 score with itemized checks (title length, keyword coverage, screenshots, …).
sonar apps score 1450772168 --store ios --tableExtract keywords from an app's metadata
sonar apps extract-keywords com.duolingo --store android --max 30Fetch app reviews
sonar apps reviews 1450772168 --store ios --sort helpful --min-rating 1 --max-rating 2 --limit 50Change history for a tracked app
Detected releases, metadata edits, screenshot swaps, price changes, and category moves.
sonar apps changes <app-id>
sonar apps changes <app-id> --type release --limit 20Untrack an app (write scope)
Stops tracking an app and removes its data. Confirms before deleting unless -f / --force.
sonar apps untrack <app-id>
sonar apps untrack <app-id> --forceProducts (write scope)
A product is the cross-store unit — one iOS app + one Android app, or just one of either. Creating a product starts tracking its app(s) and returns the app IDs used by the keyword and competitor commands.
List products
Lists your products with their linked apps and competitor counts (columns: id, name, country, #apps, #competitors).
sonar products list
sonar products list --tableCreate a product
sonar products create --ios 1450772168 --name "My App"
sonar products create --ios 1450772168 --android com.example.myapp --country usLink the second-store version
sonar products add-app <product-id> --store android --id com.example.myappTrack a competitor
sonar products add-competitor <product-id> --store ios --id 963034692Remove a competitor
Removes a competitor from a product. Auto-untracks the competitor app if no other app references it. Confirms before removing unless -f / --force.
sonar products remove-competitor <product-id> <competitor-app-id>
sonar products remove-competitor <product-id> <competitor-app-id> --forceDelete a product
Deletes a product and untracks its apps. Confirms before deleting unless -f / --force.
sonar products delete <product-id>
sonar products delete <product-id> --forceAlerts
Alert subscriptions email you when something changes — a rank drop, a competitor move, a review spike, and more. Each subscription is one alert type, optionally scoped to a single app (org-wide otherwise).
List alert subscriptions
Lists your alert subscriptions (columns: id, type, scope (app id or all), threshold, enabled).
sonar alerts list
sonar alerts list --tableCreate or update an alert subscription
Creates or updates a subscription for the given <type>. Omit --scope-app for an org-wide alert across all tracked apps; omit --threshold to use the per-type default. Subscriptions are enabled by default — pass --disabled to create one turned off. Types: rank_drop, rank_gain, entered_top10, left_top10, new_ranking, rating_drop, review_spike, competitor_change.
sonar alerts set rank_drop
sonar alerts set rank_drop --scope-app <app-id> --threshold 5
sonar alerts set review_spike --disabledDelete an alert subscription
Deletes an alert subscription. Confirms before deleting unless -f / --force.
sonar alerts delete <id>
sonar alerts delete <id> --forceKeywords
Search keywords
Returns autocomplete suggestions with difficulty scores and popularity estimates.
sonar keywords search "recipe app" --store ios
sonar keywords search "fitness" --store android --country gb{
"data": [
{ "keyword": "recipe app", "store": "ios", "country": "us", "difficulty": 77, "popularity": null, "results_count": 10 },
{ "keyword": "free recipe app", "store": "ios", "country": "us", "difficulty": 70, "popularity": null, "results_count": 10 },
{ "keyword": "mixology bartender recipe app", "store": "ios", "country": "us", "difficulty": 45, "popularity": null, "results_count": 10 }
]
}List tracked keywords for an app
Automatically paginates through all results.
sonar keywords list <app-id>Keyword metrics (single or bulk)
Difficulty + popularity for specific keywords. 1 credit each, up to 25 per call.
sonar keywords metrics "habit tracker" --store ios
sonar keywords metrics "habit tracker" "daily habits" "streaks" --store iosTrack keywords (write scope)
Starts daily rank tracking. Idempotent — re-posting the same terms reports them as already_tracked. Max 200 per call.
sonar keywords track <app-id> "habit tracker" "daily habits"
sonar keywords track <app-id> "rastreador de hábitos" --country mxSet or clear a keyword note (write scope)
The tracked-keyword id is the id field from sonar keywords list (not keyword_id).
sonar keywords note <tracked-keyword-id> "push for top 10 before WWDC"
sonar keywords note <tracked-keyword-id> --clearStar / unstar a keyword (write scope)
Marks a keyword as a favorite/target. Starred keywords show a ★ in sonar keywords list (table mode) and carry a starred_at timestamp in JSON output.
sonar keywords star <tracked-keyword-id>
sonar keywords unstar <tracked-keyword-id>Untrack a keyword (write scope)
Stops tracking one keyword/app pair. The id is the tracked-keyword id from sonar keywords list (not keyword_id). Confirms before deleting unless -f / --force.
sonar keywords untrack <tracked-keyword-id>
sonar keywords untrack <tracked-keyword-id> --forceBulk untrack keywords for an app (write scope)
Untracks multiple keywords at once. Pass exactly one of --ids (a comma-separated list of tracked-keyword ids) or --all (removes every tracked keyword for the app). Confirms unless -f / --force.
sonar keywords untrack-all <app-id> --ids <id1>,<id2>,<id3>
sonar keywords untrack-all <app-id> --all --forceAutocomplete suggestions
Raw autocomplete suggestions from the store. Faster than keywords search since no difficulty calculation is performed.
sonar keywords suggestions "recipe" --store ios
sonar keywords suggestions "photo" --store android --country de{
"data": [
{ "term": "recipe keeper", "priority": 0 },
{ "term": "recipes app free", "priority": 0 },
{ "term": "recipe book", "priority": 0 }
]
}Rankings
App rank history
Shows how your app ranks for each tracked keyword. Summarizes current, best, and worst rank over the time window.
sonar rankings <app-id>
sonar rankings <app-id> --days 7
sonar rankings <app-id> --keyword <keyword-id>{
"data": [
{
"keyword_id": "kw-uuid",
"keyword": "recipe app",
"history": [
{ "rank": 12, "measured_at": "2026-02-14" },
{ "rank": 8, "measured_at": "2026-02-13" }
]
}
]
}Keyword SERP history
Shows which apps rank for a specific keyword.
sonar rankings keyword <keyword-id>
sonar rankings keyword <keyword-id> --days 7Competitors
Competitor keyword analysis
See which keywords a competitor ranks for. Pass --app to compare against your own app and find keyword gaps.
sonar competitors keywords <competitor-app-id>
sonar competitors keywords <competitor-app-id> --app <your-app-id>{
"data": [
{
"keyword_id": "kw-uuid",
"keyword": "recipe app",
"store": "ios",
"country": "us",
"competitor_rank": 3,
"own_rank": 15,
"gap": null,
"difficulty": 72,
"popularity": null
},
{
"keyword_id": "kw-uuid-2",
"keyword": "cooking tips",
"store": "ios",
"country": "us",
"competitor_rank": 5,
"own_rank": null,
"gap": "missing",
"difficulty": 45,
"popularity": null
}
]
}gap is missing when the competitor ranks but your app doesn't. null when both rank.
Competitive landscape
The full competitive keyword picture for one of your own apps vs every tracked competitor: live stats (keyword gaps, winnable gaps, threats, leads), the top rows of each, and the latest AI insight if one has been generated.
sonar competitors landscape <your-app-id>AI competitive analysis (write scope)
Generates a fresh AI competitive insight for one of your own apps — opportunity clusters, threat narratives, strengths, and a diff vs the previous analysis. At most one analysis per app per 7 days; while in cooldown the API returns a 429 with the next available time (read the current insight with competitors landscape).
sonar competitors analyze <your-app-id>Competitor keyword discovery scan (write scope)
Discovers keywords the competitor ranks for and records both apps' ranks. Heavier than other commands (can take ~30s+); view the results with competitors keywords.
sonar competitors scan <competitor-app-id> --app <your-app-id>Export
Export ranking data
# CSV to stdout
sonar export rankings <app-id> --format csv
# CSV to file
sonar export rankings <app-id> --format csv --output rankings.csv
# JSON to file
sonar export rankings <app-id> --format json --output rankings.jsonGlobal Flags
| Flag | Description |
|---|---|
| --table | Output as formatted table instead of JSON |
| --verbose | Show request URL, status, timing, and rate limit info |
| --base-url <url> | Override the API base URL |
Output format
All commands output JSON by default, making it easy to pipe into other tools:
sonar apps list | jq '.data[].name'Use --table for human-readable table output:
sonar apps list --tableVerbose mode
Shows request details after each command:
$ sonar apps list --verbose
GET https://your-domain.com/api/v1/apps
Status: 200 (715ms)
Rate limit: 998/1000 remaining (resets 1771246534)Configuration
Config is saved to ~/.config/sonar/config.json:
{
"apiKey": "aso_xxx...",
"baseUrl": "https://your-domain.com"
}Environment variables
Environment variables override the config file. Useful for CI/CD pipelines:
| Variable | Description |
|---|---|
| SONAR_API_KEY | API key (overrides saved config) |
| SONAR_API_URL | Base URL (overrides saved config) |
# Use in CI without login
SONAR_API_KEY=aso_xxx sonar apps list