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, "output_id": "example", "input_devices": "auto", "auto_start_on_display": true, "default_app": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "default_user": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }'
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 by default. AMENDMENT 19 (#453/#455): trimmed to these six fields for direct display; connector, mode, compositor, audio_output, stream, stream_audio, grab, auto_connect_controller and fullscreen are retired. A PATCH naming any other key is 400 validation_failed; a stored key the server does not know is ignored on read.

object
enabled
boolean
output_id

The output pick: a card-scoped DRM output id from capabilities.outputs (card0:DP-4), meaning this card, launch when this connector has a monitor. null = automatic (any connected output). Need not be connected at write time.

string | null
input_devices
One of:
string
Allowed values: auto
auto_start_on_display
boolean
default_app

The app the console session runs. Offered from ConsoleConfigEnvelope.default_apps (runtime_spec.direct_display true); one without the key is accepted and reported by the console_default_app readiness check.

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

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 by default. AMENDMENT 19 (#453/#455): trimmed to these six fields for direct display; connector, mode, compositor, audio_output, stream, stream_audio, grab, auto_connect_controller and fullscreen are retired. A PATCH naming any other key is 400 validation_failed; a stored key the server does not know is ignored on read.

object
enabled
boolean
output_id

The output pick: a card-scoped DRM output id from capabilities.outputs (card0:DP-4), meaning this card, launch when this connector has a monitor. null = automatic (any connected output). Need not be connected at write time.

string | null
input_devices
One of:
string
Allowed values: auto
auto_start_on_display
boolean
default_app

The app the console session runs. Offered from ConsoleConfigEnvelope.default_apps (runtime_spec.direct_display true); one without the key is accepted and reported by the console_default_app readiness check.

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
capabilities
required

What the host can do in console mode (from agent-api capacity.console_capabilities). Empty arrays if unreported. Amendment 19: audio_sinks is no longer served.

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
input_devices
required
Array<object>
object
path
required
string
label
required
string
access

Amendment 18 (RH07 #395): whether the host’s node agent can run console mode, on an owned host where its recovery actor replaces the agent to grant it (agent-api capacity.console_capabilities.access). Absent when the agent reports none.

object
state
required

Off | applying | on | restored | unsupported; an unknown value is shown verbatim and treated as off.

string
target
required
boolean | null
request_id
required
string | null format: uuid
reason
required

A release_state failure identifier; set exactly when state is restored.

string | null
started_at
required
string | null format: date-time
finished_at
required
string | null format: date-time
summary
required
string
default_apps
required

Amendment 19: the enabled apps whose effective runtime_spec (a derived tile’s parent’s) declares direct_display true, ordered by name. The only apps the console page offers as default_app.

Array<object>
object
id
required
string format: uuid
name
required
string
readiness
required

Amendment 19: console readiness checks the control plane evaluates (source operator, never blocks). Today exactly one, console_default_app: skip with no default app, pass when it declares direct_display, fail when it is gone, disabled or does not declare it. While not pass, no console session is auto-started.

Array<object>

One host-readiness check (first-run-experience §S1). The check set is agent-owned - a consumer must pass an unrecognized status through rather than reject it.

object
id
required

Stable machine key, e.g. “nvidia_egl_vendor_json”.

string
observed_at

Amendment 11, optional. When the observation behind this check was made; for a retained host-probe result this is earlier than the report. Absent on an older agent.

string format: date-time
source

Amendment 11, optional, OPEN STRING. Known values: host_probe, local, runtime, operator.

string
blocks

Amendment 11 (#260). Present only on a readiness check that rests on evidence (a host probe or a definitive local observation); declares what the check blocks when, and only when, its status is “fail”. A proxy check never carries it.

object
scope
required

OPEN STRING. Known: host (every launch on the host), homes (launches that mount a managed home), gpu (launches placed on gpu_index). An unrecognized scope never blocks.

string
gpu_index

Only when scope is gpu: the capacity.gpus[].index it names.

integer
enforced_by
required

OPEN STRING. control_plane, or agent (the agent’s own safety state: it refuses those launches itself and no override lifts them).

string
status
required

Known values: “pass”, “fail”, “warn”, “skip”, “provisioning”, “unknown”, “unsupported” (amendment 12 addendum, #311: observed, the hardware does not provide the capability - not a fault, definitive, never blocks; a consumer MUST NOT present it as a fault - agent-api.md readiness) — “skip” means “not applicable to this host” (an NVIDIA check on an AMD box), never “we could not tell”; that is “unknown” (amendment 11: an indeterminate host probe), which never blocks. Only “fail” on a check carrying blocks blocks. DELIBERATELY NOT AN ENUM: the check set (and its status vocabulary) is agent-owned and forward-compatible, so a closed schema type would force every generated client to reject a value the contract requires it to pass through. Consumers MUST render/store an unrecognized value rather than reject it.

string
summary
required

One sentence an operator can act on, in plain language.

string
remediation
required

Exact commands to fix it, distro-aware where cheaply knowable. Empty unless the check asks the operator for something (so: empty for pass, skip and unsupported - nothing to fix - and usually for unknown and provisioning).

string
Example
{
"config": {
"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, host_not_ready, restart_required, stale_revision, unsupported_source, approval_superseded, approval_expired, attempt_conflict, cancel_too_late, retry_exhausted, home_conflict, placement_ineligible, inherited_placement, recovery_uncertain, 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. Also omitted when the holder is the caller’s parked session or released runtime (amendment 39). 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
reason

Amendment 40 (#602), ADDITIVE: a machine-readable cause under code. On 503 no_host_available, home_host_unavailable: the launch is pinned to the host that holds the caller’s home for this app (Amendment 53: or it is pinned to the host of the caller’s Steam home for a sharing launch) and that host is offline or no longer enrolled. Only an admin clears it, so a client does not spend its automatic retry on it. Names no host. Amendment 53 (#1001), on 409 home_in_use: steam_library_open_in_desktop (the holder mounts the Steam library as a shared home) or steam_game_running (the refused launch shares the library and a Steam session holds it); absent when the holder is already stopping. Open string: a client treats an unknown value as absent.

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"
}
],
"reason": "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, host_not_ready, restart_required, stale_revision, unsupported_source, approval_superseded, approval_expired, attempt_conflict, cancel_too_late, retry_exhausted, home_conflict, placement_ineligible, inherited_placement, recovery_uncertain, 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. Also omitted when the holder is the caller’s parked session or released runtime (amendment 39). 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
reason

Amendment 40 (#602), ADDITIVE: a machine-readable cause under code. On 503 no_host_available, home_host_unavailable: the launch is pinned to the host that holds the caller’s home for this app (Amendment 53: or it is pinned to the host of the caller’s Steam home for a sharing launch) and that host is offline or no longer enrolled. Only an admin clears it, so a client does not spend its automatic retry on it. Names no host. Amendment 53 (#1001), on 409 home_in_use: steam_library_open_in_desktop (the holder mounts the Steam library as a shared home) or steam_game_running (the refused launch shares the library and a Steam session holds it); absent when the holder is already stopping. Open string: a client treats an unknown value as absent.

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"
}
],
"reason": "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, host_not_ready, restart_required, stale_revision, unsupported_source, approval_superseded, approval_expired, attempt_conflict, cancel_too_late, retry_exhausted, home_conflict, placement_ineligible, inherited_placement, recovery_uncertain, 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. Also omitted when the holder is the caller’s parked session or released runtime (amendment 39). 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
reason

Amendment 40 (#602), ADDITIVE: a machine-readable cause under code. On 503 no_host_available, home_host_unavailable: the launch is pinned to the host that holds the caller’s home for this app (Amendment 53: or it is pinned to the host of the caller’s Steam home for a sharing launch) and that host is offline or no longer enrolled. Only an admin clears it, so a client does not spend its automatic retry on it. Names no host. Amendment 53 (#1001), on 409 home_in_use: steam_library_open_in_desktop (the holder mounts the Steam library as a shared home) or steam_game_running (the refused launch shares the library and a Steam session holds it); absent when the holder is already stopping. Open string: a client treats an unknown value as absent.

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"
}
],
"reason": "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, host_not_ready, restart_required, stale_revision, unsupported_source, approval_superseded, approval_expired, attempt_conflict, cancel_too_late, retry_exhausted, home_conflict, placement_ineligible, inherited_placement, recovery_uncertain, 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. Also omitted when the holder is the caller’s parked session or released runtime (amendment 39). 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
reason

Amendment 40 (#602), ADDITIVE: a machine-readable cause under code. On 503 no_host_available, home_host_unavailable: the launch is pinned to the host that holds the caller’s home for this app (Amendment 53: or it is pinned to the host of the caller’s Steam home for a sharing launch) and that host is offline or no longer enrolled. Only an admin clears it, so a client does not spend its automatic retry on it. Names no host. Amendment 53 (#1001), on 409 home_in_use: steam_library_open_in_desktop (the holder mounts the Steam library as a shared home) or steam_game_running (the refused launch shares the library and a Steam session holds it); absent when the holder is already stopping. Open string: a client treats an unknown value as absent.

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"
}
],
"reason": "example"
}
}

Conflict (duplicate, in-use, quota, non-swappable, home-in-use, …).

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, host_not_ready, restart_required, stale_revision, unsupported_source, approval_superseded, approval_expired, attempt_conflict, cancel_too_late, retry_exhausted, home_conflict, placement_ineligible, inherited_placement, recovery_uncertain, 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. Also omitted when the holder is the caller’s parked session or released runtime (amendment 39). 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
reason

Amendment 40 (#602), ADDITIVE: a machine-readable cause under code. On 503 no_host_available, home_host_unavailable: the launch is pinned to the host that holds the caller’s home for this app (Amendment 53: or it is pinned to the host of the caller’s Steam home for a sharing launch) and that host is offline or no longer enrolled. Only an admin clears it, so a client does not spend its automatic retry on it. Names no host. Amendment 53 (#1001), on 409 home_in_use: steam_library_open_in_desktop (the holder mounts the Steam library as a shared home) or steam_game_running (the refused launch shares the library and a Steam session holds it); absent when the holder is already stopping. Open string: a client treats an unknown value as absent.

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"
}
],
"reason": "example"
}
}