CLI

Command-line interface for the Sonar REST API. 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.

Installation

npm install -g @sonarapp/cli

Or 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 login

Check status

Shows your key prefix and remaining daily API quota.

sonar auth status

Logout

Removes the saved API key.

sonar auth logout

Apps

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"
    }
  }
}

Keywords

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>

Autocomplete 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 7

Competitors

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.


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.json

Global Flags

FlagDescription
--tableOutput as formatted table instead of JSON
--verboseShow 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 --table

Verbose 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:

VariableDescription
SONAR_API_KEYAPI key (overrides saved config)
SONAR_API_URLBase URL (overrides saved config)
# Use in CI without login
SONAR_API_KEY=aso_xxx sonar apps list