Summary
Denon HEOS network-connected multi-room music system, controlled via the HEOS Command Line Interface (CLI) over a telnet (TCP) connection. Commands are ASCII text strings in heos://command_group/command?attribute=value format; responses are JSON. Covers system, player, group, and browse commands plus unsolicited change events.
Transport
protocols:
- tcp
addressing:
port: 1255
auth:
type: none # inferred: no login/password required for the CLI connection; optional HEOS account sign-in exists for streaming services
Notes on transport (from source):
- Telnet connection to port 1255 on the HEOS product's IP address.
- Device discovery via UPnP SSDP; M-SEARCH search target (ST):
urn:schemas-denon-com:device:ACT-Denon:1. IP can also be set statically. - Command string delimiter:
\r\n. JSON command response delimiter:\r\n. - Max 32 simultaneous socket connections per speaker. Recommended: connect to one speaker only; multiple connections to that speaker are allowed (e.g. one for events, one for user actions).
Traits
# - powerable: no power on/off command in source (reboot only) - not claimed
- levelable # inferred: player and group volume set/up/down commands present
- queryable # inferred: extensive get_* query commands present
- routable # inferred: play_input / play_stream / play_preset source-selection commands present
Actions
# All commands verbatim from source. Parameterized parts shown as {param}.
# Base format: heos://command_group/command?attribute1=value1&attribute2=value2
# Special characters in attribute values URL-encoded: & = %26, = = %3D, % = %25
# ===== System commands =====
- id: register_for_change_events
label: Register for Change Events
kind: action
command: "heos://system/register_for_change_events?enable={enable}"
params:
- name: enable
type: enum
description: "Register or unregister for unsolicited change events (on, off)"
- id: check_account
label: HEOS Account Check
kind: query
command: "heos://system/check_account"
params: []
- id: sign_in
label: HEOS Account Sign In
kind: action
command: "heos://system/sign_in?un={username}&pw={password}"
params:
- name: un
type: string
description: HEOS account username
- name: pw
type: string
description: HEOS account password
- id: sign_out
label: HEOS Account Sign Out
kind: action
command: "heos://system/sign_out"
params: []
- id: heart_beat
label: HEOS System Heart Beat
kind: query
command: "heos://system/heart_beat"
params: []
- id: reboot
label: HEOS Speaker Reboot
kind: action
command: "heos://system/reboot"
params: []
# Reboots only the HEOS device the controller is connected to via CLI port.
- id: prettify_json_response
label: Prettify JSON Response
kind: action
command: "heos://system/prettify_json_response?enable={enable}"
params:
- name: enable
type: enum
description: "Enable or disable prettification of JSON response (on, off)"
# ===== Player commands =====
- id: get_players
label: Get Players
kind: query
command: "heos://player/get_players"
params: []
- id: get_player_info
label: Get Player Info
kind: query
command: "heos://player/get_player_info?pid={pid}"
params:
- name: pid
type: string
description: Player id returned by get_players or get_groups
- id: get_play_state
label: Get Play State
kind: query
command: "heos://player/get_play_state?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: set_play_state
label: Set Play State
kind: action
command: "heos://player/set_play_state?pid={pid}&state={state}"
params:
- name: pid
type: string
description: Player id
- name: state
type: enum
description: "Play state (play, pause, stop)"
- id: get_now_playing_media
label: Get Now Playing Media
kind: query
command: "heos://player/get_now_playing_media?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: get_volume
label: Get Volume
kind: query
command: "heos://player/get_volume?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: set_volume
label: Set Volume
kind: action
command: "heos://player/set_volume?pid={pid}&level={level}"
params:
- name: pid
type: string
description: Player id
- name: level
type: integer
description: "Volume level, 0 to 100"
- id: volume_up
label: Volume Up
kind: action
command: "heos://player/volume_up?pid={pid}&step={step}"
params:
- name: pid
type: string
description: Player id
- name: step
type: integer
description: "Step level 1 to 10 (default 5)"
- id: volume_down
label: Volume Down
kind: action
command: "heos://player/volume_down?pid={pid}&step={step}"
params:
- name: pid
type: string
description: Player id
- name: step
type: integer
description: "Step level 1 to 10 (default 5)"
- id: get_mute
label: Get Mute
kind: query
command: "heos://player/get_mute?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: set_mute
label: Set Mute
kind: action
command: "heos://player/set_mute?pid={pid}&state={state}"
params:
- name: pid
type: string
description: Player id
- name: state
type: enum
description: "Mute state (on, off)"
- id: toggle_mute
label: Toggle Mute
kind: action
command: "heos://player/toggle_mute?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: get_play_mode
label: Get Play Mode
kind: query
command: "heos://player/get_play_mode?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: set_play_mode
label: Set Play Mode
kind: action
command: "heos://player/set_play_mode?pid={pid}&repeat={repeat}&shuffle={shuffle}"
params:
- name: pid
type: string
description: Player id
- name: repeat
type: enum
description: "Repeat state (on_all, on_one, off)"
- name: shuffle
type: enum
description: "Shuffle state (on, off)"
- id: get_queue
label: Get Queue
kind: query
command: "heos://player/get_queue?pid={pid}&range={range}"
params:
- name: pid
type: string
description: Player id
- name: range
type: string
description: "Optional 'start#, end#' record index; omit for all records (max 100 per response); range starts from 0"
- id: play_queue
label: Play Queue Item
kind: action
command: "heos://player/play_queue?pid={pid}&qid={qid}"
params:
- name: pid
type: string
description: Player id
- name: qid
type: string
description: Queue id returned by get_queue
- id: remove_from_queue
label: Remove Item(s) from Queue
kind: action
command: "heos://player/remove_from_queue?pid={pid}&qid={qid_list}"
params:
- name: pid
type: string
description: Player id
- name: qid_list
type: string
description: Comma-separated list of queue ids from get_queue
- id: save_queue
label: Save Queue as Playlist
kind: action
command: "heos://player/save_queue?pid={pid}&name={name}"
params:
- name: pid
type: string
description: Player id
- name: name
type: string
description: New playlist name, limited to 128 unicode characters
- id: clear_queue
label: Clear Queue
kind: action
command: "heos://player/clear_queue?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: play_next
label: Play Next
kind: action
command: "heos://player/play_next?pid={pid}"
params:
- name: pid
type: string
description: Player id
- id: play_previous
label: Play Previous
kind: action
command: "heos://player/play_previous?pid={pid}"
params:
- name: pid
type: string
description: Player id
# ===== Group commands =====
- id: get_groups
label: Get Groups
kind: query
command: "heos://group/get_groups"
params: []
- id: get_group_info
label: Get Group Info
kind: query
command: "heos://group/get_group_info?gid={gid}"
params:
- name: gid
type: string
description: Group id returned by get_groups
- id: set_group
label: Set Group (Create / Modify / Ungroup)
kind: action
command: "heos://group/set_group?pid={pid_list}"
params:
- name: pid_list
type: string
description: Comma-separated player ids; first id is group leader. Create: heos://group/set_group?pid=3,1,4. Modify members: pid=3,1,5. Ungroup all: pid=3 (leader only)
- id: get_group_volume
label: Get Group Volume
kind: query
command: "heos://group/get_volume?gid={gid}"
params:
- name: gid
type: string
description: Group id
- id: set_group_volume
label: Set Group Volume
kind: action
command: "heos://group/set_volume?gid={gid}&level={level}"
params:
- name: gid
type: string
description: Group id
- name: level
type: integer
description: "Group volume level, 0 to 100"
- id: group_volume_up
label: Group Volume Up
kind: action
command: "heos://group/volume_up?gid={gid}&step={step}"
params:
- name: gid
type: string
description: Group id
- name: step
type: integer
description: "Step level 1 to 10 (default 5)"
- id: group_volume_down
label: Group Volume Down
kind: action
command: "heos://group/volume_down?gid={gid}&step={step}"
params:
- name: gid
type: string
description: Group id
- name: step
type: integer
description: "Step level 1 to 10 (default 5)"
- id: get_group_mute
label: Get Group Mute
kind: query
command: "heos://group/get_mute?gid={gid}"
params:
- name: gid
type: string
description: Group id
- id: set_group_mute
label: Set Group Mute
kind: action
command: "heos://group/set_mute?gid={gid}&state={state}"
params:
- name: gid
type: string
description: Group id
- name: state
type: enum
description: "Mute state (on, off)"
- id: toggle_group_mute
label: Toggle Group Mute
kind: action
command: "heos://group/toggle_mute?gid={gid}"
params:
- name: gid
type: string
description: Group id
# ===== Browse commands =====
- id: get_music_sources
label: Get Music Sources
kind: query
command: "heos://browse/get_music_sources"
params: []
- id: get_source_info
label: Get Source Info
kind: query
command: "heos://browse/get_source_info?sid={sid}"
params:
- name: sid
type: string
description: Source id returned by get_music_sources (or by browse for heos_server / heos_service types)
- id: browse_source
label: Browse Source
kind: query
command: "heos://browse/browse?sid={sid}"
params:
- name: sid
type: string
description: Source id returned by get_music_sources or browse
- id: browse_source_containers
label: Browse Source Containers
kind: query
command: "heos://browse/browse?sid={sid}&cid={cid}&range={range}"
params:
- name: sid
type: string
description: Source id
- name: cid
type: string
description: Container id returned by browse or search
- name: range
type: string
description: "Optional 'start#, end#'; omit for all records (max 50 or 100 per response depending on service); range starts from 0"
- id: get_search_criteria
label: Get Source Search Criteria
kind: query
command: "heos://browse/get_search_criteria?sid={sid}"
params:
- name: sid
type: string
description: Source id
- id: search
label: Search
kind: query
command: "heos://browse/search?sid={sid}&search={search_string}&scid={scid}&range={range}"
params:
- name: sid
type: string
description: Source id
- name: search_string
type: string
description: Search string limited to 128 unicode characters; may contain '*' wildcard if supported by scid
- name: scid
type: enum
description: "Search criteria id from get_search_criteria (artist, album, song, station)"
- name: range
type: string
description: "Optional 'start#, end#'"
- id: play_stream
label: Play Station (Play Stream)
kind: action
command: "heos://browse/play_stream?pid={pid}&sid={sid}&cid={cid}&mid={mid}&name={name}"
params:
- name: pid
type: string
description: Player id
- name: sid
type: string
description: Source id
- name: cid
type: string
description: Container id; ignore if no container (e.g. station from Search)
- name: mid
type: string
description: Media id from browse or search; must be 'station' media type
- name: name
type: string
description: Station name returned by browse
- id: play_preset
label: Play Preset Station
kind: action
command: "heos://browse/play_preset?pid={pid}&preset={preset}"
params:
- name: pid
type: string
description: Player id
- name: preset
type: integer
description: Station offset in HEOS Favorites, 1 and above
- id: play_input
label: Play Input Source
kind: action
command: "heos://browse/play_input?pid={pid}&spid={spid}&input={input}"
params:
- name: pid
type: string
description: Destination player id
- name: spid
type: string
description: "Optional source player id (playing input on another speaker); omit for same speaker"
- name: input
type: enum
description: "Input source name, e.g. inputs/aux_in_1, inputs/line_in_1..4, inputs/coax_in_1..2, inputs/optical_in_1..2, inputs/hdmi_in_1, inputs/hdmi_arc_1, inputs/cable_sat, inputs/dvd, inputs/bluray, inputs/game, inputs/mediaplayer, inputs/cd, inputs/tuner, inputs/hdradio, inputs/tvaudio, inputs/phono"
- id: add_to_queue_container
label: Add Container to Queue with Options
kind: action
command: "heos://browse/add_to_queue?pid={pid}&sid={sid}&cid={cid}&aid={aid}"
params:
- name: pid
type: string
description: Player id
- name: sid
type: string
description: Source id
- name: cid
type: string
description: Container id from browse or search; must be a 'playable' container type
- name: aid
type: enum
description: "Add criteria id (1 play now, 2 play next, 3 add to end, 4 replace and play)"
- id: add_to_queue_track
label: Add Track to Queue with Options
kind: action
command: "heos://browse/add_to_queue?pid={pid}&sid={sid}&cid={cid}&mid={mid}&aid={aid}"
params:
- name: pid
type: string
description: Player id
- name: sid
type: string
description: Source id
- name: cid
type: string
description: Container id used to browse/search current container
- name: mid
type: string
description: Media id from browse or search; must be 'track' media type
- name: aid
type: enum
description: "Add criteria id (1 play now, 2 play next, 3 add to end, 4 replace and play)"
- id: rename_playlist
label: Rename HEOS Playlist
kind: action
command: "heos://browse/rename_playlist?sid={sid}&cid={cid}&name={name}"
params:
- name: sid
type: string
description: Source id (select HEOS source)
- name: cid
type: string
description: Container id from Get HEOS Playlists
- name: name
type: string
description: New playlist name limited to 128 unicode characters
- id: delete_playlist
label: Delete HEOS Playlist
kind: action
command: "heos://browse/delete_playlist?sid={sid}&cid={cid}"
params:
- name: sid
type: string
description: Source id (select HEOS source)
- name: cid
type: string
description: Container id from Get HEOS Playlists
- id: retrieve_metadata
label: Retrieve Album Metadata
kind: query
command: "heos://browse/retrieve_metadata?sid={sid}&cid={cid}"
params:
- name: sid
type: string
description: Source id (Rhapsody/Napster)
- name: cid
type: string
description: Rhapsody/Napster album id from browse or get_now_playing_media
- id: get_service_options
label: Get Service Options for Now Playing Screen (OBSOLETE)
kind: query
command: "heos://browse/get_service_options?sid={sid}"
params:
- name: sid
type: string
description: Source id
# Source marks this OBSOLETE - get_now_playing_media now includes supported options.
- id: set_service_option
label: Set Service Option
kind: action
command: "heos://browse/set_service_option?sid={sid}&option={option}&mid={mid}&cid={cid}&name={name}&pid={pid}&scid={scid}&range={range}"
params:
- name: sid
type: string
description: Source id (not used by all options)
- name: option
type: enum
description: "Option id (1 Add Track to Library, 2 Add Album to Library, 3 Add Station to Library, 4 Add Playlist to Library, 5 Remove Track from Library, 6 Remove Album from Library, 7 Remove Station from Library, 8 Remove Playlist from Library, 11 Thumbs Up, 12 Thumbs Down, 13 Create New Station, 19 Add station to HEOS Favorites, 20 Remove from HEOS Favorites)"
- name: mid
type: string
description: Media id (options 1, 3, 5, 7, 12, 20)
- name: cid
type: string
description: Container id (options 2, 4, 6, 8, 19)
- name: name
type: string
description: Playlist name (option 4) or search string (option 13)
- name: pid
type: string
description: Player id (options 11, 12, 19 on now-playing screen)
- name: scid
type: enum
description: "Station-create criteria (option 13): 1 Artist, 3 Track, 5 Show"
- name: range
type: string
description: Optional range query for option 13
# Get HEOS Playlists (4.4.12) and Get HEOS History (4.4.15) have no dedicated
# commands in the source - they refer to Browse Source / Browse Source Containers.
Feedbacks
- id: play_state
type: enum
values: [play, pause, stop]
via: "get_play_state response message: pid='player_id'&state='play_state'"
- id: volume_level
type: integer
values: "0 to 100"
via: "get_volume / get_group_volume response message: level='vol_level'"
- id: mute_state
type: enum
values: [on, off]
via: "get_mute / get_group_mute response message: state='on_or_off'"
- id: play_mode
type: object
via: "get_play_mode response message: repeat=on_all_or_on_one_or_off & shuffle=on_or_off"
- id: now_playing_media
type: object
via: "get_now_playing_media payload (song, album, artist, image_url, mid, qid, sid, type song/station)"
- id: queue
type: list
via: "get_queue payload (song, album, artist, image_url, qid, mid, album_id per item)"
- id: players_list
type: list
via: "get_players payload (name, pid, gid, model, version, network wired/wifi, lineout, control)"
- id: groups_list
type: list
via: "get_groups payload (name, gid, players with pid and role leader/member)"
- id: account_status
type: enum
values: [signed_in, signed_out]
via: "check_account response message: 'signed_out' or 'signed_in&un=<current user name>'"
- id: music_sources
type: list
via: "get_music_sources payload (name, image_url, type music_service/heos_service/heos_server/dlna_server, sid)"
- id: search_criteria
type: list
via: "get_search_criteria payload (name, scid, wildcard, playable, cid)"
Variables
# No separate variable mechanism in source - all settable state is via Actions
# (set_volume, set_mute, set_play_state, set_play_mode, set_group_*).
Events
# Unsolicited JSON responses, received only after register_for_change_events?enable=on
- id: sources_changed
payload: '{ "heos": { "command": "event/sources_changed" } }'
- id: players_changed
payload: '{ "heos": { "command": "event/players_changed" } }'
- id: groups_changed
payload: '{ "heos": { "command": "event/groups_changed" } }'
- id: source_data_changed
payload: '{ "heos": { "command": "event/source_data_changed", "message": "sid=''source_id''" } }'
- id: player_state_changed
payload: '{ "heos": { "command": "event/player_state_changed", "message": "pid=''player_id''&state=''play_state''" } }'
- id: player_now_playing_changed
payload: '{ "heos": { "command": "event/player_now_playing_changed", "message": "pid=''player_id''" } }'
- id: player_now_playing_progress
payload: '{ "heos": { "command": "event/player_now_playing_progress", "message": "pid=player_id&cur_pos=position_ms&duration=duration_ms" } }'
- id: player_playback_error
payload: '{ "heos": { "command": "event/player_playback_error", "message": "pid=player_id&error=Could Not Download" } }'
# Error string represents error type; displayable directly to user.
- id: player_queue_changed
payload: '{ "heos": { "command": "event/player_queue_changed", "message": "pid=''player_id''" } }'
- id: player_volume_changed
payload: '{ "heos": { "command": "event/player_volume_changed", "message": "pid=''player_id''&level=''vol_level''" } }'
- id: player_mute_changed
payload: '{ "heos": { "command": "event/player_mute_changed", "message": "pid=''player_id''&state=''on_or_off''" } }'
- id: repeat_mode_changed
payload: '{ "heos": { "command": "event/repeat_mode_changed", "message": "pid=''player_id''&repeat=''on_all_or_on_one_or_off''" } }'
- id: shuffle_mode_changed
payload: '{ "heos": { "command": "event/shuffle_mode_changed", "message": "pid=''player_id''&shuffle=''on_or_off''" } }'
- id: group_changed
payload: '{ "heos": { "command": "event/group_changed", "message": "gid=''group_id''" } }'
- id: group_volume_changed
payload: '{ "heos": { "command": "event/group_volume_changed", "message": "gid=''group_id''&level=''vol_level''" } }'
- id: group_mute_changed
payload: '{ "heos": { "command": "event/group_mute_changed", "message": "gid=''group_id''&state=''on_or_off''" } }'
- id: user_changed
payload: '{ "heos": { "command": "event/user_changed", "message": "signed_out or signed_in&un=<current user name>" } }'
Macros
- id: driver_initialization
label: Driver Initialization Sequence
steps:
- "Un-register for change events (system/register_for_change_events?enable=off)"
- "Sign in to HEOS account if credentials available (system/sign_in)"
- "Retrieve ecosystem status (get_players, get_sources, get_groups, get_queue, get_now_playing_media, get_volume, get_play_state)"
- "Register for change events (system/register_for_change_events?enable=on)"
Safety
confirmation_required_for: []
interlocks: []
# UNRESOLVED: source contains no safety warnings, interlock procedures, or
# power-on sequencing requirements. reboot command exists but carries no
# documented safety constraints.
Notes
- Source document is the generic "HEOS CLI Protocol Specification" for the Denon HEOS multi-room system; it does not name the N 12Dab model explicitly. Input metadata declared RS-232C, but the source documents only telnet/TCP control on port 1255 — no serial transport, baud rate, or wiring appears anywhere in the source.
- CLI module runs dormant until first socket connection; expect initial event spew and delayed player discovery before pids resolve.
- Controllers should connect to a single speaker and control the whole network through it; up to 32 simultaneous sockets per speaker; keep an idle connection to avoid dormancy re-entry.
- Keep-alive via
system/heart_beat. - Changes made in the HEOS app (e.g. added/removed music services) do not reflect via CLI until re sign-in; expose sign-out/sign-in in controller UI.
- Custom argument
SEQUENCE=<number>allowed in browse commands to correlate command/response. - When response cannot be populated immediately (browse/search on remote servers), a
command under processinterim response is sent. - External input distribution limited to one player or one group; cannot play an external input already selected elsewhere, and self-playing external input cannot be distributed.
- Obsolete commands:
browse/get_service_options(use get_now_playing_media options) andplay_streamvariant requiringsid(useplay_input). - URL-encoding required for
&,=,%in attribute values (%26,%3D,%25); decoded strings needed for GUI display. - Error responses:
"result": "fail"withmessagecontainingeid=<error_id>&text=<error text>; error codes 1–17 defined (unrecognized command, invalid ID, wrong argument count, data unavailable, resource unavailable, invalid credentials, command not executed, not logged in, out of range, user not found, internal error, system error, processing previous command, cannot play, option not supported, queue overflow, skip limit).
Provenance
source_domains:
- assets.denon.com
source_urls:
- https://assets.denon.com/documentmaster/us/heos_cli_protocol_specification_290616.pdf
retrieved_at: 2026-08-14T22:13:04.207Z
last_checked_at: 2026-08-19T09:12:54.829Z
Verification Summary
verdict: verified
checked_at: 2026-08-19T09:12:54.829Z
matched_actions: 54
action_count: 54
confidence: medium
summary: "All 54 spec actions match literal heos:// command strings in the HEOS CLI source, transport port 1255 confirmed, no fabricated or drifted actions. (6 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "source is the generic \"HEOS CLI Protocol Specification\" and does not mention the N 12Dab model by name; model assignment comes from operator-provided input metadata. Input metadata declared protocol RS-232C, but the source document only documents telnet/TCP control — no serial config appears anywhere in the source. Firmware compatibility, error-recovery sequences, and protocol version not stated."
- "source contains no safety warnings, interlock procedures, or"
- "firmware version compatibility not stated in source"
- "protocol version number not stated in source"
- "input validity per specific HEOS device type stated only generically (\"depends on the type of source HEOS device\")"
- "exact source-id (sid) assignments per music service not enumerated in source"
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0