Pro operators

API

This is the public operator API at https://codenamesonar.app/api/v1. It is reachable from the internet. Every call needs both a current Pro membership and a live API token. A free seat, an expired membership, a missing token, or a revoked token is refused. The same token is what the CLI sends after sonar login. The sealed admin vault is not on this API.

API contract

The operator API is one HTTPS endpoint on the public internet: https://codenamesonar.app/api/v1. GET and POST both work. OPTIONS is the CORS preflight and does not need a token. Every other call needs a current Pro membership and a live API token together. Either one alone is not enough.

Request

  1. Header Authorization must be Bearer followed by the sonar_ secret from this tab. The word Bearer and a space are required. The secret is not a query parameter and not a cookie.
  2. Header Content-Type is application/json. Header Accept should be application/json.
  3. The body is one object with two fields. op is the operation id from the catalog below. input is an object. When the catalog says input none, send an empty object.
  4. You may also pass op as a query string on GET. POST body wins if both are set. A body over 220 KB is rejected before it is parsed.
  5. The server hashes the secret and compares it to the stored hash. It then checks that the token is not revoked and not past its 30-day expiry. Then it checks that the seat is still Pro and that the paid period has not ended.

Response

A success body always has ok true, the op you called, expiresAt for the token, membership, and result. membership.plan is pro, membership.active is true, and membership.until is the period end or null when the seat does not expire. result.browser is a path or URL. The CLI opens it unless you passed --no-open. Result fields besides browser are the operation payload: rows, report, holes, urls, ticket, and so on.

response
$ {"ok":true,"op":"whoami","expiresAt":"2026-10-31T00:00:00Z","membership":{"plan":"pro","until":null,"active":true},"result":{"plan":"pro","active":true}}

Refusals

401 no Authorization header, the secret is not a sonar_ token, the hash does not match, the token was revoked, or the token is past 30 days.

403 the token is valid, but the membership is free or the Pro period has ended. Create a new token only after Pro is current again. Old tokens do not start working by themselves.

400 the body is not JSON, op is missing, or input failed validation. The error string names the field.

404 op is not in the catalog. Call catalog to see the live list for this token.

413 the body is larger than 220 KB. Mail traces must stay under that cap.

429 more than 120 calls from one IP in a minute. Mail and support also have their own per-seat limits. Wait, then retry the same body. Calls are safe to retry except token.issue, which mints a new secret each time.

Tokens and the CLI

  1. This page mints the first token while you are signed in and Pro is current. The database stores sha256 only. The sonar_ value is shown once. Copy it before you leave the tab.
  2. sonar login asks for that value at the prompt, calls whoami, and writes token.json only if whoami succeeds. A rejected token is not remembered.
  3. The file is mode 0600 at %APPDATA%\codename-sonar\token.json on Windows, ~/Library/Application Support/codename-sonar/token.json on macOS, and ~/.config/codename-sonar/token.json on Linux, ChromeOS Linux, and ChromiumOS.
  4. The CLI sends that file on every later command until the expiry timestamp. sonar logout deletes the file. Revoke on this page kills it on the server even if the file remains.
  5. token.issue mints another secret for the same seat. Use it for a second computer. token.revoke needs the token id from this page, not the secret.
  6. Pass --host https://codenamesonar.app or set SONAR_HOST when the binary should not assume the public origin. The host is saved next to the token.
  7. account.password and account.delete never run from a token. The result tells the CLI to open the account page. The admin vault is not an operation.

What you can call

Session whoami, catalog, token.issue, token.revoke. Start here. catalog is the list the server will actually accept.

Scan scan.phase runs one step: resolve, ping, trace, ports, udp, deep, intel, or brief. resolve also returns the geolocation used for optical, infrared, and thermal. scan.authorize returns the options Pro is allowed to use. scan.record writes a summary. scan.history lists them.

Watchlist, mail, AI watch.add, watch.list, and watch.remove keep hosts. email.inspect checks one address. email.trace needs the raw message. ai.hunt returns defensive findings for a target.

Codename Kali status, logs, restart, and destroy. spin boots a pod only when input.agree is true. Without it the call returns needsAgree and the CLI opens the desk so the assent stays on screen.

Companion, support, billing, docs companion.boards lists hardware. companion.mint issues a Stick profile. support.open, support.list, support.read, and support.reply are limited to tickets you own. billing.status shows whether Pro is current. billing.cancel requires confirm set to CANCEL. docs.pages and docs.man return the manuals. satellite.lock returns the three map URLs.

