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

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 gb

Search apps in a store

sonar apps search "meditation" --store ios --num 25

ASO audit score

0-100 score with itemized checks (title length, keyword coverage, screenshots, …).

sonar apps score 1450772168 --store ios --table

Extract keywords from an app's metadata

sonar apps extract-keywords com.duolingo --store android --max 30

Fetch app reviews

sonar apps reviews 1450772168 --store ios --sort helpful --min-rating 1 --max-rating 2 --limit 50

Change 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 20

Untrack 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> --force

Products (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 --table

Create a product

sonar products create --ios 1450772168 --name "My App"
sonar products create --ios 1450772168 --android com.example.myapp --country us

Link the second-store version

sonar products add-app <product-id> --store android --id com.example.myapp

Track a competitor

sonar products add-competitor <product-id> --store ios --id 963034692

Remove 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> --force

Delete 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> --force

Alerts

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

Create 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 --disabled

Delete an alert subscription

Deletes an alert subscription. Confirms before deleting unless -f / --force.

sonar alerts delete <id>
sonar alerts delete <id> --force

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>

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 ios

Track 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 mx

Set 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> --clear

Star / 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> --force

Bulk 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 --force

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.

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