Cancel an action waiting for approval
const url = 'http://127.0.0.1:8080/v1/actions/example/cancel';const options = { method: 'POST', headers: {'Deedglass-Version': '2026-10-01', Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://127.0.0.1:8080/v1/actions/example/cancel \ --header 'Authorization: Bearer <token>' \ --header 'Deedglass-Version: 2026-10-01'Only from pending_approval: the action goes cancelled, then sealed, its approval is cancelled and its budget reservation goes back. From any other state the answer is 409 conflict: “This action is already executing, so it can’t be cancelled.” while it runs, and “This action has already finished, so there is nothing to cancel.” once it ended. The agent’s own key (with actions:execute), an admin+ Console session (with the Deedglass-CSRF header) or an org admin key. Another agent’s action is 404 not_found, exactly like an id that doesn’t exist.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The action id (act_…).
Header Parameters
Section titled “Header Parameters”The API version (YYYY-MM-DD). Leave it out to use your org’s pinned version (public routes use the latest). An unknown version is 400 api_version_invalid.
Needed when the request uses a Console session (it changes state); without it the answer is 403 csrf_failed. Not sent with an API key.
1 to 255 printable ASCII characters. A retry with the same key and body returns the stored response with Deedglass-Idempotent-Replayed: true for 24 hours.
Responses
Section titled “Responses”The action, status: cancelled, sealed.
One agent action. Its sections mirror the deed’s. status is the one field an agent needs; state is the exact lifecycle state (docs/GATE.md). The Gate’s own responses (POST /v1/actions and its result report) add execution.result and witness.reasons; lists leave both out.
object
true for a dg_live_ key, false for a dg_test_ key. Recorded, not enforced: connectors have no test mode in v1.
object
executed: the tool ran and the action is sealed, whatever the verdict. failed: the tool certainly didn’t apply the call. authorized: proxy mode, run the tool at the edge now. processing: still executing or witnessing. pending_approval: waiting for a person. denied: a policy, a budget or Stop refused it, and nothing ran. expired and cancelled: it waited for approval and never ran. A sealed action keeps the status of the state it was sealed from.
The action’s undo object (S23). undoes names the action an undo puts back; undone_by names the undo that put this one back; pending an undo waiting for approval or running. eligible is cheap (L2 evidence from a bound transaction, gateway mode, sealed, not undone, within undo.max_age, the row images kept): it only decides whether the Console shows Preview undo. The full answer is always the preview.
object
S40, additive: the window an approved action runs in, stored once at creation and never changed. Absent when the request carried no schedule.
object
The policy decision as an agent reads it: S11’s decision, its source, its message verbatim, the policy version that made it (pinned: a later activation doesn’t change it), and the shadow decision next to it. null until the action is evaluated.
object
The refusal code (policy_denied, budget_exceeded, agent_stopped, tool_unknown, …), approval_required, or null for an allow.
builtin is the Gate’s own decision, such as tool_unknown.
The sentence the agent sees
The policy id (pol_…).
The policy version id (pv_…).
S27, additive: the decision trace’s line about the anomaly facts the policy saw, like anomaly facts: volume_spike, or anomaly facts: detector_stale (…) when detection was behind and the policy treated the agent as anomalous. Absent when no anomaly fact was active.
What the shadow policy would have decided. Recorded, never enforced.
object
object
The approval the action waits for, or waited for. null when no rule asked for one.
object
The approval id (apr_…).
S22, additive: the reason a person gave when they denied it. Absent otherwise.
object
A short, redacted message from the tool or the Gate (at most 1 KiB).
The tool’s result. Only on the Gate’s own responses (POST /v1/actions and POST /v1/actions/{id}/result); never on lists. GET /v1/actions/{id} has it as the top-level result.
The Witness’s verdict about the action (S19): one level, one verdict and the method of that level. A verdict is never stronger than its evidence: VERIFIED needs a clean level at or above required_level; any contradicting evidence is MISMATCH; missing evidence is UNVERIFIABLE. Lists carry the claim only. The Gate’s own responses and GET /v1/actions/{id} add summary, reasons (violations and gaps; passes and notes are in the detail) and witnessed_at; ?expand[]=witness.detail adds detail. An executed action answers 200 whatever the verdict: the tool ran, and the verdict says what that means.
object
The claimed level’s method: reported, edge_reported or response.schema (L0); readback.<connector type>.<read tool>, readback.postgres.row or postcondition.<connector type> (L1); postgres.pgoutput (L2).
The level the policy’s verify: asks for (null on actions recorded before S19).
One sentence a support engineer can read aloud.
One piece of evidence, or one missing piece. The class and the message come from the reason catalog (docs/witness/REASONS.md). The full WitnessReason schema is in openapi.yaml.
object
sha256: of JCS(witness_detail): the deed’s witness.detail_digest.
Witness_detail v1 (S19): what actions.witness_detail holds and what the deed’s witness.detail_digest is the digest of. Changes are additive only; S21 fills levels.L2. The full WitnessDetail schema is in openapi.yaml.
object
GET /v1/actions/{id} only (S21): every witness section sealed about the action, oldest first: the action deed, then any amendment deeds (a later verdict never edits a deed; at most three amendments). An entry a later amendment replaced names the reason it stopped where it did (l2_timeout, …).
object
object
“sha256:” + lowercase hex of SHA-256.
What the caller does next. await_approval: wait for a person (poll_url long-polls the action). execute_at_edge: proxy mode, run the tool at the edge and report the result to report_url before deadline. scheduled (S40): approved, it runs between not_before and not_after. null otherwise.
object
await_approval only: the approval id.
scheduled only (S40): an approved action runs from this time.
scheduled only (S40): past it the action is cancelled and sealed with schedule_missed; nothing runs.
await_approval only.
await_approval only: /v1/actions/{id}?wait=25.
execute_at_edge only: /v1/actions/{id}/result.
execute_at_edge only: after it, the action is sealed UNVERIFIABLE (edge_lost).
Example
{ "object": "action", "id": "act_01j9zt3a5c7e9g1j3m5p7r9t1v", "created_at": "2026-10-02T10:14:03.401Z", "livemode": true, "agent": { "id": "agt_01j9z9b1d3f5h7k9m1p3r5t7v9", "name": "support-bot" }, "tool": "postgres.execute", "connector": null, "mode": "gateway", "state": "sealed", "status": "executed", "on_behalf_of": "u_4821", "session": "chat_77", "decision": { "outcome": "allow", "code": null, "source": "rule", "rule_id": "allow-order-updates", "reason": "Order updates are allowed.", "message": null, "policy": null, "policy_version": null, "shadow": null }, "policy": { "id": null, "version_id": null, "mode": "enforce", "decision": "allow", "rule_id": "allow-order-updates" }, "approval": null, "execution": { "status": "succeeded", "started_at": "2026-10-02T10:14:03.455Z", "finished_at": "2026-10-02T10:14:03.496Z", "latency_ms": 41, "error_code": null, "error_message": null }, "witness": { "object": "witness", "level": "L2", "verdict": "MISMATCH", "method": "postgres.pgoutput", "required_level": "L0", "detail_digest": "sha256:c3e1a07e5d1c9b20c3e1a07e5d1c9b20c3e1a07e5d1c9b20c3e1a07e5d1c9b20" }, "cost": null, "request_digest": "sha256:9c1e5b7d0a2f4c6e8b0d2f4a6c8e0b2d4f6a8c0e2b4d6f8a0c2e4b6d8f0a2c4e", "result_digest": null, "payload_pruned_at": null, "deed": "deed_01j9zt3q5s7v9w1y3a5c7e9g1j", "next_action": null}Headers
Section titled “Headers”This request’s id. Quote it to support; it matches error.request_id.
The API version this response follows.
not_found: no such action in this org, or (for an agent key) another agent’s.
object
object
One or more calm sentences with the next step.
The request field, query parameter or header the error is about.
On policy_invalid only. Each problem with its line, code and hint.
One finding about a policy file, with its position and the next step. Codes are stable and listed in docs/POLICY_ERRORS.md. In the policy_invalid error envelope each diagnostic also carries object: policy_diagnostic. The full PolicyDiagnostic schema is in openapi.yaml.
object
One agent action. Its sections mirror the deed’s. status is the one field an agent needs; state is the exact lifecycle state (docs/GATE.md). The Gate’s own responses (POST /v1/actions and its result report) add execution.result and witness.reasons; lists leave both out. The full Action schema is in openapi.yaml.
object
On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).
One of the twelve safety checks (S23 §3.3). Available means no check failed. The full UndoCheck schema is in openapi.yaml.
object
Example
{ "error": { "type": "invalid_request_error", "code": "not_found", "message": "There's no endpoint at GET /v1/helth. Did you mean /v1/health?", "param": null, "request_id": "req_01j9zr3m5k8q2w7x4t6v0b1c9d", "doc_url": "https://docs.deedglass.com/errors/not_found" }}Headers
Section titled “Headers”This request’s id. Quote it to support; it matches error.request_id.
conflict: the action isn’t waiting for approval.
object
object
One or more calm sentences with the next step.
The request field, query parameter or header the error is about.
On policy_invalid only. Each problem with its line, code and hint.
One finding about a policy file, with its position and the next step. Codes are stable and listed in docs/POLICY_ERRORS.md. In the policy_invalid error envelope each diagnostic also carries object: policy_diagnostic. The full PolicyDiagnostic schema is in openapi.yaml.
object
One agent action. Its sections mirror the deed’s. status is the one field an agent needs; state is the exact lifecycle state (docs/GATE.md). The Gate’s own responses (POST /v1/actions and its result report) add execution.result and witness.reasons; lists leave both out. The full Action schema is in openapi.yaml.
object
On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).
One of the twelve safety checks (S23 §3.3). Available means no check failed. The full UndoCheck schema is in openapi.yaml.
object
Example
{ "error": { "type": "invalid_request_error", "code": "conflict", "message": "This action is already executing, so it can't be cancelled.", "param": null, "request_id": "req_01k6w4a3d5f7h9k1n3q5s7v9x1", "doc_url": "https://docs.deedglass.com/errors/conflict" }}Headers
Section titled “Headers”This request’s id. Quote it to support; it matches error.request_id.
default
Section titled “default”An error. Every error has this envelope; doc_url explains the code.
object
object
One or more calm sentences with the next step.
The request field, query parameter or header the error is about.
On policy_invalid only. Each problem with its line, code and hint.
One finding about a policy file, with its position and the next step. Codes are stable and listed in docs/POLICY_ERRORS.md. In the policy_invalid error envelope each diagnostic also carries object: policy_diagnostic. The full PolicyDiagnostic schema is in openapi.yaml.
object
One agent action. Its sections mirror the deed’s. status is the one field an agent needs; state is the exact lifecycle state (docs/GATE.md). The Gate’s own responses (POST /v1/actions and its result report) add execution.result and witness.reasons; lists leave both out. The full Action schema is in openapi.yaml.
object
On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).
One of the twelve safety checks (S23 §3.3). Available means no check failed. The full UndoCheck schema is in openapi.yaml.
object
Example
{ "error": { "type": "invalid_request_error", "code": "not_found", "message": "There's no endpoint at GET /v1/helth. Did you mean /v1/health?", "param": null, "request_id": "req_01j9zr3m5k8q2w7x4t6v0b1c9d", "doc_url": "https://docs.deedglass.com/errors/not_found" }}Headers
Section titled “Headers”This request’s id. Quote it to support; it matches error.request_id.
The API version this response follows.