Skip to content

Update a host's console-mode config (partial; pushes config_update to the agent).

PATCH
/v1/admin/hosts/{id}/console-config
curl --request PATCH \
--url http://localhost:8080/v1/admin/hosts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/console-config \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "enabled": true, "connector": "example", "output_id": "example", "mode": { "width": 1, "height": 1, "refresh_millihz": 1 }, "compositor": "weston", "audio_output": "example", "stream": true, "stream_audio": true, "input_devices": "auto", "grab": true, "auto_start_on_display": true, "auto_connect_controller": true, "default_app": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "default_user": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "fullscreen": true }'
id
required
string format: uuid
Media typeapplication/json

Per-host console-mode config. On PATCH the body is partial (any subset); on GET it is the resolved object. Off + local-only by default; audio_output has no default (null = quiet).

object
enabled
boolean
connector

‘auto’ or a DRM connector name (DP-4, HDMI-A-1, …).

string
output_id

Card-scoped DRM output id from capabilities.outputs; null selects automatic output.

string | null
mode
One of:
null
compositor
string
Allowed values: weston cage
audio_output

Local host sink id (‘auto’ | alsa hw id | hdmi | motherboard | usb:*), or null = no local audio.

string | null
stream

Also stream over WebRTC (dual-output). Default false = local-only.

boolean
stream_audio
boolean
input_devices
One of:
string
Allowed values: auto
grab
boolean
auto_start_on_display
boolean
auto_connect_controller
boolean
default_app
string | null format: uuid
default_user

CM-06: owner of auto-started console sessions (users.id). Required when auto_start_on_display=true.

string | null format: uuid
fullscreen
boolean

New effective state.

Media typeapplication/json
object
config
required

Per-host console-mode config. On PATCH the body is partial (any subset); on GET it is the resolved object. Off + local-only by default; audio_output has no default (null = quiet).

object
enabled
boolean
connector

‘auto’ or a DRM connector name (DP-4, HDMI-A-1, …).

string
output_id

Card-scoped DRM output id from capabilities.outputs; null selects automatic output.

string | null
mode
One of:
null
compositor
string
Allowed values: weston cage
audio_output

Local host sink id (‘auto’ | alsa hw id | hdmi | motherboard | usb:*), or null = no local audio.

string | null
stream

Also stream over WebRTC (dual-output). Default false = local-only.

boolean
stream_audio
boolean
input_devices
One of:
string
Allowed values: auto
grab
boolean
auto_start_on_display
boolean
auto_connect_controller
boolean
default_app
string | null format: uuid
default_user

CM-06: owner of auto-started console sessions (users.id). Required when auto_start_on_display=true.

string | null format: uuid
fullscreen
boolean
capabilities
required

What the host can do in console mode (from agent-api capacity.console_capabilities). Empty arrays if unreported.

object
connectors
required
Array<string>
outputs

Typed per-card DRM connector and mode inventory. Additive; absent from older agents.

Array<object>
object
id
required

Stable card-scoped output id, e.g. card1:DP-4.

string
card
required
string
render_node
required
string | null
connector
required
string
connected
required
boolean
active_mode
required
One of:
object
name
required
string
width
required
integer
height
required
integer
refresh_millihz
required

Millihertz derived from exact DRM timing totals.

integer
preferred
required
boolean
interlaced
required
boolean
clock_khz
required
integer
htotal
required
integer
vtotal
required
integer
modes
required
Array<object>
object
name
required
string
width
required
integer
height
required
integer
refresh_millihz
required

Millihertz derived from exact DRM timing totals.

integer
preferred
required
boolean
interlaced
required
boolean
clock_khz
required
integer
htotal
required
integer
vtotal
required
integer
audio_sinks
required
Array<object>
object
id
required
string
label
required
string
input_devices
required
Array<object>
object
path
required
string
label
required
string
Example
{
"config": {
"compositor": "weston",
"input_devices": "auto"
}
}

Malformed or invalid request.

Media typeapplication/json
object
error
required
object
code
required

E.g. validation_failed, unauthorized, forbidden, not_found, conflict, session_quota_exceeded, home_in_use, home_not_provisioned, parent_app_disabled, profile_ineligible, profile_not_launchable_for_app, no_host_available, capacity_exhausted, restart_required, rate_limited, internal. Open string, not an enum: new codes are additive and an unknown one falls through to a client’s generic per-status branch.

string
message
required
string
live_sessions

Present on restart_required.

integer
session_id

Steam library discovery Phase 3, ADDITIVE: present on home_in_use when the guard could name the CONFLICTING live session - the one already holding the home. It is here so the client can offer “go to your running session” with a link instead of a dead-end toast. OMITTED rather than empty when the conflict is known but the session is not, so a client branches on presence and never renders a link to nowhere. Load-bearing once derived tiles exist: the lock is held by the PARENT’s home, so a user who clicks a game tile can be refused because a DIFFERENT app (the Steam launcher, or another game from the same install) is running, and without the session id the refusal reads as a bug. See control-api.md §Derived tiles.

string format: uuid
derived_tiles

Steam library discovery Phase 3, ADDITIVE: present on the 409 conflict from DELETE /v1/apps/{id} when the app has derived tiles and ?delete_derived=true was not sent. A LIST, not a count - the point of the confirmation is that the admin sees what they are about to destroy. Capped; an empty array means the tiles could not be listed, never that there are none.

