Summary
BluOS network audio player (Bluesound/NAD family) controlled over HTTP via the BluOS Custom Integration API. Covers status long-polling, volume/mute, playback control, play-queue management, presets, content browsing/search, player grouping, input selection, Bluetooth mode, doorbell chime, and reboot. The source is the platform-wide BluOS Custom Integration API document — no Zone-Network-specific protocol document exists.
Transport
protocols:
- http
addressing:
port: 11000 # stated: default for all BluOS players; CI580 exceptions use 11000/11010/11020/11030 per node
base_url: "http://{player_ip}:{port}/{request}" # pattern stated in source
auth:
type: none # inferred: no auth procedure in source
Traits
# inferred from command evidence in source
traits:
- levelable # inferred: volume/mute commands (/Volume)
- queryable # inferred: /Status, /SyncStatus, /Volume, /Playlist, /Presets queries
- routable # inferred: input/source selection (/Play?url=, /Play?inputIndex=, /Play?inputTypeIndex=)
Actions
actions:
- id: status_query
label: Playback Status Query
kind: query
command: "GET /Status?timeout={seconds}&etag={etag-value}"
params:
- name: timeout
type: integer
description: Optional long-poll duration in seconds. Recommended 100, no faster than 10.
- name: etag
type: string
description: Optional etag attribute from previous /Status response.
- id: sync_status_query
label: Player and Group Sync Status Query
kind: query
command: "GET /SyncStatus?timeout={seconds}&etag={etag-value}"
params:
- name: timeout
type: integer
description: Optional long-poll interval in seconds. Recommended 180.
- name: etag
type: string
description: Optional etag from previous /SyncStatus response.
- id: volume_query
label: Volume Query
kind: query
command: "GET /Volume"
params: []
- id: set_volume_level
label: Set Volume (level 0-100)
kind: action
command: "GET /Volume?level={level}&tell_slaves={on_off}"
params:
- name: level
type: integer
description: Absolute volume level, integer 0-100.
- name: tell_slaves
type: integer
description: 0 = selected player only; 1 = all players in group.
- id: set_volume_abs_db
label: Set Volume (absolute dB)
kind: action
command: "GET /Volume?abs_db={db}&tell_slaves={on_off}"
params:
- name: db
type: number
description: Absolute volume in dB.
- name: tell_slaves
type: integer
description: 0 = selected player only; 1 = all players in group.
- id: volume_up
label: Volume Up
kind: action
command: "GET /Volume?db={db}"
params:
- name: db
type: number
description: Volume increase in dB (typical value 2).
- id: volume_down
label: Volume Down
kind: action
command: "GET /Volume?db={db}"
params:
- name: db
type: number
description: Volume decrease in dB as negative number (typical value -2).
- id: mute_on
label: Mute On
kind: action
command: "GET /Volume?mute=1&tell_slaves={on_off}"
params:
- name: tell_slaves
type: integer
description: 0 = selected player only; 1 = all players in group.
- id: mute_off
label: Mute Off
kind: action
command: "GET /Volume?mute=0&tell_slaves={on_off}"
params:
- name: tell_slaves
type: integer
description: 0 = selected player only; 1 = all players in group.
- id: play
label: Play
kind: action
command: "GET /Play"
params: []
- id: play_seek
label: Play With Seek
kind: action
command: "GET /Play?seek={seconds}"
params:
- name: seek
type: integer
description: Jump position in seconds. Only valid if /Status includes totlen.
- id: play_seek_track
label: Play Track With Seek
kind: action
command: "GET /Play?seek={seconds}&id={trackid}"
params:
- name: seek
type: integer
description: Jump position in seconds.
- name: id
type: integer
description: Track id in the queue.
- id: play_url_stream
label: Play URL Stream
kind: action
command: "GET /Play?url={encodedStreamURL}"
params:
- name: encodedStreamURL
type: string
description: URL of streamed custom audio, must be URL-encoded.
- id: pause
label: Pause
kind: action
command: "GET /Pause"
params: []
- id: pause_toggle
label: Pause Toggle
kind: action
command: "GET /Pause?toggle=1"
params: []
- id: stop
label: Stop
kind: action
command: "GET /Stop"
params: []
- id: skip
label: Skip To Next Track
kind: action
command: "GET /Skip"
params: []
- id: back
label: Back To Previous / Track Start
kind: action
command: "GET /Back"
params: []
- id: shuffle_set
label: Set Shuffle
kind: action
command: "GET /Shuffle?state={state}"
params:
- name: state
type: integer
description: 0 = disable shuffle, 1 = enable shuffle.
- id: repeat_set
label: Set Repeat
kind: action
command: "GET /Repeat?state={state}"
params:
- name: state
type: integer
description: 0 = repeat queue, 1 = repeat track, 2 = repeat off.
- id: radio_action
label: Streaming Radio Station Action
kind: action
command: "GET /Action?service={service-name}&{action-param}={action-value}"
params:
- name: service-name
type: string
description: Music service name.
- name: action-param
type: string
description: skip, love, or ban - full URL is given by the <action> element in the /Status response; any URI is possible.
- name: action-value
type: string
description: Value from the <action> element URL in /Status response.
- id: playlist_list
label: List Play Queue Tracks
kind: query
command: "GET /Playlist?start={first}&end={last}"
params:
- name: start
type: integer
description: Optional first queue entry to include, from 0. Use with end for pagination.
- name: end
type: integer
description: Optional last queue entry to include.
notes: "GET /Playlist?length=1 returns queue status only (no track details). Unpaginated /Playlist may return a very long response."
- id: track_delete
label: Delete Track From Queue
kind: action
command: "GET /Delete?id={position}"
params:
- name: id
type: integer
description: Track id (queue position) to delete.
- id: track_move
label: Move Track In Queue
kind: action
command: "GET /Move?new={destination}&old={origin}"
params:
- name: new
type: integer
description: New position of the track being moved.
- name: old
type: integer
description: Old position of the track being moved.
- id: queue_clear
label: Clear Play Queue
kind: action
command: "GET /Clear"
params: []
- id: queue_save
label: Save Play Queue As Playlist
kind: action
command: "GET /Save?name={playlist_name}"
params:
- name: name
type: string
description: Name for the saved play queue.
- id: presets_list
label: List Presets
kind: query
command: "GET /Presets"
params: []
- id: preset_load
label: Load Preset
kind: action
command: "GET /Preset?id={presetId}"
params:
- name: id
type: string
description: Preset id number, or +1 for next preset, or -1 for previous preset. Presets loop around.
- id: browse
label: Browse Music Content
kind: query
command: "GET /Browse?key={key-value}&withContextMenuItems=1"
params:
- name: key
type: string
description: Optional browseKey/nextKey/parentKey/contextMenuKey value from earlier response, URL-encoded. Absence = top-level browse.
- name: withContextMenuItems
type: integer
description: Optional, always 1 - returns inline context menu for playlists, albums, tracks, stations, artists.
- id: search
label: Search Music Content
kind: query
command: "GET /Browse?key={key-value}&q={searchText}"
params:
- name: key
type: string
description: searchKey value from an earlier response.
- name: q
type: string
description: Search string. Without key, performs a top-level search.
- id: group_add_slave
label: Group One Secondary Player
kind: action
command: "GET /AddSlave?slave={secondaryPlayerIP}&port={secondaryPlayerPort}&group={GroupName}"
params:
- name: slave
type: string
description: IP address of the secondary player.
- name: port
type: integer
description: Port of the secondary player. Default 11000.
- name: group
type: string
description: Optional group name; BluOS assigns a default if omitted.
- id: group_add_slaves
label: Group Multiple Secondary Players
kind: action
command: "GET /AddSlave?slaves={secondaryPlayerIPs}&ports={secondaryPlayerPorts}"
params:
- name: slaves
type: string
description: Comma-separated IP addresses of secondary players.
- name: ports
type: string
description: Comma-separated port numbers of secondary players.
- id: group_remove_slave
label: Remove One Player From Group
kind: action
command: "GET /RemoveSlave?slave={secondaryPlayerIP}&port={secondaryPlayerPort}"
params:
- name: slave
type: string
description: IP of the player to remove.
- name: port
type: integer
description: Port of the player to remove.
- id: group_remove_slaves
label: Remove Multiple Players From Group
kind: action
command: "GET /RemoveSlave?slaves={secondaryPlayerIPs}&ports={secondaryPlayerPorts}"
params:
- name: slaves
type: string
description: Comma-separated IP addresses of players to remove.
- name: ports
type: string
description: Comma-separated port numbers of players to remove.
- id: reboot
label: Soft Reboot Player
kind: action
command: "POST /reboot"
params:
- name: yes
type: string
description: Any value (e.g. 1). Sent as form data (curl -d yes=1).
- id: doorbell_chime_play
label: Play Doorbell Chime
kind: action
command: "GET /Doorbell?play=1"
params: []
- id: inputs_list
label: List Active Inputs
kind: query
command: "GET /RadioBrowse?service=Capture"
params: []
- id: settings_capture_query
label: Query Capture Input Settings
kind: query
command: "GET /Settings?id=capture&schemaVersion=32"
params: []
- id: input_select_active
label: Select Active Input By URL
kind: action
command: "GET /Play?url={URL_value}"
params:
- name: URL_value
type: string
description: URL attribute from /RadioBrowse?service=Capture response. BluOS HUB inputs supported by this command only.
- id: input_select_index
label: Select External Input By Index
kind: action
command: "GET /Play?inputIndex={IndexId}"
params:
- name: inputIndex
type: integer
description: 1-based index of inputs from /Settings?id=capture&schemaVersion=32 in numerical order, Bluetooth excluded. Firmware newer than v3.8.0 and older than v4.2.0.
- id: input_select_type_index
label: Select External Input By Type-Index
kind: action
command: "GET /Play?inputTypeIndex={typeIndex}"
params:
- name: typeIndex
type: string
description: "Format type-index. Types: spdif, analog, coax, bluetooth, arc, earc, phono, computer, aesebu, balanced, microphone. Index starts at 1. Firmware v4.2.0 or newer."
- id: bluetooth_mode_set
label: Change Bluetooth Mode
kind: action
command: "GET /audiomodes?bluetoothAutoplay={value}"
params:
- name: value
type: integer
description: 0 = Manual, 1 = Automatic, 2 = Guest, 3 = Disabled.
Feedbacks
feedbacks:
- id: playback_state
type: enum
values: [play, pause, stop, stream, connecting]
source: "/Status <state>; play and stream have the same meaning; /Play resumes from pause but not stop"
- id: volume_level
type: integer
source: "/Status <volume>, /SyncStatus volume, /Volume response body; 0..100, -1 means fixed volume"
- id: volume_db
type: number
source: "/Status db, /Volume response db attribute"
- id: mute_state
type: enum
values: ["0", "1"]
source: "/Status mute, /SyncStatus mute, /Volume response mute attribute; 1 = muted"
- id: shuffle_state
type: enum
values: ["0", "1"]
source: "/Status <shuffle>; 0 = off, 1 = on"
- id: repeat_state
type: enum
values: ["0", "1", "2"]
source: "/Status <repeat>; 0 = repeat queue, 1 = repeat track, 2 = repeat off"
- id: now_playing_metadata
type: object
source: "/Status title1/title2/title3 (MUST be used for UI), twoline_title1/twoline_title2, album, artist, name, service, streamFormat, quality, totlen, secs, song"
- id: etag
type: string
source: "etag attribute of /Status and /SyncStatus root elements; opaque, used for long-polling change detection"
- id: sync_status
type: object
source: "/SyncStatus - name, model, modelName, brand, group, id, mac, master, slave(s), zone, zoneMaster, zoneSlave, initialized, syncStat"
- id: queue_id
type: string
source: "/Status <pid>; matches id attribute of /Playlist response; changes when queue changes"
- id: preset_id
type: string
source: "/Status <prid>; matches prid attribute of /Presets response; change means purge cached /Presets"
- id: battery
type: object
source: "/Status and /SyncStatus battery element (if battery pack): level percent, charging 1/0, icon URL"
- id: stream_url_flag
type: flag
source: "/Status <streamUrl> presence means queue not source of audio; song/shuffle/repeat/next/previous not relevant"
Variables
variables:
- id: volume
type: integer
range: "0..100 (-1 = fixed volume); dB variants constrained to configured range, typically -80..0"
set: "GET /Volume?level= | GET /Volume?abs_db= | GET /Volume?db="
- id: mute
type: boolean
set: "GET /Volume?mute=0|1"
- id: shuffle
type: enum
values: ["0", "1"]
set: "GET /Shuffle?state=0|1"
- id: repeat
type: enum
values: ["0", "1", "2"]
set: "GET /Repeat?state=0|1|2"
- id: bluetooth_autoplay
type: enum
values: ["0", "1", "2", "3"]
set: "GET /audiomodes?bluetoothAutoplay="
Events
# No unsolicited push events documented. State changes are observed via long-polling
# /Status and /SyncStatus with timeout and etag parameters.
events: []
Macros
# No multi-step sequences explicitly defined as macros in source.
# Note: external input selection is documented as a two-step procedure
# (query /RadioBrowse?service=Capture or /Settings?id=capture, then /Play?url=/inputIndex=).
macros: []
Safety
confirmation_required_for: []
interlocks: []
# UNRESOLVED: source contains no safety warnings or interlock procedures.
# Note: context-menu item type "delete" says user confirmation should be requested (browsing hint, not a safety interlock).
Notes
- Requests take the form
http://<player_ip>:<port>/<request>; port 11000 for all BluOS players except CI580 (4 nodes: 11000/11010/11020/11030). Actual port should be discovered via MDNS servicesmusc.tcpandmusp.tcp. - Lenbrook Service Discovery Protocol (LSDP): custom UDP-broadcast discovery on UDP port 11430 (IANA-assigned to Lenbrook). Announce ~every minute; startup burst of 7 packets at t=[0,1,2,3,5,7,10]s + 0-250ms random; query response delay 0-750ms random. Packet header: length, magic "LSDP", protocol version 1 (current).
- Polling limits: regular polling at most one request per 30 seconds; long-polling requests for the same resource never less than 1 second apart. Long-poll only one of /Status (recommended timeout 100s) or /SyncStatus (recommended 180s) — /Status includes indicating /SyncStatus changes.
- Grouped players: primary player is group main and selects source; requests to a secondary player for /Status, playback, queue, and browse are internally proxied to the primary. /SyncStatus long-polling needed to track each secondary player's volume.
- Volume range adjustable via BluOS Controller app (Settings -> Player -> Audio); typically -80..0 dB.
- secs is excluded from etag; clients must increment playback position locally when state is play or stream.
- Radio actions (/Action) URLs come from the element in /Status when playing a streaming radio station; any URI is possible, not only /Action.
- Preset numbers need not be sequential; presets loop top-to-bottom and bottom-to-top. Presets must be added/deleted via BluOS Controller app.
- Input selection is firmware-gated:
/Play?inputIndex=for firmware newer than v3.8.0 and older than v4.2.0;/Play?inputTypeIndex=for v4.2.0 or newer./Play?url=(11.1) works for active inputs from /RadioBrowse?service=Capture and is the only command supporting BluOS HUB inputs. External input selection via inputIndex/inputTypeIndex is recommended for CI. - Bluetooth excluded from inputIndex numbering. Sources must be connected and not hidden for input selection.
- /Skip and /Back only apply to play-queue playback (no in /Status); some streaming stations support skip/back/love/ban via /Action; TuneIn and Optical Input do not support skip.
- Title display: use title1/title2/title3 (three-line) or twoline_title1/twoline_title2 (two-line) for now-playing UI, not album/artist/name.
- Secondary-player proxying means /Delete, /Move etc. directed at a secondary affect the primary's queue.
Provenance
source_domains:
- bluesoundprofessional.com
- github.com
- content-bluesound-com.s3.amazonaws.com
source_urls:
- https://bluesoundprofessional.com/wp-content/uploads/2025/06/BluOS-Custom-Integration-API_v1.7.pdf
- https://github.com/albertony/blushell
- https://bluesoundprofessional.com/support/software-and-drivers/
- https://content-bluesound-com.s3.amazonaws.com/uploads/2022/04/Custom-Integration-API-v1.4.pdf
retrieved_at: 2026-06-03T23:52:38.844Z
last_checked_at: 2026-09-13T22:16:28.814Z
Verification Summary
verdict: verified
checked_at: 2026-09-13T22:16:28.814Z
matched_actions: 42
action_count: 42
confidence: medium
summary: "All 42 spec actions match HTTP endpoints documented verbatim in the BluOS Custom Integration API source; transport values are explicitly stated. (5 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "model-specific command differences not stated; source is platform-wide BluOS API doc"
- "source contains no safety warnings or interlock procedures."
- "no power on/off commands in source (soft reboot only)"
- "firmware version compatibility not stated beyond input-selection gating"
- "fixed grouping (zones) out of scope of source; zone/zoneMaster/zoneSlave attributes observed but no set commands documented"
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0