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.
Pro operators
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
- 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.
- Header Content-Type is application/json. Header Accept should be application/json.
- 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.
- 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.
- 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.
$ {"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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
$ curl -sS https://codenamesonar.app/api/v1 -H 'Authorization: Bearer sonar_YOUR_TOKEN' -H 'Content-Type: application/json' -d '{"op":"whoami","input":{}}'
$ 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}}}'
$ 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
$ 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
$ 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
- Download sonar-windows-amd64.exe while signed in as Pro. Use the arm64 file only on ARM Windows.
- Save it as C:\Tools\sonar.exe or leave the versioned name. 1.0.0 is the build you just saved.
- If SmartScreen says it is unrecognized, choose More info, then Run anyway. The file is not signed.
- In PowerShell, run the commands in the window below. Add that folder to PATH if you want sonar from any directory.
$ .\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.
$ 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.
$ chmod +x sonar-chromiumos-amd64 $ install -m 755 sonar-chromiumos-amd64 "$HOME/.local/bin/sonar" $ sonar version $ sonar login
Use it
- 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.
- 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.
- 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.
- Do not pass the token as a shell argument. The prompt does not put it in history. sonar logout deletes the file.
- 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.
- 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.
- After a successful call the binary opens the matching page in the system browser. --no-open prints the JSON and stays in the terminal.
- sonar scan example.com resolves the host and opens /?host=example.com&run=1 so the scan desk starts that target in the browser.
- 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.
- Password changes and account deletion are refused by the token. Those commands open the account page instead.
- 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.
- sonar satellite LAT LON --mode infrared builds optical, infrared, and thermal URLs and opens the mode you named.
$ 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
$ sonar whoamicatalog
Return every operation. A current Pro membership and a live token are both required.
input none
browser /api-desk
$ sonar catalogtoken.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
$ 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
$ 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 /
$ sonar scan scanme.nmap.orgscan.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 /
$ 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
$ sonar historyscan.history
List this operator's saved scan summaries.
input none
browser /report
$ sonar history
Watchlist
watch.list
List watched hosts.
input none
browser /report/ops
$ sonar watch listwatch.add
Add or update a watched host.
input { "host": "example.com", "note": "owned" }
browser /report/ops
$ sonar watch add example.com --note ownedwatch.remove
Remove a watched host by id.
input { "id": 1 }
browser /report/ops
$ sonar watch remove 1
email.inspect
Inspect one mailbox address: syntax, MX, and existence.
input { "address": "[email protected]" }
browser /email
$ sonar email inspect [email protected]email.trace
Trace a raw RFC 5322 message.
input { "raw": "<full message>" }
browser /email
$ 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
$ 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
$ sonar kali statuskali.logs
Read the current Kali session log.
input none
browser /kali
$ sonar kali logskali.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
$ sonar kali spin --agreekali.restart
Restart the current Kali pod.
input none
browser /kali
$ sonar kali restartkali.destroy
Destroy the current Kali pod.
input none
browser /kali
$ sonar kali destroy
Companion
companion.boards
List flashable boards.
input none
browser /companion
$ sonar companion boardscompanion.mint
Mint a Stick companion profile for this Pro operator.
input none
browser /companion
$ sonar companion mint
Support
support.list
List this operator's support tickets.
input none
browser /support
$ sonar support listsupport.open
Open a support ticket.
input { "subject": "Scan quota", "body": "What I expected versus what happened." }
browser /support
$ sonar support open --subject "Scan quota" --body "Details here."support.read
Read one ticket you own.
input { "id": "<ticket id>" }
browser /support
$ sonar support read <id>support.reply
Reply on a ticket you own.
input { "id": "<ticket id>", "body": "More detail." }
browser /support
$ sonar support reply <id> --body "More detail."
Billing
billing.status
Show plan, renewal, and whether Pro is active.
input none
browser /account
$ sonar billingbilling.cancel
Schedule Pro to end at the period boundary. Requires confirm:CANCEL.
input { "confirm": "CANCEL" }
browser /account
$ sonar billing cancel --confirm CANCEL
Account
account.name
Rename the operator.
input { "name": "Kent" }
browser /account
$ sonar account name Kentaccount.email
Start an email-change confirmation. The confirmation itself stays in the mailbox.
input { "email": "[email protected]" }
browser /account
$ 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
$ sonar account passwordaccount.delete
Account deletion is not accepted on the token. The CLI opens the account page instead.
input none
browser /account
$ 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
$ 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
$ sonar docs nmapdocs.pages
List report tabs and Apps-menu manuals.
input none
browser /report/kali
$ sonar docs
Browser
desk.scan
Open the scan desk
input none
browser /
$ sonar open /desk.reports
Open the report archive
input none
browser /report
$ sonar open /reportdesk.mail
Open the mail desk
input none
browser /email
$ sonar open /emaildesk.ai
Open the AI desk
input none
browser /ai
$ sonar open /aidesk.companion
Open the companion flasher
input none
browser /companion
$ sonar open /companiondesk.spectrum
Open the spectrum analyzer page
input none
browser /spectrum
$ sonar open /spectrumdesk.kali
Open Codename Kali
input none
browser /kali
$ sonar open /kalidesk.account
Open the account page
input none
browser /account
$ sonar open /accountdesk.plans
Open Free vs Pro
input none
browser /plans
$ sonar open /plansdesk.support
Open support
input none
browser /support
$ sonar open /supportdesk.api
Open this API tab
input none
browser /api-desk
$ sonar open /api-deskdesk.terms
Open the terms of service
input none
browser /terms
$ sonar open /termsdesk.wcag
Open the WCAG statement
input none
browser /wcag
$ sonar open /wcagdesk.report.summary
Open the Summary report tab
input none
browser /report/summary
$ sonar open /report/summarydesk.report.identity
Open the Identity report tab
input none
browser /report/identity
$ sonar open /report/identitydesk.report.surface
Open the Surface report tab
input none
browser /report/surface
$ sonar open /report/surfacedesk.report.path
Open the Path report tab
input none
browser /report/path
$ sonar open /report/pathdesk.report.ports
Open the Ports report tab
input none
browser /report/ports
$ sonar open /report/portsdesk.report.intel
Open the Intel report tab
input none
browser /report/intel
$ sonar open /report/inteldesk.report.packets
Open the Packets report tab
input none
browser /report/packets
$ sonar open /report/packetsdesk.report.toolkit
Open the Toolkit report tab
input none
browser /report/toolkit
$ sonar open /report/toolkitdesk.report.kali
Open the Apps report tab
input none
browser /report/kali
$ sonar open /report/kalidesk.report.threats
Open the Threats report tab
input none
browser /report/threats
$ sonar open /report/threatsdesk.report.openvas
Open the OpenVAS report tab
input none
browser /report/openvas
$ sonar open /report/openvasdesk.report.prioritize
Open the Prioritize report tab
input none
browser /report/prioritize
$ sonar open /report/prioritizedesk.report.defend
Open the Defend report tab
input none
browser /report/defend
$ sonar open /report/defenddesk.report.detect
Open the Detect report tab
input none
browser /report/detect
$ sonar open /report/detectdesk.report.respond
Open the Respond report tab
input none
browser /report/respond
$ sonar open /report/responddesk.report.govern
Open the Govern report tab
input none
browser /report/govern
$ sonar open /report/governdesk.report.ops
Open the Ops report tab
input none
browser /report/ops
$ sonar open /report/opsdesk.report.export
Open the Export report tab
input none
browser /report/export
$ sonar open /report/export