List environments
Lists tracked environments. Filters are optional exact matches, combined with AND.
GET
/v1/environmentsAuthorization
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.
Query parameters
task_idstringReturn only the environment assigned to this task ID.
statestringReturn only environments in this lifecycle state.
Allowed:
provisioningrunningdrainingdestroyinghost_idstringReturn only environments assigned to this host.
Responses
200Environment list.
environmentsEnvironment[]requiredShow propertiesHide properties
Array of
EnvironmentidstringrequiredFleet-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.
huge_pagesbooleanBack guest memory with 2M pages. The host must have that much
memory reserved as hugepages, or the create answers 409. Fixed
for the life of the environment, and required for a lazy
migrate.
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".
protocolstringThe transport this endpoint was actually published on, which is
not always what was requested: a host agent too old to know about
the field publishes tcp and omits this. Read it rather than
assuming the request was honoured.
Allowed:
tcpudpportintegerrequiredThe 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.
egressobjectThe resolved outbound policy. Always present on a server that
knows about egress: an environment created without asking
reports `direct`, so a caller can tell "not proxied" from "this
server predates the field".
Show propertiesHide properties
modestringrequiredAllowed:
directproxyproviderstringThe backend serving this environment. Proxy only.
protocolstringProxy only.
Allowed:
socks5httpendpointstringThe proxy url the workload was handed, e.g.
`socks5h://10.200.3.1:1080`. A host-local address useless to
anyone not already inside the sandbox, and never a credential.
Proxy only.
healthobjectThe endpoint's last probe verdict. Proxy only, and `unknown`
until the reconcile tick (30s by default) has probed it once.
An unhealthy proxy reports and nothing acts on it: the
environment keeps running with no egress, never with direct
egress.
Show propertiesHide properties
statestringrequiredAllowed:
unknownhealthyunhealthyreasonstringThe backend-level failure, e.g. `dial tcp 10.200.3.1:1080:
connection refused`. Empty while healthy. Never a destination
hostname or anything drawn from the sandbox's traffic.
checked_atstring<date-time>Request
curl -X GET "http://localhost:8080/v1/environments" \
-H "Authorization: Bearer YOUR_TOKEN"const response = await fetch("http://localhost:8080/v1/environments", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_TOKEN"
}
});import requests
response = requests.get(
"http://localhost:8080/v1/environments",
headers={
"Authorization": "Bearer YOUR_TOKEN"
},
)Response
{
"environments": [
{
"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": {},
"huge_pages": true,
"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",
"protocol": "tcp",
"port": 0
}
],
"health": {
"state": "starting",
"since": "2024-01-01T00:00:00Z",
"failures": 0,
"message": "string"
},
"egress": {
"mode": "direct",
"provider": "string",
"protocol": "socks5",
"endpoint": "string",
"health": {
"state": "unknown",
"reason": "string",
"checked_at": "2024-01-01T00:00:00Z"
}
}
}
]
}