Array<object>
object
id
required
string format: uuid
name
required
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"live_sessions": 1,
"session_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"derived_tiles": [
{
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"name": "example"
}
]
}
}

Missing/invalid/expired/revoked token.

Media typeapplication/json
object
error
required
object
code
required

E.g. validation_failed, unauthorized, forbidden, not_found, conflict, session_quota_exceeded, home_in_use, home_not_provisioned, parent_app_disabled, profile_ineligible, profile_not_launchable_for_app, no_host_available, capacity_exhausted, restart_required, rate_limited, internal. Open string, not an enum: new codes are additive and an unknown one falls through to a client’s generic per-status branch.

string
message
required
string
live_sessions

Present on restart_required.

integer
session_id

Steam library discovery Phase 3, ADDITIVE: present on home_in_use when the guard could name the CONFLICTING live session - the one already holding the home. It is here so the client can offer “go to your running session” with a link instead of a dead-end toast. OMITTED rather than empty when the conflict is known but the session is not, so a client branches on presence and never renders a link to nowhere. Load-bearing once derived tiles exist: the lock is held by the PARENT’s home, so a user who clicks a game tile can be refused because a DIFFERENT app (the Steam launcher, or another game from the same install) is running, and without the session id the refusal reads as a bug. See control-api.md §Derived tiles.

string format: uuid
derived_tiles

Steam library discovery Phase 3, ADDITIVE: present on the 409 conflict from DELETE /v1/apps/{id} when the app has derived tiles and ?delete_derived=true was not sent. A LIST, not a count - the point of the confirmation is that the admin sees what they are about to destroy. Capped; an empty array means the tiles could not be listed, never that there are none.

Array<object>
object
id
required
string format: uuid
name
required
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"live_sessions": 1,
"session_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"derived_tiles": [
{
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"name": "example"
}
]
}
}

Authenticated but insufficient role / not the owner (precedes resource lookup).

Media typeapplication/json
object
error
required
object
code
required

E.g. validation_failed, unauthorized, forbidden, not_found, conflict, session_quota_exceeded, home_in_use, home_not_provisioned, parent_app_disabled, profile_ineligible, profile_not_launchable_for_app, no_host_available, capacity_exhausted, restart_required, rate_limited, internal. Open string, not an enum: new codes are additive and an unknown one falls through to a client’s generic per-status branch.

string
message
required
string
live_sessions

Present on restart_required.

integer
session_id

Steam library discovery Phase 3, ADDITIVE: present on home_in_use when the guard could name the CONFLICTING live session - the one already holding the home. It is here so the client can offer “go to your running session” with a link instead of a dead-end toast. OMITTED rather than empty when the conflict is known but the session is not, so a client branches on presence and never renders a link to nowhere. Load-bearing once derived tiles exist: the lock is held by the PARENT’s home, so a user who clicks a game tile can be refused because a DIFFERENT app (the Steam launcher, or another game from the same install) is running, and without the session id the refusal reads as a bug. See control-api.md §Derived tiles.

string format: uuid
derived_tiles

Steam library discovery Phase 3, ADDITIVE: present on the 409 conflict from DELETE /v1/apps/{id} when the app has derived tiles and ?delete_derived=true was not sent. A LIST, not a count - the point of the confirmation is that the admin sees what they are about to destroy. Capped; an empty array means the tiles could not be listed, never that there are none.

Array<object>
object
id
required
string format: uuid
name
required
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"live_sessions": 1,
"session_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"derived_tiles": [
{
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"name": "example"
}
]
}
}

No such resource.

Media typeapplication/json
object
error
required
object
code
required

E.g. validation_failed, unauthorized, forbidden, not_found, conflict, session_quota_exceeded, home_in_use, home_not_provisioned, parent_app_disabled, profile_ineligible, profile_not_launchable_for_app, no_host_available, capacity_exhausted, restart_required, rate_limited, internal. Open string, not an enum: new codes are additive and an unknown one falls through to a client’s generic per-status branch.

string
message
required
string
live_sessions

Present on restart_required.

integer
session_id

Steam library discovery Phase 3, ADDITIVE: present on home_in_use when the guard could name the CONFLICTING live session - the one already holding the home. It is here so the client can offer “go to your running session” with a link instead of a dead-end toast. OMITTED rather than empty when the conflict is known but the session is not, so a client branches on presence and never renders a link to nowhere. Load-bearing once derived tiles exist: the lock is held by the PARENT’s home, so a user who clicks a game tile can be refused because a DIFFERENT app (the Steam launcher, or another game from the same install) is running, and without the session id the refusal reads as a bug. See control-api.md §Derived tiles.

string format: uuid
derived_tiles

Steam library discovery Phase 3, ADDITIVE: present on the 409 conflict from DELETE /v1/apps/{id} when the app has derived tiles and ?delete_derived=true was not sent. A LIST, not a count - the point of the confirmation is that the admin sees what they are about to destroy. Capped; an empty array means the tiles could not be listed, never that there are none.

Array<object>
object
id
required
string format: uuid
name
required
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"live_sessions": 1,
"session_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"derived_tiles": [
{
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"name": "example"
}
]
}
}