Skip to content

A single host (admin).

GET
/v1/hosts/{id}
curl --request GET \
--url http://localhost:8080/v1/hosts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0 \
--header 'Authorization: Bearer <token>'
id
required
string format: uuid

OK.

Media typeapplication/json
object
id
required
string format: uuid
node_name
required
string
status
required
string
Allowed values: online offline draining
admission_restrictions
required

RH05 active owner-scoped admission holds, always serialized; [] means no hold. This explains draining without exposing owner IDs or implying that an offline host is schedulable. The server derives reason from a bounded code set, never from private host or user data.

Array<object>
object
owner_kind
required
string
Allowed values: manual legacy platform idle_apply recovery reconciliation
reason
required

Stable safe display code; never a free-form host, user or operation identifier.

string
Allowed values: manual_drain legacy_drain platform_apply idle_configuration configuration_recovery journal_reconciliation journal_quarantine
created_at
required
string format: date-time
agent_version
required
string | null
cpu_cores
required
integer | null
mem_mb
required
integer | null
cpu_model
required
string | null
last_registered_at
required
string | null format: date-time
last_heartbeat_at
required
string | null format: date-time
storage
required
Array<object> | null
object
label
required
string
path
required
string
total_mb
required
integer
available_mb
required
integer
capacity_detection
required

Whether the latest hardware capacity report is authoritative and schedulable.

string
Allowed values: ok unavailable failed
capacity_reason
required

Operator-facing reason when capacity detection is unavailable or failed.

string | null
readiness
required
Array<object> | null

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

When the agent last reported readiness (stamped on every real report); null until reported. The readiness gate abstains when this is older than the staleness window.

string | null format: date-time
readiness_gate
required

Amendment 11 (#260). The control plane’s current readiness verdict for this host. ALWAYS SERIALIZED.

object
state
required

OPEN STRING. active, or abstaining (never reported, or the report is stale — nothing is excluded).

string
blocking
required

One entry per check carrying blocks with status fail, INCLUDING overridden ones, so a failing check is never hidden. Populated whatever state is; while abstaining nothing is excluded from admission.

Array<object>
object
check_id
required
string
scope
required
string
gpu_index
required
integer | null
enforced_by
required
string
overridden
required

True = an admin override excludes this check from the verdict.

boolean
readiness_overrides
required

Amendment 11 (#260). Every readiness override stored for this host. ALWAYS SERIALIZED; [] when none.

Array<object>

Amendment 11 (#260). An admin’s decision to launch on a host despite one named failing readiness check.

object
check_id
required
string
created_by
required
string | null format: uuid
created_by_username
required
string | null
created_at
required
string format: date-time
inert
required

True = the host’s current report has no check with this id; the override excludes nothing.

boolean
source_commit
required

The git commit the running agent binary was built from: 7-40 lowercase hex, stored exactly as sent.

string | null
built_at
required

When that agent binary was built.

string | null format: date-time
install_mode
required

How this host got its platform images (CONTEXT.md “Install mode”): registry = pulled published images, source = built on the host, owned (amendment 14, #353) = created and replaced by the machine’s recovery actor. A source host can be TOLD about a platform release but never given one. A client meeting an unrecognized mode shows it as unknown.

string | null
Allowed values: registry source owned
updater_present
required

Whether an updater sits on this host’s stack. NULL IS NOT false: null = no amendment-aware agent has registered, false = an agent looked and found none. On an owned host (amendment 14): whether its recovery actor answered on the agent socket.

boolean | null
recovery_actor_version

Semver (no leading v) of the recovery actor serving this host’s machine. Compared with the installed control plane’s floor (below_floor).

string | null
recovery_actor_source_commit

The git commit that recovery actor was built from: 7-40 lowercase hex, stored exactly as sent. With source_commit, what up_to_date compares on an owned host.

string | null
seed_version

Opaque version of the seed the recovery actor last saw on the machine. Informational; nothing is decided on it (ADR 0007).

string | null
engine

The container engine the host’s agent drives: docker, podman, or another lowercase token a newer agent reports (a client shows an unrecognized value verbatim).

string | null
/^[a-z][a-z0-9-]{0,31}$/
engine_version

The engine’s own product version, opaque; never parsed or ordered.

string | null
/^[!-~]{1,64}$/
engine_mode

Whether that engine runs as root on its host (rootful) or as an ordinary user (rootless). A capability a mode lacks is reported by readiness checks, never inferred from this field.

string | null
Allowed values: rootful rootless
capacity
required

Summed over this host’s REPORTED GPUs. Null - not a zeroed object - when the host has no schedulable GPUs to sum: none reported yet, or capacity_detection is not ok, which is the same condition under which GET /v1/hosts/{id}/gpus returns an empty list. “Nothing to say” and “zero capacity” are different facts and a fleet gauge must not draw the first as the second.

object
slots_total
required

Sum of slots_total over the host’s reported GPUs.

integer
slots_used
required

Sum of slots_reserved: encode slots held by sessions in a reservation-holding state (assigned, starting, running, stopping).

integer
vram_mb_total
required

Sum of vram_mb_total.

integer
vram_mb_used
required

Sum of the LIVE-SAMPLED per-GPU vram_mb_used (the same figure the per-GPU route serves), counting only GPUs that have a sample; 0 when none has. It is deliberately NOT the declared vram_mb_reserved accounting, which #383 removed from admission and which is permanently 0 for every session created since.

integer
active_sessions
required

Sessions in a reservation-holding state on this host’s GPUs.

integer
gpu_count
required

How many reported GPUs the figures above are summed over. Never 0 (the object is null instead).

integer
Example
{
"status": "online",
"admission_restrictions": [
{
"owner_kind": "manual",
"reason": "manual_drain"
}
],
"capacity_detection": "ok",
"install_mode": "registry",
"engine_mode": "rootful"
}

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"
}
}