CLI
Command-line interface for the Sonar REST API. Requires a paid subscription API key. Install via npm or run with npx.
Installation
npm install -g sonar-asoOr run without installing:
npx sonar-aso <command>Authentication
Login
Prompts for your API key, validates it against the API, and saves it to ~/.config/aso/config.json.
aso auth loginCheck status
Shows your key prefix and remaining daily API quota.
aso auth statusLogout
Removes the saved API key.
aso auth logoutApps
List all tracked apps
aso 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
aso 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"
}
}
}Keywords
Search keywords
Returns autocomplete suggestions with difficulty scores and popularity estimates.
aso keywords search "recipe app" --store ios
aso 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.
aso keywords list <app-id>Autocomplete suggestions
Raw autocomplete suggestions from the store. Faster than keywords search since no difficulty calculation is performed.
aso keywords suggestions "recipe" --store ios
aso 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.
aso rankings <app-id>
aso rankings <app-id> --days 7
aso 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.
aso rankings keyword <keyword-id>
aso 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.
aso competitors keywords <competitor-app-id>
aso 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.
Export
Export ranking data
# CSV to stdout
aso export rankings <app-id> --format csv
# CSV to file
aso export rankings <app-id> --format csv --output rankings.csv
# JSON to file
aso 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:
aso apps list | jq '.data[].name'Use --table for human-readable table output:
aso apps list --tableVerbose mode
Shows request details after each command:
$ aso 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/aso/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 |
|---|---|
| ASO_API_KEY | API key (overrides saved config) |
| ASO_API_URL | Base URL (overrides saved config) |
# Use in CI without login
ASO_API_KEY=aso_xxx aso apps list