Browser desk.* does not change data. It returns the page the CLI should open.

https
$ curl -sS https://codenamesonar.app/api/v1 -H 'Authorization: Bearer sonar_YOUR_TOKEN' -H 'Content-Type: application/json' -d '{"op":"whoami","input":{}}'
scan
$ curl -sS https://codenamesonar.app/api/v1 -H 'Authorization: Bearer sonar_YOUR_TOKEN' -H 'Content-Type: application/json' -d '{"op":"scan.phase","input":{"phase":"resolve","target":"scanme.nmap.org","options":{"profile":"quick","traceroute":true,"satellite":true}}}'
cli
$ sonar login
$ sonar whoami
$ sonar catalog
$ sonar scan scanme.nmap.org
$ sonar call token.issue --input '{"name":"laptop"}'

CLI 1.0.0

Version 1.0.0. Native programs for Linux, macOS, Windows, ChromeOS, and ChromiumOS. No Node, no installer, no runtime. The download and the API both require a current Pro membership. A free seat, an ended membership, a signed-out browser, or a copied link is refused.

  • Linux · x64

    Ubuntu, Debian, Fedora, Arch. uname -m prints x86_64.

    1.0.0

    Download unlocks when Pro is current.

  • Linux · arm64

    Raspberry Pi 4/5, ARM cloud. uname -m prints aarch64.

    1.0.0

    Download unlocks when Pro is current.

  • macOS · Apple silicon

    M1, M2, M3, M4. About This Mac says Apple.

    1.0.0

    Download unlocks when Pro is current.

  • macOS · Intel

    About This Mac says Intel.

    1.0.0

    Download unlocks when Pro is current.

  • Windows · x64

    Settings, System, About. Most PCs.

    1.0.0

    Download unlocks when Pro is current.

  • Windows · arm64

    Surface Pro X and other ARM Windows.

    1.0.0

    Download unlocks when Pro is current.

  • ChromeOS · x64

    Intel and AMD Chromebooks. Runs in the Linux container. uname -m prints x86_64.

    1.0.0

    Download unlocks when Pro is current.

  • ChromeOS · arm64

    ARM Chromebooks. Runs in the Linux container. uname -m prints aarch64.

    1.0.0

    Download unlocks when Pro is current.

  • ChromiumOS · x64

    x64 ChromiumOS shell. uname -m prints x86_64.

    1.0.0

    Download unlocks when Pro is current.

  • ChromiumOS · arm64

    ARM ChromiumOS shell. uname -m prints aarch64.

    1.0.0

    Download unlocks when Pro is current.

Install 1.0.0

Use the download button while you are signed in as Pro. A curl without that session gets 401 or 403. After the file is on disk:

Linux

linux
$ chmod +x sonar-linux-amd64
$ sudo install -m 755 sonar-linux-amd64 /usr/local/bin/sonar
$ sonar version
$ sonar login

On arm64, install sonar-linux-arm64 the same way. uname -m prints x86_64 or aarch64. sonar version must print 1.0.0.

macOS

macos
$ chmod +x sonar-macos-arm64
$ xattr -d com.apple.quarantine sonar-macos-arm64
$ sudo install -m 755 sonar-macos-arm64 /usr/local/bin/sonar
$ sonar version

Intel Macs use sonar-macos-amd64. If macOS says the developer cannot be verified, the quarantine line clears the browser flag, or allow it under System Settings, Privacy and Security.

Windows

  1. Download sonar-windows-amd64.exe while signed in as Pro. Use the arm64 file only on ARM Windows.
  2. Save it as C:\Tools\sonar.exe or leave the versioned name. 1.0.0 is the build you just saved.
  3. If SmartScreen says it is unrecognized, choose More info, then Run anyway. The file is not signed.
  4. In PowerShell, run the commands in the window below. Add that folder to PATH if you want sonar from any directory.
windows
$ .\sonar.exe version
$ .\sonar.exe login

ChromeOS

Turn on Linux in Settings, then Developers, then Linux development environment. Download the file into the Linux folder. Intel and AMD Chromebooks use sonar-chromeos-amd64. ARM Chromebooks use sonar-chromeos-arm64. Check with uname -m.

chromeos
$ chmod +x sonar-chromeos-amd64
$ sudo install -m 755 sonar-chromeos-amd64 /usr/local/bin/sonar
$ sonar version
$ sonar login

ChromiumOS

