Get environment
Fetches a VM by ID.
GET
/v1/environments/{vmId}Authorization
AuthorizationBearer token · headerrequired`Authorization: Bearer <token>` — either the static master token
(`ORCH_AUTH_TOKEN`) or a revocable API key issued via
/v1/api-keys (API keys require Postgres; without a database only
the master token is accepted). Master-only surfaces (exec,
attach, API key management) refuse API keys with 403.
**Authentication can be disabled entirely.** When neither
`ORCH_AUTH_TOKEN` nor an API key store (`DATABASE_URL`) is
configured — the default local-development posture — the bearer
middleware becomes a pass-through: every operation this document
marks as secured is reachable with no credentials, requests carry
no principal, and master-only surfaces therefore admit everyone.
Never run that configuration on a reachable network; set
`ORCH_REQUIRE_AUTH=true` to make the orchestrator refuse to start
without a master token.
or
fuse_sessionAPI key · cookierequiredHttpOnly session cookie set by POST /login for browser callers.
Consulted only when no Authorization header is present.
Path parameters
vmIdstringrequiredVM identifier assigned by the orchestrator.
Responses
200Environment.
idstringrequiredFleet-assigned VM identifier (prefix + task_id).
statestringrequiredAllowed:
provisioningrunningdrainingdestroyingtask_idstringrequiredEmpty when the VM is being torn down.
host_idstringScheduler-assigned host ID when placement uses the host registry.
urlstringrequiredhost:port address where the guest agent (fused) is
reachable, via per-VM DNAT. Empty before the VM is running.
specResourceSpecrequiredHardware requirements for a VM.
No lower bound is declared on cpus/ram_mb because the server
does not enforce one: createEnvironment validates only task_id
and the GPU fields, so a spec with `cpus: 0` / `ram_mb: 0` is
accepted and scheduled. Callers should still send positive
values; a strict request validator must not reject zero, or it
will refuse payloads the API accepts.
Show propertiesHide properties
cpusinteger<int32>min 0
ram_mbinteger<int32>min 0
storage_gbinteger<int32>min 0
gpusinteger<int32>Count of GPU devices requested. Zero means no GPU.
With gpu_profile unset, this is whole devices; with
gpu_profile set, this is the count of MIG instances of
that profile (decision D5).
min 0
gpu_kindstringOptional GPU model to match (e.g. "a100"). Empty matches any
kind on a host that has GPUs.
gpu_profilestringOptional MIG profile in mig-parted vocabulary (e.g. "1g.10gb").
When set, gpus counts MIG instances of this profile rather
than whole devices, and the qemu host agent attaches them
via vfio-pci sysfsdev (decision D5).
imagestringOptional named base rootfs for the provider to boot from
(resolved by the host agent against its named-rootfs
directory). Empty means the provider's default base image.
regionstringhost_idstringPins the environment to an exact host id (the Fusefile's
placement.host). A pin is a hard gate, not an override: the
host must still be active, run the right backend, and fit the
request. An unknown host id is rejected with 404 before any VM
is created.
labelsobjectPlacement label selectors (the Fusefile's placement.labels).
Every pair must match the target host's operator-declared
labels. A selector that matches no host is rejected with 503,
never queued.
max_runtime_secondsinteger<int64>Leak-detection ceiling for this task. Zero means "use the
fleet default". The orchestrator tears down tasks that
exceed this age with no state transitions.
idle_timeout_secondsinteger<int64>Destroys the environment once it has gone this long with no
exec and no attach session. Zero means "use the fleet
default", which is no idle expiry unless the operator
configured one. Measured from the last exec or attach, not
from create, and must be at least 60 (idle detection runs on
the reconcile loop). In-guest CPU use and traffic on exposed
ports are not observed.
created_atstring<date-time>requiredupdated_atstring<date-time>requirederrorstringLast failure message, empty on the happy path.
endpointsEndpoint[]Published network endpoints for ports requested via the
create request's `expose` list. Omitted when none.
Show propertiesHide properties
Array of
EndpointasstringCaller-chosen label from the expose request.
urlstringrequiredReachable address, e.g. "http://203.0.113.5:41231".
portintegerrequiredThe guest-side port this endpoint publishes.
healthobjectLast verdict of the environment-level healthcheck. Omitted
when the environment declared no healthcheck, and omitted
until the first verdict has been read back from the guest.
The orchestrator refreshes it on the reconcile tick (30s by
default), so it lags the guest by up to one tick.
Show propertiesHide properties
statestringrequiredThe probe's last verdict. Deliberately separate from
`Environment.state`: an unhealthy environment is still a
running one, and nothing tears it down for a failing probe.
Allowed:
startingpassingfailingsincestring<date-time>When the probe entered this state.
failuresintegerConsecutive failed attempts. Zero while passing.
messagestringThe last attempt's failure detail. Empty while passing.
404Resource does not exist. Note the distinct code
`route_not_found`, returned when the URL matches no registered
route at all (wrong host, port, or path prefix) rather than a
known route with a missing resource.
errorobjectrequiredShow propertiesHide properties
codestringrequiredStable machine-readable code. `route_not_found` (404)
means the URL matches no route this server exposes —
usually a wrong host, port, or path prefix — as opposed
to `not_found`, where the route exists but the resource
does not. `forbidden` is emitted only by CIDR-allowlist
rejections; master-only refusals (exec, attach, API key
management) return 403 with code `unauthorized`.
Allowed:
not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedmessagestringrequiredHuman-readable description.
detailsobjectOptional stable, non-sensitive metadata (e.g. ids,
counts). Omitted when empty.
Request
curl -X GET "http://localhost:8080/v1/environments/string" \
-H "Authorization: Bearer YOUR_TOKEN"const response = await fetch("http://localhost:8080/v1/environments/string", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_TOKEN"
}
});import requests
response = requests.get(
"http://localhost:8080/v1/environments/string",
headers={
"Authorization": "Bearer YOUR_TOKEN"
},
)Response
{
"id": "string",
"state": "provisioning",
"task_id": "string",
"host_id": "string",
"url": "string",
"spec": {
"cpus": 0,
"ram_mb": 0,
"storage_gb": 0,
"gpus": 0,
"gpu_kind": "string",
"gpu_profile": "string",
"image": "string",
"region": "string",
"host_id": "string",
"labels": {},
"max_runtime_seconds": 0,
"idle_timeout_seconds": 0
},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z",
"error": "string",
"endpoints": [
{
"as": "string",
"url": "string",
"port": 0
}
],
"health": {
"state": "starting",
"since": "2024-01-01T00:00:00Z",
"failures": 0,
"message": "string"
}
}{
"error": {
"code": "not_found",
"message": "string",
"details": {}
}
}