Skip to content

HTTP API

IC edited this page May 28, 2026 · 2 revisions

HTTP API

NyxScope exposes a JSON HTTP API on port 8765 for status, control, message tails, audio streaming, and IQ streaming. It runs always-on alongside the Tauri GUI and also runs standalone in --headless-api mode (no GUI).

Useful for: Home Assistant integrations, Node-RED flows, custom dashboards, CLI tooling, headless deployments on a server with no display.

Conventions

  • Base URL: http://127.0.0.1:8765
  • Auth: none. The server binds to localhost by default — anything on your machine can call it. To expose remotely, put it behind a reverse proxy with auth.
  • Methods: mostly GET for reads, POST for actions. JSON request bodies; JSON responses.
  • Errors: non-2xx status code, body is {"error": "message"}.

Status + health

Method Path Description
GET /api/health Liveness check. Returns {"ok": true} if the API is up.
GET /api/scan/status Scanner state (running / locked / discovery), active range, current frequency.
GET /api/device/status Connected SDR info: model, sample rate, gain, frequency.
GET /api/vfo/states All VFOs: frequency, mode, squelch, mute, audio level, decoder badge.
curl http://127.0.0.1:8765/api/scan/status

Device control

Method Path Description
GET /api/devices List discovered SDRs (USB-attached + network).
GET /api/device/mdns_scan Re-trigger mDNS auto-discovery for network SDRs.
POST /api/device/connect Body: {"device_id": "..."}. Connect to the named device.
POST /api/device/disconnect Disconnect the current SDR.
POST /api/device/test Probe a device without connecting.
POST /api/device/gain Body: {"gain": 30.0} (dB).
POST /api/device/sample_rate Body: {"rate": 2400000} (Hz).
GET /api/slots List active SDR slots (multi-SDR mode).

Scanner control

Method Path Description
POST /api/scan/start Body: {"ranges": ["FM Broadcast"]} (optional — defaults to active).
POST /api/scan/stop Halt scanning.
POST /api/scan/lock Body: {"frequency_hz": 96100000, "mode": "wfm"}. Lock onto a specific frequency.
POST /api/scan/unlock Release the locked frequency, resume scan.
POST /api/scan/adsb Switch to ADS-B mode.
POST /api/scan/ais Switch to AIS mode.
POST /api/scan/acars Switch to ACARS mode.
POST /api/scan/lora Body: {"region": "US915"} (optional).
POST /api/scan/identify_protocol Auto-identify the digital mode at the locked frequency.
POST /api/scanner/max-vfos Body: {"max": 8}. Per-instance VFO ceiling.

VFO control

Method Path Description
GET /api/vfo/states All VFOs with current state.
GET /api/vfo/diagnostics Per-VFO decoder diagnostics.
GET /api/vfo/:id/rds RDS data for a specific VFO (WFM only).
POST /api/vfo/:id/volume Body: {"volume": 0.75}.
POST /api/vfo/:id/mute Body: {"muted": true}.
POST /api/vfo/:id/audio_agc Body: {"enabled": true}.

Decoded messages

NyxScope tracks decoded messages by category. All endpoints support ?since=<cursor> for incremental polling.

Method Path Description
GET /api/decoded_messages Multimon-ng output: POCSAG, FLEX, CTCSS/DCS, DTMF, EAS, etc.
GET /api/protocol_messages Non-multimon decoders: APRS, AIS, ACARS, VDL2, native decoders.
GET /api/rtl433_messages rtl_433 sensor messages — smart meters, weather stations, TPMS, etc.
GET /api/intercept_results Signal classification + protocol identification results.
# Tail FLEX/POCSAG pager messages since cursor 0
curl http://127.0.0.1:8765/api/decoded_messages?since=0

The response includes a cursor field — pass that as since=<cursor> next time to get only new messages.

Trunking

Method Path Description
POST /api/trunking/start Body: {"system": "..."}. Activate a configured trunked system.
POST /api/trunking/stop Stop trunking; return to scan mode.
POST /api/trunking/lock Body: {"frequency_hz": 851012500}. Lock to a specific CC.
GET /api/trunking/status Active system, current TG, source ID, encryption flag.
GET /api/trunking/calls Call history (recent grants).
POST /api/trunking/import Body: JSON or CSV with talkgroup / system definitions.

Discovery

Method Path Description
POST /api/trunking/discovery/start Body: {"bands": ["800 MHz PS"]} (optional).
POST /api/trunking/discovery/stop
GET /api/trunking/discovery/snapshot Current candidates + confirmed CCs in one Vec.
GET /api/trunking/discovery/results Confirmed CCs only.
POST /api/trunking/discovery/clear Wipe candidates + confirmed list.

HD Radio