Run this in the ChromiumOS shell, not in the browser. x64 images use sonar-chromiumos-amd64. ARM images use sonar-chromiumos-arm64. The token file is the Linux path, ~/.config/codename-sonar/token.json.

chromiumos
$ chmod +x sonar-chromiumos-amd64
$ install -m 755 sonar-chromiumos-amd64 "$HOME/.local/bin/sonar"
$ sonar version
$ sonar login

Use it

  1. Create the token on this tab first. It is shown once, it is a bearer secret, and it dies after 30 days. Revoke it here if a laptop is lost.
  2. Run sonar login. The prompt says Codename Sonar API token. Paste the token and press Enter. The binary checks it against this site before it keeps it.
  3. The token file is %APPDATA%\codename-sonar\token.json on Windows, ~/Library/Application Support/codename-sonar/token.json on macOS, and ~/.config/codename-sonar/token.json on Linux. Mode 0600. The same 30-day expiry is stored in that file. When it is missing or past, the next command asks at the prompt again.
  4. Do not pass the token as a shell argument. The prompt does not put it in history. sonar logout deletes the file.
  5. If this site is not the public origin, login with --host https://your-sonar-origin or set SONAR_HOST. The host is saved with the token.
  6. Every command sends POST /api/v1 with Authorization Bearer and a JSON body of op plus input. No token, a free seat, a revoked token, or an expired token is rejected.
  7. After a successful call the binary opens the matching page in the system browser. --no-open prints the JSON and stays in the terminal.
  8. sonar scan example.com resolves the host and opens /?host=example.com&run=1 so the scan desk starts that target in the browser.
  9. sonar open /kali only opens a page. sonar call scan.phase --input JSON runs any operation listed below. The JSON is one object, quoted so the shell does not eat it.
  10. Password changes and account deletion are refused by the token. Those commands open the account page instead.
  11. sonar kali spin does not boot a pod unless you pass --agree. Without it, the binary opens Codename Kali so the assent stays on screen.
  12. sonar satellite LAT LON --mode infrared builds optical, infrared, and thermal URLs and opens the mode you named.
sonar
$ sonar version
$ sonar login
$ sonar whoami
$ sonar catalog
$ sonar scan scanme.nmap.org
$ sonar history
$ sonar watch add example.com --note owned
$ sonar watch list
$ sonar email inspect [email protected]
$ sonar ai scanme.nmap.org
$ sonar kali status
$ sonar companion boards
$ sonar support list
$ sonar billing
$ sonar docs nmap
$ sonar open /report
$ sonar logout
$ sonar scan scanme.nmap.org --no-open

Session

  • whoami

    Show the operator bound to this token, whether Pro is current, and when the token expires.

    input none

    browser /api-desk

    whoami
    $ sonar whoami
    
  • catalog

    Return every operation. A current Pro membership and a live token are both required.

    input none

    browser /api-desk

    catalog
    $ sonar catalog
    
  • token.issue

    Mint another CLI token for this same Pro seat. The secret is returned once. Paste it into sonar login on another computer.

    input { "name": "laptop" }

    browser /api-desk

    token.issue
    $ sonar call token.issue --input '{"name":"laptop"}'
    
  • token.revoke

    Revoke one token id belonging to this seat. The token that made the call keeps working until you revoke its own id.

    input { "id": "<token id>" }

    browser /api-desk

    token.revoke
    $ sonar call token.revoke --input '{"id":"TOKEN_ID"}'
    

Scan

  • scan.authorize

    Check that this Pro token may run a sweep and return the clamped options.

    input { "options": { "profile": "quick", "timing": "T3", "traceroute": true, "satellite": true } }

    browser /

    scan.authorize
    $ sonar scan scanme.nmap.org
    
  • scan.phase

    Run one phase: resolve, ping, trace, ports, udp, deep, intel, or brief. Resolve returns geolocation for optical, infrared, and thermal.

    input { "phase": "resolve", "target": "scanme.nmap.org", "options": { "profile": "quick" } }

    browser /

    scan.phase
    $ sonar call scan.phase --input '{"phase":"trace","target":"scanme.nmap.org","options":{"profile":"quick","traceroute":true}}'
    
  • scan.record

    Write a scan summary into this operator's history.

    input { "target": "scanme.nmap.org", "posture": "watch", "openPorts": "80/tcp,443/tcp" }

    browser /report

    scan.record
    $ sonar history
    
  • scan.history

    List this operator's saved scan summaries.

    input none

    browser /report

    scan.history
    $ sonar history
    

