API
REST, WebSocket, and MCP drive the same live receiver as the interface. Changes reach every connected client.
| Endpoint | Serves |
|---|---|
/api/docs | Swagger UI |
/api/openapi.json | OpenAPI schema |
/api/ws | WebSocket |
/api/wt | WebTransport |
/mcp | MCP over streamable HTTP |
The OpenAPI schema is also in the repository, for generating clients without a running server.
With a token set, send it on every request:
curl -H "Authorization: Bearer $SDRMM_TOKEN" http://receiver.local:8080/api/state
REST
| Area | Routes |
|---|---|
| State and discovery | /api/state, /api/devices, /api/saved-radios, /api/channeltypes, /api/clients, /api/patch/catalog, /api/serial/ports, /api/position/nmea-devices |
| Nodes | /api/workspaces/active/nodes/{node}: channel and device settings, actions (tune, retype, scan, hunt, playback, network export, transmit, send); /api/devices/network and /api/devices/serial add a radio; /api/patch/wiring lists where a wire fits |
| Workspaces | /api/workspaces: activate, apply, undo, redo, export, import; /api/workspaces/active/resolved |
| Saved setups | /api/templates, /api/examples, /api/presets, /api/bookmarks |
| Data | /api/decoderlog, /api/recordings, /api/audiorecordings, /api/calls, /api/images, /api/occupancy, /api/sinks |
| Processing nodes | /api/arrays, /api/processors, /api/fusion, /api/survey, /api/missions |
| Tools | /api/tools, /api/nanovna, /api/cps (radio programmer), /api/denoise-models |
| Reference | /api/bandplan, /api/satellites, /api/ionosonde |
| Access | /api/auth, /api/phones |
| Credentials | /api/secrets: POST stores an Event output credential and returns its id, PUT /api/secrets/{id} sets one a workspace names. Values are never read back |
| Server | /api/status, /api/about, /api/doctor, /api/diagnostics, /api/transport |
Errors are JSON with error, an optional detail, and an optional stable code such as
not_found or auth.
WebSocket
Clients subscribe to streams over /api/ws. The server sends decoded records, scanner and hunt
progress, levels, node updates, state-change notices, and binary spectrum, audio, video, IQ,
symbol and surface frames. When it says some state changed, fetch that state again through REST.
Stream IDs belong to one connection. A client that sends Present joins the list of people
here and can send Point to share its pointer, selection, and drags. PipelineHealth reports
the queues and, over WebTransport, the round trip and packet loss of the client's own link.
WebTransport
GET /api/transport names the UDP port and the SHA-256 of the session certificate when the server
offers WebTransport. Connect to https://<server>:<port>/api/wt with that hash in
serverCertificateHashes, and ?token=... if a token is set. Read the hash before every
connection; the certificate rotates.
The session carries the same messages as the WebSocket. Each stream message follows its length
as a little-endian u32:
| Carrier | Holds |
|---|---|
| The bidirectional stream the client opens | ClientCommand up, ServerEvent down, as JSON |
| Datagrams | Audio frames, one each; drop any that arrive behind a newer one |
| Server streams | The binary frames of one stream ID each, newest first when the link is slow |
A workspace PUT sent against an older revision is merged with what others wrote since. A channel
PATCH with a base lands only the fields changed from it. Undo and redo act on the caller's own
steps, named by the x-sdrmm-author header. The messages are ClientCommand and ServerEvent in the
OpenAPI schema; the web client in web/src is the reference implementation.
MCP
Point an MCP client at /mcp on the server, with the bearer header if a token is set. Its
tools edit the open canvas the way a user does: add, change and remove nodes, draw and cut wires,
tune radios, set channels, scan, and undo. Every change shows up on the canvas. It also reads the
decoder log and spectrum, and runs the tools. Tool arguments use the
same types as the OpenAPI schema.