Resolve a build layer
Returns the newest ready artifact for one build layer cache key, scoped to the caller’s tenant. The tenant is taken from the credentials the request authenticated with and cannot be named in the request: an artifact is only ever served back to whoever built it.
A cold cache is a 200 with found: false, not a 404. A client
walks its layer chain deepest-first, one key per call, and stops
at the first hit, so misses are the ordinary path here.
GET
/v1/snapshots/resolveAuthorization
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
layer_keystringrequiredDerived cache key of the setup step.
archstringrequiredArchitecture the artifact must have been built on. Required,
never defaulted: an artifact is a rootfs image and a rootfs
does not travel across architectures, so a guess here would
hand back bytes the caller cannot boot.
Allowed:
amd64arm64Responses
200The resolved artifact, or a miss.
foundbooleanrequiredFalse on a cold cache; snapshot is then absent.
snapshotSnapshotShow propertiesHide properties
idstringrequiredvm_idstringrequiredtask_idstringtenant_idstringparent_snapshot_idstringmodestringNormally "manual" or "auto". Not an enum: the server stores
the caller-supplied `mode` verbatim (only an empty value is
defaulted to "manual"), so an arbitrary string can appear
here. Treat unknown values as opaque rather than rejecting
the response.
statestringAllowed:
creatingreadyrestoringdeletingerrorcommentstringlayer_keystringDerived cache key of the setup step this artifact
materializes. Absent on any snapshot that is not a build
layer.
archstringArchitecture of the host that built the artifact, not of
whoever asked for it. An ext4 rootfs does not travel across
architectures, so this is what says whether these bytes are
bootable for you.
Allowed:
amd64arm64digeststringHex sha256 of the artifact rootfs, for verifying a transfer
of these exact bytes. It is not an identity two artifacts
can share: rebuilding the same recipe produces different
bytes, so nothing is looked up by digest. Absent when the
host agent does not hash.
kindstringWhat this artifact actually contains. "disk" is the rootfs
and nothing else, so restoring it cold-boots the guest;
"live" additionally carries the vCPU state and the whole
guest memory, so restoring it resumes the guest where it
stopped.
This is what the host agent reports it wrote, never what
the caller requested: a `live: true` create served by an
agent that could only take a disk snapshot reads back as
"disk". Branch on this rather than on your own request.
Always present, on every read path. Records written before
live snapshots existed read back as "disk".
default: "disk"
Allowed:
disklivesize_bytesinteger<int64>created_atstring<date-time>requiredupdated_atstring<date-time>retention_untilstring<date-time> | nullWhen the snapshot becomes eligible for garbage collection;
null/absent when it is kept until deleted.
last_errorstringexport_refstringexportsSnapshotExport[]Show propertiesHide properties
Array of
SnapshotExportdestinationstringrequiredstatusstringNormally "pending", "ready", or "error". Not an enum: the
create handler stores the caller-supplied `export_status`
verbatim (only an empty value is defaulted to "pending"), so
an arbitrary string can appear here. Treat unknown values as
opaque rather than rejecting the response.
requested_atstring<date-time>updated_atstring<date-time>last_errorstring400layer_key or arch missing.
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.
500Unexpected server error.
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/snapshots/resolve?layer_key=string&arch=amd64" \
-H "Authorization: Bearer YOUR_TOKEN"const response = await fetch("http://localhost:8080/v1/snapshots/resolve?layer_key=string&arch=amd64", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_TOKEN"
}
});import requests
response = requests.get(
"http://localhost:8080/v1/snapshots/resolve?layer_key=string&arch=amd64",
headers={
"Authorization": "Bearer YOUR_TOKEN"
},
)Response
{
"found": true,
"snapshot": {
"id": "string",
"vm_id": "string",
"task_id": "string",
"tenant_id": "string",
"parent_snapshot_id": "string",
"mode": "manual",
"state": "creating",
"comment": "string",
"layer_key": "string",
"arch": "amd64",
"digest": "string",
"kind": "disk",
"size_bytes": 0,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z",
"retention_until": "2024-01-01T00:00:00Z",
"last_error": "string",
"export_ref": "string",
"exports": [
{
"destination": "string",
"status": "pending",
"requested_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z",
"last_error": "string"
}
]
}
}{
"error": {
"code": "not_found",
"message": "string",
"details": {}
}
}{
"error": {
"code": "not_found",
"message": "string",
"details": {}
}
}