Watchlist

  • watch.list

    List watched hosts.

    input none

    browser /report/ops

    watch.list
    $ sonar watch list
    
  • watch.add

    Add or update a watched host.

    input { "host": "example.com", "note": "owned" }

    browser /report/ops

    watch.add
    $ sonar watch add example.com --note owned
    
  • watch.remove

    Remove a watched host by id.

    input { "id": 1 }

    browser /report/ops

    watch.remove
    $ sonar watch remove 1
    

Mail

  • email.inspect

    Inspect one mailbox address: syntax, MX, and existence.

    input { "address": "[email protected]" }

    browser /email

    email.inspect
    $ sonar email inspect [email protected]
    
  • email.trace

    Trace a raw RFC 5322 message.

    input { "raw": "<full message>" }

    browser /email

    email.trace
    $ sonar email trace ./message.eml
    

AI

  • ai.hunt

    Run the defensive hole hunter against a target and optional open ports.

    input { "target": "scanme.nmap.org", "openPorts": [{ "port": 22, "proto": "tcp", "service": "ssh" }] }

    browser /ai

    ai.hunt
    $ sonar ai scanme.nmap.org
    

Codename Kali

  • kali.status

    Read the Kubernetes shell status. Secrets are not returned on this API.

    input none

    browser /kali

    kali.status
    $ sonar kali status
    
  • kali.logs

    Read the current Kali session log.

    input none

    browser /kali

    kali.logs
    $ sonar kali logs
    
  • kali.spin

    Boot a Kali pod. Requires agree:true. Without it, the CLI only opens the desk so you can assent in the browser.

    input { "agree": true }

    browser /kali

    kali.spin
    $ sonar kali spin --agree
    
  • kali.restart

    Restart the current Kali pod.

    input none

    browser /kali

    kali.restart
    $ sonar kali restart
    
  • kali.destroy

    Destroy the current Kali pod.

    input none

    browser /kali

    kali.destroy
    $ sonar kali destroy
    

Companion

  • companion.boards

    List flashable boards.

    input none

    browser /companion

    companion.boards
    $ sonar companion boards
    
  • companion.mint

    Mint a Stick companion profile for this Pro operator.

    input none

    browser /companion

    companion.mint
    $ sonar companion mint
    

Support

  • support.list

    List this operator's support tickets.

    input none

    browser /support

    support.list
    $ sonar support list
    
  • support.open

    Open a support ticket.

    input { "subject": "Scan quota", "body": "What I expected versus what happened." }

    browser /support

    support.open
    $ sonar support open --subject "Scan quota" --body "Details here."
    
  • support.read

    Read one ticket you own.

    input { "id": "<ticket id>" }

    browser /support

    support.read
    $ sonar support read <id>
    
  • support.reply

    Reply on a ticket you own.

    input { "id": "<ticket id>", "body": "More detail." }

    browser /support

    support.reply
    $ sonar support reply <id> --body "More detail."
    

Billing

  • billing.status

    Show plan, renewal, and whether Pro is active.

    input none

    browser /account

    billing.status
    $ sonar billing
    
  • billing.cancel

    Schedule Pro to end at the period boundary. Requires confirm:CANCEL.

    input { "confirm": "CANCEL" }

    browser /account

    billing.cancel
    $ sonar billing cancel --confirm CANCEL
    

Account

  • account.name

    Rename the operator.

    input { "name": "Kent" }

    browser /account

    account.name
    $ sonar account name Kent
    
  • account.email

    Start an email-change confirmation. The confirmation itself stays in the mailbox.

    input { "email": "[email protected]" }

    browser /account

    account.email
    $ sonar account email [email protected]
    
  • account.password

    Password changes are not accepted on the token. The CLI opens the account page instead.

    input none

    browser /account

    account.password
    $ sonar account password
    
  • account.delete

    Account deletion is not accepted on the token. The CLI opens the account page instead.

    input none

    browser /account

    account.delete
    $ sonar account delete
    

Satellite

  • satellite.lock

    Build the optical, infrared, and thermal lock URLs for a latitude and longitude and open the optical frame.

    input { "lat": 37.77, "lon": -122.41, "span": 0.18, "mode": "optical" }

    browser /api/sonar/satellite?lat=37.77&lon=-122.41&span=0.18&mode=optical&w=1280&h=720

    satellite.lock
    $ sonar satellite 37.77 -122.41 --mode infrared
    

