Get intervention
Reads one intervention. With wait, long-polls until it is
settled or the wait passes, and always answers 200 with the state
at that moment. Settled means terminal and, for an approved gated
action, also performed with result set; so a caller loops until
state is not pending and, for an approved gate, result is
present. A pending intervention past its deadline is expired on
read, applying its on_timeout. Requires hitl:read. An
intervention on an environment the caller’s key does not cover is
404, the same as one that does not exist.
GET
/v1/interventions/{interventionId}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. An expired
key is refused with 401 like an unknown one.
A key minted with `scopes` reaches only the hitl routes
(`/v1/interventions`, `/v1/hitl/*`, and POST /v1/api-keys to mint
a narrower key). Any other route is 403 code `forbidden`, reason
`env_scope`, except an `/v1/environments/{vmId}` route for an
environment the key does not cover, which is 404 so the key
cannot probe which environments exist.
**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
interventionIdstringrequiredQuery parameters
waitstringSeconds, or a duration like `30s`. Capped at 50s.
Header parameters
Fuse-ActorstringThe person behind this request, as an opaque id (`user_42`,
`alice@corp.com`, `slack:U0123`). Fuse records it on hitl
interventions and the audit log and never checks it. Accepted on
every authenticated route; it matters wherever an actor is
recorded (raising, deciding, minting). At most 128 bytes, no
control characters; a malformed value is 400.
How the recorded actor is resolved:
- key pinned to an actor: that actor (`source: pinned`). A
different `Fuse-Actor` is 403 `forbidden`, reason
`actor_mismatch`.
- key with `hitl:act-as`: the header value (`source: asserted`,
with the asserting key's id), else `key:<key_id>`.
- any other key: `key:<key_id>` named after the key's label
(`source: key`). Sending the header is 403 `forbidden`, reason
`actor_not_allowed`, rather than silently dropped.
- master token: the header value (`source: asserted`), else
`master` (`source: key`).
An asserted actor is only as true as the key holder's own auth.
max length 128
Fuse-Actor-NamestringOptional display name for `Fuse-Actor`, at most 256 bytes. Sending
it without `Fuse-Actor` is 400.
max length 256
Responses
200The intervention.
idstringrequiredenv_idstringrequiredkindstringrequiredAllowed:
asksecrettakeoverreviewexeclifecyclecomputerstallexpirygatestringThe gate that raised it. Empty for a request.
modestringThe gate's mode. Notify and deny records are born terminal.
Allowed:
asknotifydenystatestringrequiredAllowed:
pendingapprovedrejectedexpiredcancelledpayloadobjectrequiredWhat was asked or attempted: `question` for an ask, `secret`,
`takeover` or `review` for those requests, `exec`, `lifecycle`
or `computer` for a gate, `signal` for a stall or expiry.
`decider` is set when a gate's decider sent the action on to
a human.
Show propertiesHide properties
questionstringchoicesstring[]execExecPayloadA held exec.
Show propertiesHide properties
argvstring[]requiredshellstringThe script when the caller sent `shell`; argv is then the sh -lc that runs it.
timeout_msinteger<int64>lifecycleLifecyclePayloadA held environment action.
Show propertiesHide properties
actionstringrequiredAllowed:
destroyforkmigratedrainsnapshotrotate-tokensecretInterventionSecretA secret request. It never holds the value.
Show propertiesHide properties
targetstringrequiredThe declared target's `env` name or `file` path.
labelstringrequiredThe target's label from the policy. Show it first: the agent
writes `message`, so `message` alone could claim to be
anything.
messagestringThe agent's own text.
takeoverInterventionTakeoverA takeover. `holder` and `started_at` are set while a human holds
the environment, which is also when the agent's exec and computer
calls get 423. The intervention stays `pending` until release.
Show propertiesHide properties
viastringrequiredAllowed:
terminaldesktopreasonstringholderActorShow propertiesHide properties
idstringrequiredA pinned or asserted actor id, `key:<key_id>`, `master`,
`system` for fuse itself, or `decider:<gate>`.
namestringsourcestringrequired`pinned`: fixed on the key at mint time. `asserted`: named in
`Fuse-Actor` by a `hitl:act-as` key or the master token, and only
as true as that caller's own auth. `key`: derived from the
credential. `system`: expiry and cancellation. `decider`: a
gate's decider allowed or denied the action; the id is
`decider:<gate>`.
Allowed:
pinnedassertedkeysystemdeciderkey_idstringThe key that authenticated the request, including the key that
asserted an actor. Omitted for the master token.
started_atstring<date-time>signalInterventionSignalWhat fuse saw when it raised a stall or expiry. A stall carries
`failures` and `last_exit_code`, or `quiet_seconds`. An expiry
carries `reaper` and `reap_at`, and once approved
`extended_until`.
Show propertiesHide properties
failuresintegerThe run of consecutive non-zero exec exits.
last_exit_codeintegerThe exit code that completed the run.
quiet_secondsinteger<int64>How long the agent had made no exec or computer call.
reaperstringWhat will tear the environment down.
Allowed:
idle_timeoutmax_runtimereap_atstring<date-time>When. The expiry's own deadline is capped at this, with a 10s floor.
extended_untilstring<date-time>Set on approval. The reapers leave the environment alone until then.
computerComputerPayloadA held computer action. On approval the orchestrator replays
`input` to the guest, with the approver's `edited_text` in place
of `text` when there is one.
Show propertiesHide properties
actionstringrequiredThe computer action name.
textstringThe text of a `type` (or the keys of a `key`), as sent.
inputobjectrequiredThe whole action body as the caller sent it (a ComputerActionRequest).
reviewInterventionReviewA review request. When `path` is set, `content` is that file as
fuse read it at request time, so the human reviews what the
agent submitted even if the file changed afterwards.
Show propertiesHide properties
pathstringcontentstringrequiredformatstringrequiredAllowed:
textdiffmessagestringThe agent's note to the reviewer.
truncatedbooleanSet when the file was longer than 1 MiB and was cut off.
deciderInterventionDeciderWhat a gate's decider said about an action it sent on to a
human: `verdict` `ask` with its `reason`, or the `error` that
made fuse fall through to a human.
Show propertiesHide properties
verdictstringrequiredAllowed:
askreasonstringerrorstringSet when the decider call failed.
triggered_byActorrequiredShow propertiesHide properties
idstringrequiredA pinned or asserted actor id, `key:<key_id>`, `master`,
`system` for fuse itself, or `decider:<gate>`.
namestringsourcestringrequired`pinned`: fixed on the key at mint time. `asserted`: named in
`Fuse-Actor` by a `hitl:act-as` key or the master token, and only
as true as that caller's own auth. `key`: derived from the
credential. `system`: expiry and cancellation. `decider`: a
gate's decider allowed or denied the action; the id is
`decider:<gate>`.
Allowed:
pinnedassertedkeysystemdeciderkey_idstringThe key that authenticated the request, including the key that
asserted an actor. Omitted for the master token.
deadlinestring<date-time>requiredon_timeoutstringrequiredAllowed:
rejectallowdecisionobjectPresent once terminal. An expired intervention carries the
on_timeout outcome and a cancelled one a reject, both decided
by "system".
Show propertiesHide properties
outcomestringrequiredAllowed:
approverejectanswerstringreasonstringdecided_byActorrequiredShow propertiesHide properties
idstringrequiredA pinned or asserted actor id, `key:<key_id>`, `master`,
`system` for fuse itself, or `decider:<gate>`.
namestringsourcestringrequired`pinned`: fixed on the key at mint time. `asserted`: named in
`Fuse-Actor` by a `hitl:act-as` key or the master token, and only
as true as that caller's own auth. `key`: derived from the
credential. `system`: expiry and cancellation. `decider`: a
gate's decider allowed or denied the action; the id is
`decider:<gate>`.
Allowed:
pinnedassertedkeysystemdeciderkey_idstringThe key that authenticated the request, including the key that
asserted an actor. Omitted for the master token.
decided_atstring<date-time>requirededited_argvstring[]The argv the approver replaced a held exec's with.
edited_textstringThe text the approver replaced a held `type` action's with.
grantstringHow far an approval of a gated action reaches.
resultInterventionResultWhat performing an approved gated action produced.
Show propertiesHide properties
execExecEnvironmentResponseThe outcome of a guest command.
A non-zero `exit_code` arrives with **HTTP 200**: the command
ran and failed, which is a successful answer to the question the
caller asked. It is not an error and must not be raised by an
SDK. HTTP errors mean the command could not be run at all.
`stdout` and `stderr` are kept apart, and are plain strings
rather than base64 — exec output is overwhelmingly text, and
encoding it would make every caller pay a decoding tax for the
rare binary case.
Show propertiesHide properties
exit_codeintegerrequiredThe guest command's own exit status. Non-zero is a normal
result, delivered with HTTP 200.
stdoutstringrequiredstderrstringrequiredcomputerComputerActionResponseThe guest's answer to one action.
Show propertiesHide properties
outputstringTextual output, e.g. the pointer location for `cursor_position`.
screenshotstringBase64 PNG of the display after the action settled. Present on
every action that implies one; for `zoom` it is the cropped
region at full resolution.
env_idstringThe environment a fork or migrate produced.
snapshot_idstringThe snapshot a snapshot action produced.
errorstringSet when the approved action could not be performed. A
non-zero exec exit code is a result in `exec`, not an error.
finished_atstring<date-time>requiredcreated_atstring<date-time>requiredupdated_atstring<date-time>required400Malformed request.
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 by CIDR-allowlist
rejections and by hitl access checks, which set
`details.reason` (see the Forbidden response);
master-only refusals (exec, attach, listing and revoking
API keys) return 403 with code `unauthorized`.
Allowed:
not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlockedmessagestringrequiredHuman-readable description.
detailsobjectOptional stable, non-sensitive metadata (e.g. ids,
counts). Omitted when empty. A 403 `forbidden` from a
hitl access check carries `reason` (`missing_scope`,
`env_scope`, `self_approval`, `actor_required`,
`actor_mismatch`, `actor_not_allowed`,
`mint_escalation`, `hitl_denied`), plus `scope` for
`missing_scope`, and `gate` and `intervention_id` for
`hitl_denied`. A 423 `locked` carries `intervention_id`
and `kind` (`takeover` or `stall`).
403The caller authenticated, but may not make this request.
Master-only surfaces (exec, attach, listing and revoking API keys)
refuse API keys; those 403 bodies carry code `unauthorized`. CIDR
allowlist rejections return 403 with code `forbidden` and no
reason. Access checks on the hitl routes and scoped keys return
403 with code `forbidden` and `details.reason` set to one of:
- `missing_scope`: the key lacks the scope the route needs
(`details.scope` names it). Full-access keys never hold
`hitl:decide`, `hitl:secret`, `hitl:takeover` or `hitl:act-as`.
- `env_scope`: a scoped key called a route outside the hitl
routes.
- `self_approval`: the key or actor that raised an intervention
tried to decide it.
- `actor_required`: the environment sets `require_actor` and the
decision names no pinned or asserted actor.
- `actor_mismatch`: `Fuse-Actor` differs from the key's pinned
actor.
- `actor_not_allowed`: `Fuse-Actor` sent by a key without
`hitl:act-as`.
- `hitl_denied`: a hitl gate in `deny` mode, or a gate's decider,
refused an exec, lifecycle or computer action, or an edit
matched a `deny` gate. `details.gate` names the gate and
`details.intervention_id` the terminal record; the message is
the gate's `reason`.
- `mint_escalation`: a scoped key tried to mint a key wider than
itself.
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 by CIDR-allowlist
rejections and by hitl access checks, which set
`details.reason` (see the Forbidden response);
master-only refusals (exec, attach, listing and revoking
API keys) return 403 with code `unauthorized`.
Allowed:
not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlockedmessagestringrequiredHuman-readable description.
detailsobjectOptional stable, non-sensitive metadata (e.g. ids,
counts). Omitted when empty. A 403 `forbidden` from a
hitl access check carries `reason` (`missing_scope`,
`env_scope`, `self_approval`, `actor_required`,
`actor_mismatch`, `actor_not_allowed`,
`mint_escalation`, `hitl_denied`), plus `scope` for
`missing_scope`, and `gate` and `intervention_id` for
`hitl_denied`. A 423 `locked` carries `intervention_id`
and `kind` (`takeover` or `stall`).
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 by CIDR-allowlist
rejections and by hitl access checks, which set
`details.reason` (see the Forbidden response);
master-only refusals (exec, attach, listing and revoking
API keys) return 403 with code `unauthorized`.
Allowed:
not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlockedmessagestringrequiredHuman-readable description.
detailsobjectOptional stable, non-sensitive metadata (e.g. ids,
counts). Omitted when empty. A 403 `forbidden` from a
hitl access check carries `reason` (`missing_scope`,
`env_scope`, `self_approval`, `actor_required`,
`actor_mismatch`, `actor_not_allowed`,
`mint_escalation`, `hitl_denied`), plus `scope` for
`missing_scope`, and `gate` and `intervention_id` for
`hitl_denied`. A 423 `locked` carries `intervention_id`
and `kind` (`takeover` or `stall`).
Request
curl -X GET "http://localhost:8080/v1/interventions/string" \
-H "Authorization: Bearer YOUR_TOKEN"const response = await fetch("http://localhost:8080/v1/interventions/string", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_TOKEN"
}
});import requests
response = requests.get(
"http://localhost:8080/v1/interventions/string",
headers={
"Authorization": "Bearer YOUR_TOKEN"
},
)Response
{
"id": "string",
"env_id": "string",
"kind": "ask",
"gate": "string",
"mode": "ask",
"state": "pending",
"payload": {
"question": "string",
"choices": [
"string"
],
"exec": {
"argv": [
"string"
],
"shell": "string",
"timeout_ms": 0
},
"lifecycle": {
"action": "destroy"
},
"secret": {
"target": "string",
"label": "string",
"message": "string"
},
"takeover": {
"via": "terminal",
"reason": "string",
"holder": {
"id": "string",
"name": "string",
"source": "pinned",
"key_id": "string"
},
"started_at": "2024-01-01T00:00:00Z"
},
"signal": {
"failures": 0,
"last_exit_code": 0,
"quiet_seconds": 0,
"reaper": "idle_timeout",
"reap_at": "2024-01-01T00:00:00Z",
"extended_until": "2024-01-01T00:00:00Z"
},
"computer": {
"action": "string",
"text": "string",
"input": {}
},
"review": {
"path": "string",
"content": "string",
"format": "text",
"message": "string",
"truncated": true
},
"decider": {
"verdict": "ask",
"reason": "string",
"error": "string"
}
},
"triggered_by": {
"id": "string",
"name": "string",
"source": "pinned",
"key_id": "string"
},
"deadline": "2024-01-01T00:00:00Z",
"on_timeout": "reject",
"decision": {
"outcome": "approve",
"answer": "string",
"reason": "string",
"decided_by": {
"id": "string",
"name": "string",
"source": "pinned",
"key_id": "string"
},
"decided_at": "2024-01-01T00:00:00Z",
"edited_argv": [
"string"
],
"edited_text": "string",
"grant": "string"
},
"result": {
"exec": {
"exit_code": 0,
"stdout": "hi\n",
"stderr": ""
},
"computer": {
"output": "string",
"screenshot": "string"
},
"env_id": "string",
"snapshot_id": "string",
"error": "string",
"finished_at": "2024-01-01T00:00:00Z"
},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}{
"error": {
"code": "not_found",
"message": "string",
"details": {}
}
}{
"error": {
"code": "not_found",
"message": "string",
"details": {}
}
}{
"error": {
"code": "not_found",
"message": "string",
"details": {}
}
}