Web Server API¶
Built-in HTTP + WebSocket interface used by the browser UI and automation clients.
Auth Model¶
If web server is started with --auth-token, all /api/* HTTP routes require:
WebSocket routes additionally allow query token:
HTTP Endpoints¶
Read Endpoints¶
| Method | Path | Purpose |
|---|---|---|
GET |
/api/v1/info |
Runtime model/capability summary |
GET |
/api/v1/state |
Canonical current state snapshot |
GET |
/api/v1/capabilities |
Full profile-backed capabilities |
GET |
/api/v1/dx/spots |
Buffered DX spots |
GET |
/api/v1/bridge |
Audio bridge status |
GET |
/api/v1/band-plan/config |
Active band-plan region |
GET |
/api/v1/band-plan/layers |
Band-plan layers metadata |
GET |
/api/v1/band-plan/segments?start=<hz>&end=<hz>&layers=<csv> |
Band-plan overlay segments |
GET |
/api/v1/eibi/status |
EiBi loader status |
GET |
/api/v1/eibi/stations |
EiBi station list (paged/filterable) |
GET |
/api/v1/eibi/segments?start=<hz>&end=<hz>&on_air=true |
EiBi overlay segments |
GET |
/api/v1/eibi/identify?freq=<hz>&tolerance=<hz> |
Identify probable broadcast stations |
GET |
/api/v1/eibi/bands |
EiBi frequency bands |
Control Endpoints¶
| Method | Path | Purpose |
|---|---|---|
POST |
/api/v1/radio/connect |
Connect/reconnect radio control path |
POST |
/api/v1/radio/disconnect |
Disconnect radio control path |
POST |
/api/v1/radio/power |
Power on/off via CI-V power control |
POST |
/api/v1/bridge |
Start audio bridge |
DELETE |
/api/v1/bridge |
Stop audio bridge |
POST |
/api/v1/band-plan/config |
Change active region and reload band plans |
POST |
/api/v1/eibi/fetch |
Fetch/refresh EiBi dataset |
GET /api/v1/info¶
Version, model, capability summary, and connection metadata.
{
"server": "icom-lan",
"version": "0.12.0",
"proto": 1,
"radio": "IC-7300",
"model": "IC-7300",
"capabilities": {
"hasSpectrum": true,
"hasAudio": true,
"hasTx": true,
"hasDualReceiver": false,
"hasTuner": false,
"hasCw": true,
"maxReceivers": 1,
"tags": ["audio", "cw", "meters", "scope", "tx"],
"modes": ["USB", "LSB", "CW", "CW-R", "AM", "FM", "RTTY", "RTTY-R"],
"filters": ["FIL1", "FIL2", "FIL3"],
"vfoScheme": "ab",
"hasLan": false
},
"connection": {
"rigConnected": true,
"radioReady": true,
"controlConnected": true,
"wsClients": 2
}
}
GET /api/v1/state¶
Canonical full state payload for web consumers (camelCase keys).
- Includes
revision+updatedAt. - Includes
connectionobject (rigConnected,radioReady,controlConnected). - For single-receiver profiles,
subkey is omitted. - Supports
ETagbased onrevisionfor conditional requests.
{
"main": { "freqHz": 14074000, "mode": "USB", "filter": 1 },
"revision": 42,
"updatedAt": "2026-03-15T10:00:00+00:00",
"radioDetail": { "status": "connected" },
"wsClients": { "scope": 1, "control": 1, "audio": 0 },
"connection": {
"rigConnected": true,
"radioReady": true,
"controlConnected": true
}
}
GET /api/v1/capabilities¶
Profile-backed capabilities used to build dynamic UI.
Notable fields:
| Field | Type | Notes |
|---|---|---|
receivers |
int |
Receiver count from active profile |
vfoScheme |
"ab" | "main_sub" |
VFO label scheme |
freqRanges[].bands[].bsrCode |
int (optional) |
Band Stack Register code for set_band |
scopeSource |
"hardware" | "audio_fft" | null |
Spectrum data source |
scopeConfig.defaultSpan |
int |
Hardware scope span or audio FFT bandwidth |
audioConfig |
object | Web audio transport defaults |
When radio has audio but no hardware scope support, backend enables AudioFftScope
and reports scopeSource: "audio_fft".
WebSocket Endpoints¶
| Path | Direction | Payload |
|---|---|---|
/api/v1/ws |
bi-directional | JSON commands/events/state updates |
/api/v1/scope |
server -> client | Binary scope frames |
/api/v1/audio |
bi-directional | JSON control + binary audio frames |
/api/v1/ws command envelope¶
Response:
Error response:
Rate-limited high-frequency set_* commands are ACKed with:
State update stream (/api/v1/ws)¶
Server publishes state_update messages in two shapes:
- Full snapshot:
- Delta update:
set_band workflow (/api/v1/ws)¶
band is BSR code from freqRanges[].bands[].bsrCode.
Backend path:
- Try BSR recall (
0x1A 0x01 <band> 0x01). - If recall fails, fallback to profile
default_hzfor matchingbsr_code. - If profile has no matching
bsr_code, command is acknowledged but no retune happens.
Operational Runbook¶
Power on/off through HTTP¶
curl -X POST http://127.0.0.1:8080/api/v1/radio/power \
-H "Content-Type: application/json" \
-d '{"state":"on"}'
Audio bridge start/status/stop¶
curl -X POST http://127.0.0.1:8080/api/v1/bridge
curl http://127.0.0.1:8080/api/v1/bridge
curl -X DELETE http://127.0.0.1:8080/api/v1/bridge
Change band-plan region¶
curl -X POST http://127.0.0.1:8080/api/v1/band-plan/config \
-H "Content-Type: application/json" \
-d '{"region":"IARU-R1"}'
Refresh EiBi cache¶
curl -X POST http://127.0.0.1:8080/api/v1/eibi/fetch \
-H "Content-Type: application/json" \
-d '{"force":true}'
Modules¶
server.py— asyncio HTTP/WebSocket server, endpoint routinghandlers.py— control/scope/audio channel handlersradio_poller.py— state polling and command queue executionruntime_helpers.py— canonical public state/capability shapingdx_cluster.py— DX spot ingest and buffering