Docs

  • docs.man

    Return one Apps-menu man page.

    input { "id": "nmap" }

    browser /report/kali?app=nmap&man=1

    docs.man
    $ sonar docs nmap
    
  • docs.pages

    List report tabs and Apps-menu manuals.

    input none

    browser /report/kali

    docs.pages
    $ sonar docs
    

Browser

  • desk.scan

    Open the scan desk

    input none

    browser /

    desk.scan
    $ sonar open /
    
  • desk.reports

    Open the report archive

    input none

    browser /report

    desk.reports
    $ sonar open /report
    
  • desk.mail

    Open the mail desk

    input none

    browser /email

    desk.mail
    $ sonar open /email
    
  • desk.ai

    Open the AI desk

    input none

    browser /ai

    desk.ai
    $ sonar open /ai
    
  • desk.companion

    Open the companion flasher

    input none

    browser /companion

    desk.companion
    $ sonar open /companion
    
  • desk.spectrum

    Open the spectrum analyzer page

    input none

    browser /spectrum

    desk.spectrum
    $ sonar open /spectrum
    
  • desk.kali

    Open Codename Kali

    input none

    browser /kali

    desk.kali
    $ sonar open /kali
    
  • desk.account

    Open the account page

    input none

    browser /account

    desk.account
    $ sonar open /account
    
  • desk.plans

    Open Free vs Pro

    input none

    browser /plans

    desk.plans
    $ sonar open /plans
    
  • desk.support

    Open support

    input none

    browser /support

    desk.support
    $ sonar open /support
    
  • desk.api

    Open this API tab

    input none

    browser /api-desk

    desk.api
    $ sonar open /api-desk
    
  • desk.terms

    Open the terms of service

    input none

    browser /terms

    desk.terms
    $ sonar open /terms
    
  • desk.wcag

    Open the WCAG statement

    input none

    browser /wcag

    desk.wcag
    $ sonar open /wcag
    
  • desk.report.summary

    Open the Summary report tab

    input none

    browser /report/summary

    desk.report.summary
    $ sonar open /report/summary
    
  • desk.report.identity

    Open the Identity report tab

    input none

    browser /report/identity

    desk.report.identity
    $ sonar open /report/identity
    
  • desk.report.surface

    Open the Surface report tab

    input none

    browser /report/surface

    desk.report.surface
    $ sonar open /report/surface
    
  • desk.report.path

    Open the Path report tab

    input none

    browser /report/path

    desk.report.path
    $ sonar open /report/path
    
  • desk.report.ports

    Open the Ports report tab

    input none

    browser /report/ports

    desk.report.ports
    $ sonar open /report/ports
    
  • desk.report.intel

    Open the Intel report tab

    input none

    browser /report/intel

    desk.report.intel
    $ sonar open /report/intel
    
  • desk.report.packets

    Open the Packets report tab

    input none

    browser /report/packets

    desk.report.packets
    $ sonar open /report/packets
    
  • desk.report.toolkit

    Open the Toolkit report tab

    input none

    browser /report/toolkit

    desk.report.toolkit
    $ sonar open /report/toolkit
    
  • desk.report.kali

    Open the Apps report tab

    input none

    browser /report/kali

    desk.report.kali
    $ sonar open /report/kali
    
  • desk.report.threats

    Open the Threats report tab

    input none

    browser /report/threats

    desk.report.threats
    $ sonar open /report/threats
    
  • desk.report.openvas

    Open the OpenVAS report tab

    input none

    browser /report/openvas

    desk.report.openvas
    $ sonar open /report/openvas
    
  • desk.report.prioritize

    Open the Prioritize report tab

    input none

    browser /report/prioritize

    desk.report.prioritize
    $ sonar open /report/prioritize
    
  • desk.report.defend

    Open the Defend report tab

    input none

    browser /report/defend

    desk.report.defend
    $ sonar open /report/defend
    
  • desk.report.detect

    Open the Detect report tab

    input none

    browser /report/detect

    desk.report.detect
    $ sonar open /report/detect
    
  • desk.report.respond

    Open the Respond report tab

    input none

    browser /report/respond

    desk.report.respond
    $ sonar open /report/respond
    
  • desk.report.govern

    Open the Govern report tab

    input none

    browser /report/govern

    desk.report.govern
    $ sonar open /report/govern
    
  • desk.report.ops

    Open the Ops report tab

    input none

    browser /report/ops

    desk.report.ops
    $ sonar open /report/ops
    
  • desk.report.export

    Open the Export report tab

    input none

    browser /report/export

    desk.report.export
    $ sonar open /report/export