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 20Products (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.
Create 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 963034692Keywords
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> --clearAutocomplete 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.
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