Summary
BluOS-based multi-room music streamer from Bluesound / NAD Electronics. Control via HTTP GET/POST requests sent to port 11000 on the player IP; responses are UTF-8 encoded XML. Discovery optionally via mDNS (services musc.tcp and musp.tcp) or via LSDP (Lenbrook Service Discovery Protocol) over UDP broadcast on port 11430.
Transport
protocols:
- http
- udp
addressing:
base_url: "http://<player_ip>:11000"
port: 11000
discovery_port: 11430
auth:
type: none # inferred: no auth procedure in source
Traits
- powerable # UNRESOLVED: no explicit power on/off commands in source; reboot exists
- queryable # inferred from /Status, /SyncStatus, /Volume query examples
- routable # inferred from /Play?inputTypeIndex, /Play?inputIndex, and /Play?url input selection examples
- levelable # inferred from /Volume?level, /Volume?db, mute commands
Actions
- id: status_query
label: Playback Status
kind: query
command: "GET /Status?timeout={seconds}&etag={etag-value}"
params:
- name: timeout
type: integer
description: Optional long-poll interval in seconds (recommended 100)
- name: etag
type: string
description: Optional etag from previous /Status response
- id: sync_status_query
label: Player and Group Sync Status
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_set
label: Set Volume (Level)
kind: action
command: "GET /Volume?level={level}&tell_slaves={on_off}"
params:
- name: level
type: integer
description: Absolute volume 0-100
- name: tell_slaves
type: integer
description: 0 = this player only, 1 = include all grouped players
- id: volume_set_abs_db
label: Set Volume (Absolute dB)
kind: action
command: "GET /Volume?abs_db={db}&tell_slaves={on_off}"
params:
- name: abs_db
type: number
description: Absolute volume in dB
- name: tell_slaves
type: integer
description: 0 = this player only, 1 = include all grouped players
- id: volume_set_relative_db
label: Set Volume (Relative dB)
kind: action
command: "GET /Volume?db={delta-db}&tell_slaves={on_off}"
params:
- name: db
type: number
description: Relative volume change in dB (positive or negative)
- name: tell_slaves
type: integer
description: 0 = this player only, 1 = include all grouped players
- id: volume_up
label: Volume Up
kind: action
command: "GET /Volume?db=2"
params: []
- id: volume_down
label: Volume Down
kind: action
command: "GET /Volume?db=-2"
params: []
- id: mute_on
label: Mute On
kind: action
command: "GET /Volume?mute=1"
params: []
- id: mute_off
label: Mute Off
kind: action
command: "GET /Volume?mute=0"
params: []
- id: play
label: Play
kind: action
command: "GET /Play"
params: []
- id: play_seek
label: Play at Seek Position
kind: action
command: "GET /Play?seek={seconds}"
params:
- name: seek
type: integer
description: Position in seconds within current track
- id: play_seek_id
label: Play at Seek Position by Track ID
kind: action
command: "GET /Play?seek={seconds}&id={trackid}"
params:
- name: seek
type: integer
description: Position in seconds
- name: id
type: integer
description: Track id within play queue
- id: play_url
label: Play Stream URL
kind: action
command: "GET /Play?url={encodedStreamURL}"
params:
- name: url
type: string
description: URL-encoded stream URL
- 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 / Previous Track
kind: action
command: "GET /Back"
params: []
- id: shuffle
label: Shuffle Queue
kind: action
command: "GET /Shuffle?state={state}"
params:
- name: state
type: integer
description: 0 = disable shuffle, 1 = enable shuffle
- id: repeat
label: Set Repeat Mode
kind: action
command: "GET /Repeat?state={state}"
params:
- name: state
type: integer
description: 0 = repeat queue, 1 = repeat track, 2 = repeat off
- id: action_streaming_radio
label: Streaming Radio Action
kind: action
command: "GET /Action?service={service-name}&action={action-URL}"
params:
- name: service
type: string
description: Service name (e.g. Slacker)
- name: action
type: string
description: Action URL from <action> element in /Status response
- id: playlist_list
label: List Play Queue
kind: query
command: "GET /Playlist"
params: []
- id: playlist_status
label: Play Queue Status
kind: query
command: "GET /Playlist?length=1"
params: []
- id: playlist_paginate
label: Paginate Play Queue
kind: query
command: "GET /Playlist?start={first}&end={last}"
params:
- name: start
type: integer
description: First entry (0-based)
- name: end
type: integer
description: Last entry
- id: delete_track
label: Delete Track from Queue
kind: action
command: "GET /Delete?id={position}"
params:
- name: id
type: integer
description: Position of track to delete in queue
- id: move_track
label: Move Track in Queue
kind: action
command: "GET /Move?new={destination}&old={origin}"
params:
- name: new
type: integer
description: New position
- name: old
type: integer
description: Old position
- id: clear_queue
label: Clear Play Queue
kind: action
command: "GET /Clear"
params: []
- id: save_queue
label: Save Play Queue as Playlist
kind: action
command: "GET /Save?name={playlist_name}"
params:
- name: name
type: string
description: Playlist name
- 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, or +1 for next, -1 for previous
- id: browse
label: Browse Music Content
kind: query
command: "GET /Browse?key={key-value}"
params:
- name: key
type: string
description: URL-encoded browseKey / nextKey / parentKey
- id: browse_with_context
label: Browse with Inline Context Menu
kind: query
command: "GET /Browse?key={key-value}&withContextMenuItems=1"
params:
- name: key
type: string
description: URL-encoded browseKey
- name: withContextMenuItems
type: string
description: Always "1"
- id: search
label: Search Music Content
kind: query
command: "GET /Browse?key={key-value}&q={searchText}"
params:
- name: key
type: string
description: URL-encoded searchKey from earlier response
- name: q
type: string
description: Search string
- id: add_slave
label: Group Two Players
kind: action
command: "GET /AddSlave?slave={secondaryPlayerIP}&port={secondaryPlayerPort}&group={GroupName}"
params:
- name: slave
type: string
description: Secondary player IP
- name: port
type: integer
description: Secondary player port
- name: group
type: string
description: Optional group name
- id: add_slaves
label: Group Multiple Players
kind: action
command: "GET /AddSlave?slaves={secondaryPlayerIPs}&ports={secondaryPlayerPorts}"
params:
- name: slaves
type: string
description: Comma-separated secondary player IPs
- name: ports
type: string
description: Comma-separated secondary player ports
- id: remove_slave
label: Remove One Player From Group
kind: action
command: "GET /RemoveSlave?slave={secondaryPlayerIP}&port={secondaryPlayerPort}"
params:
- name: slave
type: string
description: Secondary player IP
- name: port
type: integer
description: Secondary player port
- id: 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 secondary player IPs
- name: ports
type: string
description: Comma-separated secondary player ports
- id: reboot
label: Reboot Player
kind: action
command: "POST /reboot"
params:
- name: yes
type: string
description: Any value (e.g. 1); required as POST body (`-d yes=1`)
- id: doorbell_chime
label: Play Doorbell Chime
kind: action
command: "GET /Doorbell?play=1"
params: []
- id: active_input_select
label: Active Input Selection
kind: action
command: "GET /Play?url={URL_value}"
params:
- name: url
type: string
description: URL attribute from /RadioBrowse?service=Capture response
- id: external_input_select_legacy
label: External Input Selection (firmware >v3.8.0 and <v4.2.0)
kind: action
command: "GET /Play?inputIndex={IndexId}"
params:
- name: inputIndex
type: integer
description: Input index (starts at 1); Bluetooth excluded
- id: external_input_select_v4_2
label: External Input Selection (firmware v4.2.0+)
kind: action
command: "GET /Play?inputTypeIndex={typeIndex}"
params:
- name: inputTypeIndex
type: string
description: Format type-index (e.g. spdif-2). Type is one of spdif|analog|coax|bluetooth|arc|earc|phono|computer|aesebu|balanced|microphone
- id: bluetooth_mode_set
label: Set Bluetooth Mode
kind: action
command: "GET /audiomodes?bluetoothAutoplay={value}"
params:
- name: bluetoothAutoplay
type: integer
description: "0 = Manual, 1 = Automatic, 2 = Guest, 3 = Disabled"
- id: settings_get
label: Get Settings (Capture)
kind: query
command: "GET /Settings?id=capture&schemaVersion=32"
params: []
Feedbacks
- id: playback_status
type: object
description: "/Status XML response; key fields include state (play|pause|stop|stream|connecting), volume (0..100 or -1 fixed), mute (0|1), db, muteDb, muteVolume, song, totlen, secs, repeat (0|1|2), shuffle (0|1), service, album, artist, title1, title2, title3, image, canSeek (0|1), canMovePlayback, pid, prid, syncStat, etag"
- id: sync_status
type: object
description: "/SyncStatus XML response; key fields include volume (0..100 or -1), db, mute (0|1), muteDb, muteVolume, model, modelName, brand, name, group, id (ip:port), mac, icon, schemaVersion, initialized, syncStat, etag; plus master/slave entries with port and id"
- id: volume_state
type: object
description: "/Volume response: <volume db=\"...\" mute=\"0|1\" offsetDb=\"...\" etag=\"...\">level</volume>; muteDb and muteVolume present when muted"
- id: play_state
type: enum
values: [play, stream, pause, stop, connecting]
description: State attribute after playback commands"
- id: doorbell_status
type: object
description: "<status enable=\"0|1\" volume=\"...\" chime=\"...\"/> response for doorbell"
- id: radio_browse_capture
type: object
description: "/RadioBrowse?service=Capture response lists available active inputs with URL attribute"
- id: load_preset_response
type: object
description: "/Preset response: <loaded service=\"...\"> <entries>N</entries> </loaded> for playlists; <state>stream</state> for radio"
- id: preset_state
type: enum
values: [stream]
description: State when loaded preset is a radio"
- id: streaming_radio_action_ack
type: object
description: "/Action response: <skip/>, <back/>, <love>1</love>, or <love skip=\"1\">0</love>"
- id: playlist_status
type: object
description: "<playlist name=\"...\" modified=\"0|1\" length=\"...\" id=\"...\" shuffle=\"0|1\" repeat=\"0|1|2\"> with <song> entries"
- id: delete_ack
type: integer
description: "<deleted>position</deleted> from /Delete"
- id: move_ack
type: string
description: "<moved>moved</moved> from /Move"
- id: clear_status
type: object
description: "<playlist modified=\"0|1\" length=\"0\" id=\"...\"/> from /Clear"
- id: save_status
type: object
description: "<saved><entries>N</entries></saved> from /Save"
- id: add_slave_ack
type: object
description: "<addSlave><slave port=\"...\" id=\"...\"/></addSlave> from /AddSlave"
Variables
- id: volume_level
type: integer
range: "0..100 (or -1 = fixed)"
description: Settable via /Volume?level
- id: volume_db
type: number
description: Settable via /Volume?abs_db or /Volume?db; constrained to configured available volume range (typically -80..0)
- id: mute_state
type: integer
enum: [0, 1]
description: Settable via /Volume?mute
- id: repeat_state
type: integer
enum: [0, 1, 2]
description: 0 = repeat queue, 1 = repeat track, 2 = repeat off
- id: shuffle_state
type: integer
enum: [0, 1]
description: 0 = off, 1 = on (via /Shuffle?state)
- id: seek_position
type: integer
description: Seconds within current track (via /Play?seek)
- id: doorbell_volume
type: integer
description: Returned by /Doorbell response
- id: bluetooth_autoplay
type: integer
enum: [0, 1, 2, 3]
description: "0=Manual, 1=Automatic, 2=Guest, 3=Disabled (via /audiomodes?bluetoothAutoplay)"
- id: input_type_index
type: string
description: '{type}-{index}; type in spdif|analog|coax|bluetooth|arc|earc|phono|computer|aesebu|balanced|microphone, index starts at 1'
Events
# UNRESOLVED: source does not document unsolicited notification pushes (only long-polling for /Status and /SyncStatus). The only documented notification surface is the <notifyurl> element returned in /Status.
Macros
# UNRESOLVED: no multi-step macro sequences described in source.
Safety
confirmation_required_for: []
interlocks: []
Notes
- All requests are HTTP GET (except
/rebootwhich is HTTP POST); responses are UTF-8 encoded XML. - Discovery: mDNS services
musc.tcpandmusp.tcpshould be used to discover the player IP and port. Alternatively, LSDP (Lenbrook Service Discovery Protocol) uses UDP broadcast on port 11430 (registered with IANA, assigned to Lenbrook as of 2014-03-27). Source: section 13.1. - Polling rate limit: regular polling should be at most once every 30 seconds; long-polling clients must not make two consecutive requests for the same resource less than one second apart.
- For CI580 (4 streamers in one chassis): node 1 = port 11000, node 2 = 11010, node 3 = 11020, node 4 = 11030.
- Grouping: only the primary player selects source; many requests directed at secondary players are internally proxied to the primary. Use
/SyncStatuslong-polling to track per-secondary volume. - Input selection command changed in BluOS firmware v4.2.0: legacy
/Play?inputIndex=N(Bluetooth excluded, 1-based order in/Settings?id=capture&schemaVersion=32) replaced by/Play?inputTypeIndex={type}-{index}. - Source document is "BluOS Custom Integration API" versions 1.0-1.7 (last updated 2025-04-09); describes only a subset of the full BluOS API Control Protocol.
Provenance
source_domains:
- bluesoundprofessional.com
source_urls:
- https://bluesoundprofessional.com/wp-content/uploads/2025/06/BluOS-Custom-Integration-API_v1.7.pdf
- https://bluesoundprofessional.com/software-and-drivers/
- https://bluesoundprofessional.com/control-systems/
retrieved_at: 2026-05-21T14:13:45.664Z
last_checked_at: 2026-09-13T22:18:16.810Z
Verification Summary
verdict: verified
checked_at: 2026-09-13T22:18:16.810Z
matched_actions: 44
action_count: 44
confidence: medium
summary: "All 44 spec actions map verbatim to endpoints in the BluOS Custom Integration API source; transport values port 11000 and 11430 confirmed. (5 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "source describes the BluOS Custom Integration API subset of the full BluOS API Control Protocol; some commands in the full protocol are not covered here."
- "no explicit power on/off commands in source; reboot exists"
- "source does not document unsolicited notification pushes (only long-polling for /Status and /SyncStatus). The only documented notification surface is the <notifyurl> element returned in /Status."
- "no multi-step macro sequences described in source."
- "firmware compatibility ranges across the various command revisions not fully enumerated. No `powerable` evidence: source lacks explicit power on/off commands (only `reboot` via POST /reboot)."
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0