Command reference
Send each command as a separate JSON text message over an authenticated
WebSocket connection. Start with the connection guide
if you have not received your first state yet.
All field names are case-sensitive. Replace example IDs with values from your latest state. The server applies the same playback rules, locks, and feature access as the app. Use subsequent snapshots to confirm the result; a successful send is not an acknowledgement that a command ran.
State and connection
Section titled “State and connection”| Command | Purpose |
|---|---|
{"type":"request_state"} |
Request a fresh full snapshot, for example after losing local state. Routine polling is unnecessary. |
{"type":"ping"} |
Receive {"type":"pong"} if hello_ok.features includes ping. |
Launch a playable
Section titled “Launch a playable”play_playable
Section titled “play_playable”{ "type": "play_playable", "playable_id": "playable-id", "action": "start", "next_volume": 70, "next_pan": 0}playable_id is required and comes from project.categories[].playables[].id.
A playable is a project button, such as a sound, video, image, or instruction.
Launching it can create a player with a different runtime ID.
| Optional field | Meaning and default |
|---|---|
action |
Launch action below; defaults to start. |
next_volume |
Integer display percentage, 0–100. Defaults to control.next_sound_volume. |
next_pan |
Pan percentage, -100 (left) to 100 (right). Defaults to 0 (center). |
| Action | Behavior |
|---|---|
start |
Start the playable using its configured playback behavior. |
fade_in |
Start with a fade-in. |
crossfade |
Start with the app’s crossfade action. |
replace |
Start with the app’s replace action. |
toggle |
Stop matching active players, or start if none are active. |
toggle_fade |
Fade out matching active players, or start if none are active. |
Action behavior depends on the playable type and its configuration. The WebSocket launch command has no output-device field; use the configured routing and output selection in Sound Show.
Global playback
Section titled “Global playback”stop_all and fade_out_all
Section titled “stop_all and fade_out_all”{ "type": "stop_all" }{ "type": "fade_out_all", "duration_ms": 1500 }These affect unlocked sound and visual players. stop_all stops immediately
unless you supply a positive duration. fade_out_all uses the app’s fade
behavior when no duration is supplied. Both accept optional duration_seconds
or duration_ms; send one unit at a time. Custom global durations apply to
sound players; visual players use the app’s visual fade behavior.
pause_all and resume_all
Section titled “pause_all and resume_all”{ "type": "pause_all", "fade": false }{ "type": "resume_all", "fade": false }Pause unlocked sound and visual players, or resume paused players. The optional
fade flag applies to sound players; visual players use their normal pause
and resume behavior.
Control a running player
Section titled “Control a running player”Use players[].id for every player_id below. A playable ID cannot replace
a player ID. Resolve the player again after playback ends or the project changes.
toggle_player_playback
Section titled “toggle_player_playback”{ "type": "toggle_player_playback", "player_id": "player-id", "fade": false }Toggle pause/resume. fade is optional.
toggle_player_loop
Section titled “toggle_player_loop”{ "type": "toggle_player_loop", "player_id": "player-id" }Toggle the running player’s loop state. Locked players ignore this action.
Read the resulting loop_enabled from the player snapshot. This does not
edit the project’s playable configuration.
stop_player and fade_out_player
Section titled “stop_player and fade_out_player”{ "type": "stop_player", "player_id": "player-id" }{ "type": "fade_out_player", "player_id": "player-id", "duration_seconds": 2 }Both accept optional duration_seconds or duration_ms. stop_player with a
positive duration fades out instead of stopping immediately. fade_out_player
uses the default fade when no duration is given.
seek_player
Section titled “seek_player”{ "type": "seek_player", "player_id": "player-id", "position_seconds": 12.5 }Alternatively send position_percent from 0 to 100. Send one position
field at a time. Percentages refer to the full source timeline, even when
the playable has trimmed start and stop points. The result is clamped to the
player’s playback window. Unknown durations cannot be sought unless an
explicit stop time provides a finite timeline. See player state.
set_player_volume
Section titled “set_player_volume”{ "type": "set_player_volume", "player_id": "player-id", "volume": 65 }volume is a display percentage from 0 to 100, not a linear audio gain.
Read volume_percent from snapshots for the displayed result.
set_player_muted
Section titled “set_player_muted”{ "type": "set_player_muted", "player_id": "player-id", "muted": true, "duration_ms": 1000 }Use muted: false to unmute. Omit duration_ms or use 0 for an immediate
change; a positive duration fades the mute/unmute. The maximum is 60000 ms.
Shared controls and volume levels
Section titled “Shared controls and volume levels”set_next_sound_volume
Section titled “set_next_sound_volume”{ "type": "set_next_sound_volume", "volume": 70 }Set the default volume for future launches to an integer from 0 to 100.
This updates control.next_sound_volume.
set_selected_category
Section titled “set_selected_category”{ "type": "set_selected_category", "category_id": "category-id" }Update the shared category selection. Use category_id: null to clear it.
set_volume_level_active and toggle_volume_level
Section titled “set_volume_level_active and toggle_volume_level”{ "type": "set_volume_level_active", "level_id": "speech", "active": true }{ "type": "toggle_volume_level", "level_id": "speech" }Get level_id from control.volume_level_presets[].id. For a hold button,
send active: true on press and active: false on release over the same
connection. Use toggle_volume_level for a latching button.
The hold belongs to your connection and is released when it disconnects.
Sound Show applies the preset’s direction and fade rules to its selected
output. control_snapshot reports the new active target immediately; output
volume snapshots show the fade progressing.
clear_volume_levels
Section titled “clear_volume_levels”{ "type": "clear_volume_levels" }Release all remote-controlled volume levels. This is a global clear, not just
the hold belonging to your connection. To release your own hold, send
set_volume_level_active with active: false instead.
set_low_volume_active (compatibility)
Section titled “set_low_volume_active (compatibility)”{ "type": "set_low_volume_active", "active": true }Activate the low preset, or the first configured preset if low does not
exist. New integrations should use an explicit level_id.
Outputs
Section titled “Outputs”Use logical_devices[].id to target a Sound Show logical output. IDs refer to
the app’s routing, not operating-system device names or numeric positions.
select_logical_device
Section titled “select_logical_device”{ "type": "select_logical_device", "logical_device_id": "main" }set_logical_device_volume
Section titled “set_logical_device_volume”{ "type": "set_logical_device_volume", "logical_device_id": "main", "volume": 80 }volume is an integer display percentage from 0 to 100. Check the target’s
available flag before offering controls.
Audio effects
Section titled “Audio effects”Discover supported controls and their ranges through
capabilities.audio_controls.
Only offer a control if its descriptor supports your target’s scope.
set_audio_control
Section titled “set_audio_control”{ "type": "set_audio_control", "target": { "kind": "logical_device", "id": "main" }, "control_id": "five_eq.high_mid_gain_db", "value": -6, "fade_duration_ms": 750, "command_id": "eq-change-1"}Required fields are target, control_id, and value. target.kind is
logical_device or player, and target.id is that target’s current ID.
Values are absolute, in the descriptor’s native units. The server validates
the range and the affected effect settings together; a value inside one
control’s range can still conflict with another setting, such as EQ crossovers.
reset_audio_control
Section titled “reset_audio_control”{ "type": "reset_audio_control", "target": { "kind": "player", "id": "player-id" }, "control_id": "pan", "fade_duration_ms": 500, "command_id": "pan-reset-1"}Reset to the descriptor’s current default_value.
Both commands accept optional fade_duration_ms from 0 to 60000; omitted
or 0 applies immediately. A newer command for the same target and control
replaces an active fade. Locked players are rejected. Optional command_id
is echoed in errors for these commands; it does not create a success response
or make retries safe to repeat automatically.
Project lights
Section titled “Project lights”set_project_light_level
Section titled “set_project_light_level”{ "type": "set_project_light_level", "project_light_id": "project-light-id", "value_percent": 72, "fade_duration_ms": 1200, "command_id": "light-change-1"}Use an ID from lights.lights[].id. value_percent is an absolute 0–100
level. fade_duration_ms and command_id are optional with the same bounds
and error-correlation behavior as audio controls. A new write to the same
light replaces its active fade.
Configure the project light and its QLC+ connection in Sound Show first. The target must be available; starting a fade also requires a readable current level. The command respects the light’s configured range, inversion, and feature access.
Instructions
Section titled “Instructions”trigger_current_instruction_go
Section titled “trigger_current_instruction_go”{ "type": "trigger_current_instruction_go", "next_volume": 70, "next_pan": 0 }Trigger GO on the current instruction player. Optional next_volume and
next_pan have the same units and defaults as play_playable.
set_instruction_next
Section titled “set_instruction_next”{ "type": "set_instruction_next", "player_index": 0, "path": [1, 0] }Both fields are required. player_index is a zero-based position in
instructions.players. Copy path from the desired item’s snapshot; offer
selection for items with can_set_next: true and a nonempty path. This changes
the next instruction without triggering GO or editing the definition.
Playlists
Section titled “Playlists”Playlist and item indexes are zero-based positions in the current
playlists.playlists array and a playlist’s queue. Resolve them again after
state changes; a saved index can point to a different item after reordering.
playlist_play_next
Section titled “playlist_play_next”{ "type": "playlist_play_next", "playlist_index": 0, "activate_autoplay": true, "crossfade_all": false }All three fields are optional. Omitted playlist_index uses
playlists.current_index; activate_autoplay and crossfade_all default to
false.
playlist_play_item
Section titled “playlist_play_item”{ "type": "playlist_play_item", "playlist_index": 0, "item_index": 2, "crossfade_all": false }Both indexes are required. Play the item now using the app’s normal autoplay,
looping, and queue-advancement rules. Optional crossfade_all: true requests
the app’s right-click behavior; it defaults to false.
set_playlist_autoplay
Section titled “set_playlist_autoplay”{ "type": "set_playlist_autoplay", "playlist_index": 0, "autoplay": true, "crossfade_current_sounds": false }autoplay is required. Omitted playlist_index uses playlists.current_index.
Optional crossfade_current_sounds defaults to false.
Timers
Section titled “Timers”Each command requires a zero-based timer_index from the current timers array.
{ "type": "start_timer", "timer_index": 0 }{ "type": "pause_timer", "timer_index": 0 }{ "type": "reset_timer", "timer_index": 0 }These use the timer’s configuration in Sound Show. Read timers_snapshot
messages to display elapsed time, remaining time, and running state.