Method Path Description
GET /api/hd_radio/status Sync state, current program, BER/PER, station info.
GET /api/hd_radio/messages PSD/SIS history (title/artist changes, station name).
GET /api/hd_radio/check Whether nrsc5 is available + correctly configured.
GET /api/hd_radio/aas/:filename Album-art / logo files sent by the station.

Aircraft (ADS-B)

Method Path Description
GET /api/aircraft/lookup Query: ?icao=ABCDEF. Returns registration, type, operator.

Live aircraft position data is in /api/protocol_messages (filter by protocol=adsb or protocol=uat).

LoRa

Method Path Description
GET /api/lora/messages Decoded LoRa packets + LoRaWAN MAC parsing.
POST /api/lora/clear Clear the message buffer.
GET /api/lora/regions List supported regional plans (US915, EU868, etc.).

Talkgroups

Method Path Description
GET /api/talkgroups All TGs across all systems.
GET /api/talkgroups/systems Configured trunked systems.
POST /api/talkgroups/update Update a single TG (priority, alpha tag, etc.).
POST /api/talkgroups/delete-system Body: {"name": "Pinellas P25"}.
GET /api/talkgroups/export Dump all TGs to JSON for backup.
POST /api/talkgroups/import Bulk import from JSON/CSV.

Channel banks

Method Path Description
GET /api/channels/banks List all channel banks.
POST /api/channels/banks/create Body: {"name": "Local Repeaters"}.
POST /api/channels/import Import channels from CHIRP / CSV / RadioReference.
POST /api/channels/scan/start Start scanning a bank.
POST /api/channels/scan/stop
GET /api/channels/bank-scan-config Current bank-scan configuration.

Spectrum + waterfall

Method Path Description
GET /api/spectrum Current FFT snapshot (frequency bins + dBFS magnitudes).

Events stream

Method Path Description
GET /api/events Server-Sent Events stream — every scanner / VFO / decoder / trunking event in real time.
# Tail every event the app emits
curl -N http://127.0.0.1:8765/api/events

Each event is a JSON object with a type field (scanner-state, vfo-update, frequency-found, talkgroup-active, hd-radio-status, etc.) and event-specific payload. Useful for live dashboards.

Settings

Method Path Description
GET /api/settings Full settings document.
POST /api/settings Replace settings (also accepts partial JSON for diff-merge).

Blacklist

Method Path Description
GET /api/blacklist Blocked frequencies.
POST /api/blacklist/add Body: {"frequency_hz": 152300000}.
POST /api/blacklist/remove
POST /api/blacklist/clear Wipe permanent blacklist.
POST /api/blacklist/clear-temporary Wipe session blacklist only.

Transcription

Method Path Description
POST /api/transcription/start Body: {"vfo_id": 0, "engine": "whisper-local"}.
POST /api/transcription/stop
GET /api/transcription/status Active jobs + queue depth.
GET /api/transcription/transcripts Completed transcripts.

Debug

These are for diagnostics, not stable contracts. Format may change between releases.

Method Path Description
GET /api/debug/stats Atomic counters — sync events, frames decoded, throughput, etc.
GET /api/debug/log In-memory log buffer.
GET /api/debug/log/tail Last N log lines.
GET /api/debug/dsd_stderr dsd-neo subprocess stderr (digital voice diagnostics).
GET /api/debug/provoice_stderr ProVoice decoder stderr.
GET /api/debug/multimon_raw multimon-ng raw output.
GET /api/debug/classifications Signal-classification raw scores.
GET /api/debug/noise_floor Adaptive noise-floor tracker state.
GET /api/debug/trunking/per_cc_stats Per-CC TSBK counts, sync stats.

Common patterns

Poll for new messages

cursor=0
while sleep 1; do
  resp=$(curl -s "http://127.0.0.1:8765/api/decoded_messages?since=$cursor")
  cursor=$(echo "$resp" | jq .cursor)
  echo "$resp" | jq .messages
done

Listen to events live

curl -N http://127.0.0.1:8765/api/events | while read line; do
  echo "$line" | jq .
done

Connect a device + lock to a frequency

curl -X POST http://127.0.0.1:8765/api/device/connect \
  -H "Content-Type: application/json" \
  -d '{"device_id": "rtl-sdr:0"}'

curl -X POST http://127.0.0.1:8765/api/scan/lock \
  -H "Content-Type: application/json" \
  -d '{"frequency_hz": 96100000, "mode": "wfm"}'

Headless deployment

Run NyxScope with no GUI:

nyxscope.exe --headless-api

The API is the only surface. Useful for Pi-hole-style deployments where the SDR is on a server elsewhere on the LAN.


For deeper diagnostics, see Troubleshooting. For the conceptual overview of what NyxScope does, see the README and MANUAL.md.

Clone this wiki locally