Stream Deck API
Integrate the Sonoran Radio Stream Deck plugin with desktop or FiveM.
Sonoran Radio includes a Stream Deck plugin that can control the desktop application directly or control the FiveM radio through the desktop app.
This document covers the public integration contract for:
the built-in desktop bridge exposed by the Electron app
the built-in FiveM bridge exposed by the Electron app when Stream Deck actions are set to
FiveM
Overview
Each Stream Deck action is configured with a target:
Desktopsends commands directly to Sonoran Radio DesktopFiveMsends commands to Sonoran Radio Desktop, which forwards them to a FiveM client over localhost
The plugin uses the same command and snapshot schema for both targets. The difference is transport:
Desktopuses local HTTP requests to Sonoran Radio DesktopFiveMuses local HTTP requests to Sonoran Radio Desktop, and Sonoran Radio Desktop forwards commands and receives snapshots over a local WebSocket connected by your FiveM client script
Recommended FiveM Architecture
When the Stream Deck action target is set to FiveM, the recommended flow is:
Stream Deck Plugin
-> Sonoran Radio Desktop HTTP bridge
-> local FiveM WebSocket client
-> FiveM client script
-> Sonoran Radio iframe/NUI
Sonoran Radio iframe/NUI
-> FiveM client script
-> local FiveM WebSocket client
-> Sonoran Radio Desktop snapshot cache
-> Stream Deck Plugin label/status pollingThis means the Stream Deck plugin does not need to talk to the FiveM NUI directly anymore. As long as:
Sonoran Radio Desktop is running
the Stream Deck action is set to
FiveMyour FiveM client script is connected to the desktop WebSocket
your FiveM client script forwards commands to the iframe and forwards snapshots back to desktop
the plugin will behave the same as normal.
Desktop Bridge
When Sonoran Radio Desktop is running, it starts a local HTTP bridge on:
Health Check
GET /streamdeck/health
Response:
Get Current Snapshot
GET /streamdeck/labels
Response:
Send a Command
POST /streamdeck/command
Headers:
Example request:
Example response:
If the command is invalid, the radio is not ready, or the payload is malformed, the bridge returns a non-200 response.
FiveM Desktop Bridge
When the Stream Deck action target is set to FiveM, the plugin first talks to the desktop app at:
The desktop app then talks to your FiveM client over:
Health Check
GET /streamdeck/fivem/health
Response:
Get Current FiveM Snapshot
GET /streamdeck/fivem/labels
Response:
Forward a Command to FiveM
POST /streamdeck/fivem/command
Headers:
Request:
Response:
If no FiveM socket clients are connected, the desktop app returns a non-200 response.
WebSocket Message Contract
Your FiveM client should connect to:
Messages Sent From Desktop to FiveM
hello
Sent immediately after the socket connects.
streamdeck_command
Sent when a Stream Deck action is pressed/rotated while targeting FiveM.
streamdeck_snapshot
Sent when the FiveM client explicitly requests the latest cached snapshot.
Messages Sent From FiveM to Desktop
streamdeck_snapshot
Send this whenever the iframe publishes a new radio snapshot.
streamdeck_snapshot_request
Optional. Ask the desktop app to send back its current cached snapshot.
Optional Acknowledgements
The desktop app may reply with:
streamdeck_snapshot_ackstreamdeck_command_ack
These are informational and do not need special handling.
Command Payload
All commands use the same JSON shape:
Fields:
command
string
Yes
One of the supported command IDs listed below
phase
"down" or "up"
No
Defaults to "down" if omitted
channelId
number
Conditional
Used by single-channel commands
channelIds
number[]
Conditional
Used by multi-channel commands
Phase Rules
Most commands execute on phase: "down".
The following hold-style commands use both phases:
transmit.ptttransmit.tempChannel
For those commands:
send
phase: "down"when the button is pressedsend
phase: "up"when the button is released
Supported Commands
group.next
None
Move to the next channel group
group.previous
None
Move to the previous channel group
channel.next
None
Move to the next channel within the current group
channel.previous
None
Move to the previous channel within the current group
transmit.toggleChannels
channelIds
Toggle one or more transmit channels
transmit.tempChannel
channelId, phase
Temporarily transmit on a single channel while held
scan.toggleChannels
channelIds
Toggle one or more scan channels
toggle.ai
None
Toggle AI on or off
transmit.ptt
phase
Push-to-talk
toggle.toneBoard
None
Open or close the tone board
audio.volumeUp
None
Increase master volume
audio.volumeDown
None
Decrease master volume
audio.volumeMute
None
Toggle master mute
audio.sfxUp
None
Increase SFX volume
audio.sfxDown
None
Decrease SFX volume
audio.sfxMute
None
Toggle SFX mute
audio.aiUp
None
Increase AI volume
audio.aiDown
None
Decrease AI volume
audio.aiMute
None
Toggle AI mute
audio.currentChannelsUp
None
Increase current primary channel volume
audio.currentChannelsDown
None
Decrease current primary channel volume
audio.currentChannelsMute
None
Toggle mute for current primary channels
desktop.connectedUsers
None
Open the connected users window
desktop.focusRadio
None
Focus the Sonoran Radio desktop window
desktop.toggleRadio
None
Show or hide the Sonoran Radio desktop window
Snapshot Schema
The plugin reads a snapshot to populate action configuration, channel selectors, and active button state.
Channels
id
number
Channel/profile ID
label
string
Display name shown in the plugin
groupId
number
Parent group ID
groupName
string
Parent group display name
State
connected
boolean
Whether the radio is currently connected
aiEnabled
boolean
Whether AI is enabled
micOpen
boolean
Whether the microphone/PTT is currently active
primaryChIds
number[]
Current transmit channels
scannedChIds
number[]
Current scan channels
sfxVolume
number
Current SFX volume
agentGain
number
Current AI volume
FiveM Iframe Message Contract
Inside the FiveM web view, Sonoran Radio uses iframe messages for Stream Deck integration.
Messages Sent To Sonoran Radio
streamdeck_command
Send a standard command payload:
streamdeck_snapshot_request
Request that the iframe publish its latest state:
Messages Sent From Sonoran Radio
streamdeck_snapshot
The iframe emits this message whenever radio/channel state changes and also in response to streamdeck_snapshot_request.
FiveM JavaScript Example
The following browser-side example shows the minimum bridge needed in FiveM to make Stream Deck FiveM mode work through Sonoran Radio Desktop.
This example assumes:
your FiveM client script can open a browser WebSocket to
ws://127.0.0.1:39112/streamdeck/fivem/socketyour client script can forward messages to the Sonoran Radio iframe/NUI
your iframe/NUI can send
streamdeck_snapshotmessages back to this script
Notes
Use channel IDs exactly as returned by the snapshot.
transmit.tempChannelandtransmit.pttshould send both press and release phases.Multi-channel commands should send
channelIdsas an array of numbers.Your FiveM client does not need to translate command names or payload fields. Forward them exactly as documented.
The desktop app caches the most recent FiveM snapshot, so send
streamdeck_snapshotwhenever radio state changes inside the iframe.
Last updated
Was this helpful?

