Summary
The BluOS C 700 is a network-connected audio player running the BluOS operating system. This spec covers the BluOS Custom Integration API (version 1.7), which exposes HTTP GET/POST endpoints for volume control, playback control, play queue management, content browsing, player grouping, and direct input selection. All commands are sent to http://<player_ip>:<port>/<request>; port 11000 is used for all BluOS players except the CI580. Responses are UTF-8 encoded XML.
Transport
protocols:
- http
addressing:
port: 11000
base_url: "http://<player_ip>:11000"
# Note: CI580 uses ports 11000/11010/11020/11030 for its four nodes.
# Port should be confirmed via MDNS (services musc.tcp / musp.tcp) or LSDP discovery.
auth:
type: none # inferred: no auth procedure in source
Traits
- levelable # inferred from volume set/up/down/mute commands in section 3
- queryable # inferred from /Status, /SyncStatus, /Volume query endpoints
- powerable # inferred from /reboot command in section 9 (soft reboot only; power on/off not documented)
- routable # inferred from direct input selection commands in section 11
Actions
# --- Volume Control (section 3) ---
- id: set_volume
label: Set Volume
kind: action
params:
- name: level
type: integer
description: Absolute volume level 0–100
- name: tell_slaves
type: integer
description: "0 = only this player; 1 = all players in group"
required: false
http:
method: GET
path: /Volume
query_params: "level={level}&tell_slaves={tell_slaves}"
- id: set_volume_db
label: Set Volume (dB)
kind: action
params:
- name: abs_db
type: number
description: Absolute volume in dB (within configured range, typically -80..0)
- name: tell_slaves
type: integer
description: "0 = only this player; 1 = all players in group"
required: false
http:
method: GET
path: /Volume
query_params: "abs_db={abs_db}&tell_slaves={tell_slaves}"
- id: adjust_volume_db
label: Adjust Volume (relative dB)
kind: action
params:
- name: db
type: number
description: Relative dB change; positive = up, negative = down (typical ±2 dB)
- name: tell_slaves
type: integer
description: "0 = only this player; 1 = all players in group"
required: false
http:
method: GET
path: /Volume
query_params: "db={db}&tell_slaves={tell_slaves}"
- id: mute_on
label: Mute
kind: action
params: []
http:
method: GET
path: /Volume
query_params: "mute=1"
- id: mute_off
label: Unmute
kind: action
params: []
http:
method: GET
path: /Volume
query_params: "mute=0"
# --- Playback Control (section 4) ---
- id: play
label: Play
kind: action
params: []
http:
method: GET
path: /Play
- id: play_seek
label: Play with Seek
kind: action
params:
- name: seek
type: integer
description: Position in seconds within the current track (only valid when /Status includes <totlen>)
- name: id
type: integer
description: Track id in the queue (optional)
required: false
http:
method: GET
path: /Play
query_params: "seek={seek}&id={id}"
- id: play_url
label: Play Stream URL
kind: action
params:
- name: url
type: string
description: URL-encoded stream URL to play
http:
method: GET
path: /Play
query_params: "url={url}"
- id: pause
label: Pause
kind: action
params: []
http:
method: GET
path: /Pause
- id: pause_toggle
label: Pause Toggle
kind: action
params: []
http:
method: GET
path: /Pause
query_params: "toggle=1"
- id: stop
label: Stop
kind: action
params: []
http:
method: GET
path: /Stop
- id: skip
label: Skip to Next Track
kind: action
params: []
http:
method: GET
path: /Skip
- id: back
label: Back (Previous Track / Restart)
kind: action
params: []
http:
method: GET
path: /Back
- id: set_shuffle
label: Set Shuffle
kind: action
params:
- name: state
type: integer
description: "0 = shuffle off; 1 = shuffle on"
http:
method: GET
path: /Shuffle
query_params: "state={state}"
- id: set_repeat
label: Set Repeat
kind: action
params:
- name: state
type: integer
description: "0 = repeat queue; 1 = repeat track; 2 = repeat off"
http:
method: GET
path: /Repeat
query_params: "state={state}"
# --- Play Queue Management (section 5) ---
- id: get_playlist
label: List Play Queue
kind: action
params:
- name: start
type: integer
description: First track index (0-based) to include
required: false
- name: end
type: integer
description: Last track index to include
required: false
http:
method: GET
path: /Playlist
- id: delete_track
label: Delete Track from Queue
kind: action
params:
- name: id
type: integer
description: Track position id to delete
http:
method: GET
path: /Delete
query_params: "id={id}"
- id: move_track
label: Move Track in Queue
kind: action
params:
- name: old
type: integer
description: Current position of the track
- name: new
type: integer
description: Destination position
http:
method: GET
path: /Move
query_params: "new={new}&old={old}"
- id: clear_queue
label: Clear Play Queue
kind: action
params: []
http:
method: GET
path: /Clear
- id: save_queue
label: Save Play Queue
kind: action
params:
- name: name
type: string
description: Name for the saved playlist (URL-encoded)
http:
method: GET
path: /Save
query_params: "name={name}"
# --- Presets (section 6) ---
- id: list_presets
label: List Presets
kind: action
params: []
http:
method: GET
path: /Presets
- id: load_preset
label: Load Preset
kind: action
params:
- name: id
type: string
description: "Preset id number, +1 for next preset, or -1 for previous preset"
http:
method: GET
path: /Preset
query_params: "id={id}"
# --- Content Browsing (section 7) ---
- id: browse
label: Browse Music Content
kind: action
params:
- name: key
type: string
description: Browse key (URL-encoded). Omit for top-level browse.
required: false
- name: withContextMenuItems
type: integer
description: Set to 1 to include inline context menus
required: false
http:
method: GET
path: /Browse
- id: search
label: Search Music Content
kind: action
params:
- name: key
type: string
description: Search key from a prior /Browse searchKey attribute (URL-encoded)
- name: q
type: string
description: Search text
http:
method: GET
path: /Browse
query_params: "key={key}&q={q}"
# --- Player Grouping (section 8) ---
- id: add_slave
label: Group Player (Add Secondary)
kind: action
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
required: false
http:
method: GET
path: /AddSlave
query_params: "slave={slave}&port={port}&group={group}"
- id: add_slaves
label: Group Multiple Players
kind: action
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
http:
method: GET
path: /AddSlave
query_params: "slaves={slaves}&ports={ports}"
- id: remove_slave
label: Ungroup Player (Remove Secondary)
kind: action
params:
- name: slave
type: string
description: IP address of the secondary player to remove
- name: port
type: integer
description: Port of the secondary player
http:
method: GET
path: /RemoveSlave
query_params: "slave={slave}&port={port}"
- id: remove_slaves
label: Ungroup Multiple Players
kind: action
params:
- name: slaves
type: string
description: Comma-separated IP addresses of secondary players to remove
- name: ports
type: string
description: Comma-separated port numbers
http:
method: GET
path: /RemoveSlave
query_params: "slaves={slaves}&ports={ports}"
# --- Reboot (section 9) ---
- id: reboot
label: Soft Reboot Player
kind: action
params: []
http:
method: POST
path: /reboot
body: "yes=1"
# --- Doorbell Chime (section 10) ---
- id: doorbell_chime
label: Play Doorbell Chime
kind: action
params: []
http:
method: GET
path: /Doorbell
query_params: "play=1"
# --- Direct Input Selection (section 11) ---
- id: play_input_active
label: Select Active Input (via URL)
kind: action
params:
- name: url
type: string
description: URL-encoded input URL from /RadioBrowse?service=Capture response
http:
method: GET
path: /Play
query_params: "url={url}"
- id: play_input_index
label: Select External Input by Index (firmware < v4.2.0)
kind: action
params:
- name: inputIndex
type: integer
description: 1-based index of inputs from /Settings?id=capture response (Bluetooth excluded)
http:
method: GET
path: /Play
query_params: "inputIndex={inputIndex}"
notes: "Only valid for BluOS firmware newer than v3.8.0 and older than v4.2.0"
- id: play_input_type_index
label: Select External Input by Type and Index (firmware >= v4.2.0)
kind: action
params:
- name: inputTypeIndex
type: string
description: "Format: {type}-{index}. Types: spdif, analog, coax, bluetooth, arc, earc, phono, computer, aesebu, balanced, microphone. Index starts at 1."
http:
method: GET
path: /Play
query_params: "inputTypeIndex={inputTypeIndex}"
notes: "Only valid for BluOS firmware v4.2.0 or newer"
# --- Bluetooth Mode (section 12) ---
- id: set_bluetooth_mode
label: Set Bluetooth Mode
kind: action
params:
- name: bluetoothAutoplay
type: integer
description: "0 = Manual, 1 = Automatic, 2 = Guest, 3 = Disabled"
http:
method: GET
path: /audiomodes
query_params: "bluetoothAutoplay={bluetoothAutoplay}"
Feedbacks
# /Status (section 2.1) — long-pollable
- id: playback_status
label: Playback Status
type: object
endpoint: GET /Status
long_poll_params:
timeout: integer # seconds; recommended 100s, never faster than 10s
etag: string # from previous response root attribute
key_fields:
- name: state
type: enum
values: [play, pause, stop, stream, connecting]
- name: volume
type: integer
description: Player volume 0–100; -1 means fixed volume
- name: db
type: number
description: Volume level in dB
- name: mute
type: integer
values: [0, 1]
- name: muteVolume
type: integer
description: Unmuted volume 0–100 when muted
- name: muteDb
type: number
description: Unmuted volume in dB when muted
- name: shuffle
type: integer
values: [0, 1]
- name: repeat
type: integer
values: [0, 1, 2]
description: "0 = repeat queue, 1 = repeat track, 2 = off"
- name: title1
type: string
- name: title2
type: string
- name: title3
type: string
- name: artist
type: string
- name: album
type: string
- name: name
type: string
- name: secs
type: integer
description: Seconds played; not included in etag (must be incremented by client)
- name: totlen
type: integer
description: Total track length in seconds
- name: syncStat
type: string
description: Changes when /SyncStatus changes; use to detect need for /SyncStatus poll
- name: pid
type: integer
description: Unique play queue id
- name: prid
type: integer
description: Unique preset id
# /SyncStatus (section 2.2) — long-pollable
- id: sync_status
label: Player and Group Sync Status
type: object
endpoint: GET /SyncStatus
long_poll_params:
timeout: integer # recommended 180s
etag: string
key_fields:
- name: volume
type: integer
description: Volume 0–100; -1 = fixed
- name: db
type: number
- name: mute
type: integer
values: [0, 1]
- name: muteVolume
type: integer
- name: muteDb
type: number
- name: name
type: string
description: Player name
- name: modelName
type: string
- name: model
type: string
- name: brand
type: string
- name: group
type: string
- name: id
type: string
description: Player IP and port
- name: mac
type: string
- name: initialized
type: boolean
# /Volume (section 3.1) — also returns current state on query
- id: volume_state
label: Volume State
type: object
endpoint: GET /Volume
key_fields:
- name: volume
type: integer
description: Current volume 0–100; -1 = fixed
- name: db
type: number
- name: mute
type: integer
values: [0, 1]
- name: muteDb
type: number
- name: muteVolume
type: integer
Variables
# Volume range is configurable via the BluOS Controller app (Settings -> Player -> Audio).
# The available volume range is typically -80..0 dB but is not directly settable via the API.
# UNRESOLVED: no API endpoint for reading or setting the configured volume range bounds.
Events
# BluOS supports long-polling on /Status and /SyncStatus as a push-like mechanism.
# The device does not send unsolicited events; all state changes are discovered via long-polling.
# etag values in responses change only when content changes, minimizing unnecessary processing.
# UNRESOLVED: no unsolicited event/webhook mechanism documented in the source.
Macros
# UNRESOLVED: no multi-step macro sequences explicitly described in the source.
# Note: external input selection requires a two-step sequence:
# 1. GET /RadioBrowse?service=Capture (discover input URLs)
# 2. GET /Play?url={url} (activate selected input)
# Or for firmware v4.2.0+: GET /Play?inputTypeIndex={type}-{index} (single step)
Safety
confirmation_required_for:
- reboot # POST /reboot causes a soft reboot; no confirmation prompt in the API itself
interlocks: []
# UNRESOLVED: no power-on sequencing requirements, electrical interlocks, or
# explicit safety warnings found in the source beyond standard network cautions.
Notes
- Base URL: All requests use
http://<player_ip>:11000/<endpoint>. The document useshttp://192.168.1.100:11000as a reference example. - Port discovery: Use mDNS (services
musc.tcp/musp.tcp) or the LSDP protocol (UDP broadcast on port 11430) to discover the correct port. Do not hardcode 11000 without confirming via discovery, especially for multi-node devices like the CI580. - XML responses: All responses are UTF-8 encoded XML. Attributes and elements not listed in this spec may be present and should be ignored per the source documentation.
- Long polling: Clients should not poll /Status or /SyncStatus faster than once every 30 seconds without long polling. With long polling, do not make two consecutive requests for the same resource less than 1 second apart. Recommended /Status timeout is 100 s; /SyncStatus is 180 s.
- Grouped players: Secondary players proxy most requests to the primary player. Use /SyncStatus with long polling to track per-player volume in a group.
secsfield: Thesecselement in /Status is excluded from the etag calculation and will not trigger a long-poll return. Clients must increment the displayed playback position themselves.streamUrlflag: Presence of<streamUrl>in /Status indicates queue-based controls (shuffle, repeat, skip, back) are not relevant.- Firmware-specific input selection: The
/Play?inputIndex=form applies only to firmware v3.8.0–v4.2.0; the/Play?inputTypeIndex=form applies to v4.2.0+. Verify firmware version before using these commands. - Reboot: Uses HTTP POST (
curl -d yes=1 <ip>/reboot), not GET. - Doorbell chime: Response includes chime volume and audio file path; chime assets are stored on the device.
- Image redirects: Image URLs starting with
/Artworkmay redirect. AddingfollowRedirects=1as a query parameter avoids the redirect. - API version covered: BluOS Custom Integration API v1.7 (2025-04-09).
Provenance
source_domains:
- bluos.io
source_urls:
- https://bluos.io/wp-content/uploads/2025/06/BluOS-Custom-Integration-API_v1.7.pdf
retrieved_at: 2026-05-16T20:18:50.703Z
last_checked_at: 2026-06-02T21:54:13.434Z
Verification Summary
verdict: verified
checked_at: 2026-06-02T21:54:13.434Z
matched_actions: 34
action_count: 34
confidence: medium
summary: "All 34 spec actions traced to BluOS volume control API. Complete volume management including individual and grouped player control confirmed. (8 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "the source document is the generic BluOS Custom Integration API and covers many product models (Bluesound, NAD, DALI, etc.); it is not specific to the C 700. C 700-specific input types, hardware capabilities, and firmware compatibility range are not stated."
- "no API endpoint for reading or setting the configured volume range bounds."
- "no unsolicited event/webhook mechanism documented in the source."
- "no multi-step macro sequences explicitly described in the source."
- "no power-on sequencing requirements, electrical interlocks, or"
- "C 700-specific hardware capabilities (supported inputs, output configuration, amplifier class, etc.) are not stated in the source API document. The API is generic across all BluOS players."
- "authentication and HTTPS/TLS support not addressed in source."
- "error response format for HTTP-level errors (4xx/5xx) not documented in source; only XML <error> root element is described for browse errors."
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0