-
Notifications
You must be signed in to change notification settings - Fork 7
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
- Status + health
- Device control
- Scanner control
- Decoded messages
- Trunking
- HD Radio
- Aircraft (ADS-B)
- LoRa
- Talkgroups
- Channel banks
- Spectrum + waterfall
- Events stream
- Settings
- Debug
- Common patterns
-
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
GETfor reads,POSTfor actions. JSON request bodies; JSON responses. -
Errors: non-2xx status code, body is
{"error": "message"}.
| 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| 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). |
| 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. |
| 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}. |
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=0The response includes a cursor field — pass that as since=<cursor> next time to get only new messages.
| 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. |
| 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. |
| 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. |
| 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).
| 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.). |
| 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. |
| 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. |
| Method | Path | Description |
|---|---|---|
| GET | /api/spectrum |
Current FFT snapshot (frequency bins + dBFS magnitudes). |
| 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/eventsEach 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.
| Method | Path | Description |
|---|---|---|
| GET | /api/settings |
Full settings document. |
| POST | /api/settings |
Replace settings (also accepts partial JSON for diff-merge). |
| 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. |
| 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. |
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. |
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
donecurl -N http://127.0.0.1:8765/api/events | while read line; do
echo "$line" | jq .
donecurl -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"}'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.