Skip to content

Send an action through the Gate

POST
/v1/actions
curl --request POST \
--url http://127.0.0.1:8080/v1/actions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Deedglass-Version: 2026-10-01' \
--data '{ "tool": "fake.echo", "args": { "message": "hello" }, "mode": "gateway", "wait": 10, "context": { "client": { "name": "deedglass-cli", "version": "0.1.0" }, "transport": "rest" } }'

Every tool call an agent makes passes through here (docs/GATE.md). The Gate checks the signed intent (when the agent’s intent mode asks for one), reads the agent’s Stop state, asks the active policy, and then refuses the action, waits for a person, runs the tool (gateway mode) or authorizes the edge to run it (proxy mode). Every action it records ends as a sealed deed. status is the one field an agent needs: executed (200: the tool ran and the action is sealed, whatever the verdict), failed (200: the tool certainly didn’t apply the call), authorized (200, proxy mode: run the tool at the edge now, then report it to next_action.report_url), processing (202: still running when wait ended; poll GET /v1/actions/{id}?wait=25) and pending_approval (202: waiting for a person; next_action.poll_url waits for the decision). A refusal is an error envelope that carries the sealed action in error.action: policy_denied and policy_unavailable (403 policy_error), agent_stopped, agent_suspended and org_stopped (403 permission_error), budget_exceeded (429 rate_limit_error, with Retry-After) and tool_unknown (404). The message is the decision’s own sentence, verbatim. Malformed requests (400 validation_failed) and identity failures (intent_required, intent_invalid, intent_replay) are not recorded. A gateway action keeps running when the HTTP request ends: it is recorded and sealed either way. The Gate owns idempotency on this route, not S03’s middleware: a key names one action per agent for 24 hours, the same key with the same request answers with the original action (and Deedglass-Idempotent-Replayed: true), a duplicate that arrives while the original runs waits for it, and the same key with a different request is 422 idempotency_conflict. An agent key with actions:execute; a stopped or suspended agent’s attempt is recorded and sealed, then refused.

Deedglass-Version
string
/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/

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.

Idempotency-Key
string
>= 1 characters <= 255 characters

Recommended (the SDKs always send one). 1 to 255 printable ASCII characters. It names one action of this agent for 24 hours. The comparison is the request digest plus Deedglass-On-Behalf-Of and Deedglass-Session; a signed intent isn’t part of it, so a retry signed again still replays.

Deedglass-Intent
string
<= 4096 characters

A signed intent: base64url of the intent’s JCS bytes, ., and base64url of the 64-byte Ed25519 signature. The intent follows the schema deedglass.intent/1; the signature input is "deedglass/intent/v1\n" followed by the intent_hash. Clocks may differ by up to 60 s either way, and an intent lives at most 5 minutes. See docs/INTENTS.md.

Deedglass-On-Behalf-Of
string
/^[A-Za-z0-9._~:@/+=-]{1,256}$/

The end user the agent acts for, in your own ids. At most once; a malformed or repeated header is 422 validation_failed.

Deedglass-Session
string
/^[A-Za-z0-9._~:@/+=-]{1,256}$/

The conversation or session the call belongs to, in your own ids. At most once; a malformed or repeated header is 422 validation_failed.

Media typeapplication/json

The body of POST /v1/actions.

object
tool
required

<connector>.<tool>, split at the first dot. The connector is ^[a-z][a-z0-9-]{1,31}$. The tool part is ^[a-z][a-z0-9_]{0,63}$ for native connectors, and the MCP charset ^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$ in proxy mode. Empty, over 200 bytes or not UTF-8 is 400 validation_failed; any other name that isn’t a tool, or that no connector serves in gateway mode, is recorded, sealed and refused with 404 tool_unknown.

string
>= 1 characters <= 200 characters
args
required

The tool’s arguments, a JSON object ({} for none): at most gate.max_args_bytes (256 KiB), nested at most 32 levels, and no integer beyond ±9007199254740991, which RFC 8785 would round (send it as a string). Floats are fine.

object
mode

gateway: Deedglass runs the tool through a connector. proxy: the edge runs it and reports the result.

string
default: gateway
Allowed values: gateway proxy
wait

Seconds to wait for a gateway action to finish before answering 202 processing. The default is gate.wait_timeout (10 s). 0 answers at once.

number
<= 25
context

Who sent the action, as the client says. Never part of any digest; at most 4 KiB.

object
client
object
name
string
<= 64 characters
version
string
<= 64 characters
transport

rest, sdk, mcp_stdio or mcp_http. A call through mcp_stdio or mcp_http for an agent whose intent mode is required is refused with intent_required.

string
/^[a-z][a-z0-9_]{0,31}$/
call_id

The agent framework’s own id for this tool call (a LangChain tool_call_id, a Claude tool_use_id, an OpenAI call_id), stored with the context for correlation. Never part of a digest or a deed. Added 2026-10-05 (S32), additive.

string
/^[\x21-\x7e]{1,128}$/
connector_type

Proxy mode only: the edge’s connector type (default mcp). postgres turns on the SQL facts for a string args.sql. In gateway mode it is 400 validation_failed.

string
Allowed values: postgres rest mcp mcp_http sdk github slack stripe gmail notion fake
tool_digest

The digest of the tool’s definition, sent by MCP edges. Part of request_digest.

string
/^sha256:[0-9a-f]{64}$/
schedule

S40, additive. Gateway mode only (proxy: 400 validation_failed, param: schedule). With require_approval, the approved action runs inside the window: the countersign schedules the run at not_before, and past not_after it is cancelled and sealed with schedule_missed. With allow, it runs now when not_before is at most 60 seconds away and is denied (schedule_needs_approval) otherwise. At least 5 minutes long, not_after within 72 hours and still ahead. Bound into the approval’s context_digest.

object
not_before
required
string format: date-time
not_after
required
string format: date-time
Examples

Deedglass runs the tool

{
"tool": "fake.echo",
"args": {
"message": "hello"
},
"mode": "gateway",
"wait": 10,
"context": {
"client": {
"name": "deedglass-cli",
"version": "0.1.0"
},
"transport": "rest"
}
}

executed or failed (sealed), or authorized (proxy mode). execution.result holds the tool’s result on this response only.

Media typeapplication/json

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
object
required
string
Allowed value: action
id
required
string
/^act_[0-7][0-9a-hjkmnp-tv-z]{25}$/
created_at
required
string format: date-time
livemode
required

true for a dg_live_ key, false for a dg_test_ key. Recorded, not enforced: connectors have no test mode in v1.

boolean
agent
required
object
id
required
string
name
required
string
tool
required
string
connector
required
string | null
mode
required
string
Allowed values: gateway proxy
state
required
string
Allowed values: received authenticated evaluated denied pending_approval executing executed failed witnessing verified mismatch unverifiable sealed expired cancelled
status
required

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.

string
Allowed values: processing authorized pending_approval denied executed failed expired cancelled
on_behalf_of
required
string | null
session
required
string | null
undo

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
undoes
required
string | null
undone_by
required
string | null
pending
string | null
eligible
required
boolean
schedule

S40, additive: the window an approved action runs in, stored once at creation and never changed. Absent when the request carried no schedule.

object
not_before
required
string format: date-time
not_after
required
string format: date-time
decision
required

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
outcome
required
string
Allowed values: allow deny require_approval
code
required

The refusal code (policy_denied, budget_exceeded, agent_stopped, tool_unknown, …), approval_required, or null for an allow.

string | null
source
required

builtin is the Gate’s own decision, such as tool_unknown.

string | null
Allowed values: stop budget rule default builtin
rule_id
required
string | null
reason
required
string | null
message
required

The sentence the agent sees

string | null
policy
required

The policy id (pol_…).

string | null
policy_version
required

The policy version id (pv_…).

string | null
anomaly

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.

string
shadow
required

What the shadow policy would have decided. Recorded, never enforced.

object
outcome
required
string
Allowed values: allow deny require_approval
rule_id
required
string | null
policy_version
required
string | null
policy
required
object
id
required
string | null
version_id
required
string | null
mode
required
string
Allowed values: enforce shadow
decision
required
string | null
Allowed values: allow deny require_approval
rule_id
required
string | null
approval
required

The approval the action waits for, or waited for. null when no rule asked for one.

object
id
required

The approval id (apr_…).

string
status
required
string
Allowed values: pending approved denied expired cancelled
expires_at
required
string format: date-time
decision_reason

S22, additive: the reason a person gave when they denied it. Absent otherwise.

string
execution
required
object
status
required
string | null
Allowed values: succeeded failed unknown
started_at
required
string | null format: date-time
finished_at
required
string | null format: date-time
latency_ms
required
integer | null
error_code
required
string | null
error_message

A short, redacted message from the tool or the Gate (at most 1 KiB).

string | null
<= 1024 characters
result

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.

witness
required

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
object
required
string
Allowed value: witness
level
required
string
Allowed values: L0 L1 L2
verdict
required
string
Allowed values: VERIFIED MISMATCH UNVERIFIABLE
method
required

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).

string | null
required_level
required

The level the policy’s verify: asks for (null on actions recorded before S19).

string | null
Allowed values: L0 L1 L2
summary

One sentence a support engineer can read aloud.

string
reasons
Array<object>

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
witnessed_at
string format: date-time
detail_digest
required

sha256: of JCS(witness_detail): the deed’s witness.detail_digest.

string | null
detail

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
history

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, …).

Array<object>
object
deed
required
string
/^deed_[0-7][0-9a-hjkmnp-tv-z]{25}$/
kind
required
string
Allowed values: action amendment
level
required
string
Allowed values: L0 L1 L2
verdict
required
string
Allowed values: VERIFIED MISMATCH UNVERIFIABLE
at
required
string format: date-time
reason
string
cost
required
object
amount
required
integer
currency
required
string
/^[a-z]{3}$/
request_digest
required

“sha256:” + lowercase hex of SHA-256.

string
/^sha256:[0-9a-f]{64}$/
result_digest
required
string | null
payload_pruned_at
required
string | null format: date-time
deed
required
string | null
next_action
required

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
type
required
string
Allowed values: await_approval execute_at_edge scheduled
approval

await_approval only: the approval id.

string
not_before

scheduled only (S40): an approved action runs from this time.

string format: date-time
not_after

scheduled only (S40): past it the action is cancelled and sealed with schedule_missed; nothing runs.

string format: date-time
expires_at

await_approval only.

string format: date-time
poll_url

await_approval only: /v1/actions/{id}?wait=25.

string
report_url

execute_at_edge only: /v1/actions/{id}/result.

string
deadline

execute_at_edge only: after it, the action is sealed UNVERIFIABLE (edge_lost).

string format: date-time
Examples

Gateway mode, executed and sealed

{
"object": "action",
"id": "act_01k6w3p8r2t4v6x8z0b2d4f6h8",
"created_at": "2026-10-05T04:12:09.114Z",
"livemode": false,
"agent": {
"id": "agt_01k633rrmh3bcz2p39gg4vp46q",
"name": "support-bot"
},
"tool": "fake.echo",
"connector": null,
"mode": "gateway",
"state": "sealed",
"status": "executed",
"on_behalf_of": null,
"session": null,
"decision": {
"outcome": "allow",
"code": null,
"source": "rule",
"rule_id": "allow-fake",
"reason": "Fake tools are safe to run.",
"message": null,
"policy": "pol_01k6r2m8q0s2v4x6z8b0d2f4h6",
"policy_version": "pv_01k6r2m9a1c3e5g7j9m1q3s5v7",
"shadow": null
},
"policy": {
"id": "pol_01k6r2m8q0s2v4x6z8b0d2f4h6",
"version_id": "pv_01k6r2m9a1c3e5g7j9m1q3s5v7",
"mode": "enforce",
"decision": "allow",
"rule_id": "allow-fake"
},
"approval": null,
"execution": {
"status": "succeeded",
"started_at": "2026-10-05T04:12:09.116Z",
"finished_at": "2026-10-05T04:12:09.117Z",
"latency_ms": 1,
"error_code": null,
"error_message": null,
"result": {
"echo": {
"message": "hello"
}
}
},
"witness": {
"object": "witness",
"level": "L0",
"verdict": "VERIFIED",
"method": "reported",
"required_level": "L0",
"summary": "The tool reported success.",
"reasons": [],
"witnessed_at": "2026-10-05T04:12:09.130Z",
"detail_digest": "sha256:0b5f2e9a7c4d1e8f3a6b9c2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a0b3c6d9e2f"
},
"cost": {
"amount": 0,
"currency": "usd"
},
"request_digest": "sha256:c2cb9a8c51c029f97049fed02f985cc49cee22836423d2c9a8e1b74e333a3c4c",
"result_digest": "sha256:fca08626754877b4929151a6f5a278d4189da0bdff4e71b4f523d6f97bb8f0d0",
"payload_pruned_at": null,
"deed": "deed_01k6w3p9a1c3e5g7j9m1q3s5v7",
"next_action": null
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

Deedglass-Version
string

The API version this response follows.

Deedglass-Idempotent-Replayed
string
Allowed values: true

Present, and true, when the response is a stored one replayed for an Idempotency-Key.

processing (still executing or witnessing when wait ended) or pending_approval (waiting for a person). Poll GET /v1/actions/{id}?wait=25.

Media typeapplication/json

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
object
required
string
Allowed value: action
id
required
string
/^act_[0-7][0-9a-hjkmnp-tv-z]{25}$/
created_at
required
string format: date-time
livemode
required

true for a dg_live_ key, false for a dg_test_ key. Recorded, not enforced: connectors have no test mode in v1.

boolean
agent
required
object
id
required
string
name
required
string
tool
required
string
connector
required
string | null
mode
required
string
Allowed values: gateway proxy
state
required
string
Allowed values: received authenticated evaluated denied pending_approval executing executed failed witnessing verified mismatch unverifiable sealed expired cancelled
status
required

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.

string
Allowed values: processing authorized pending_approval denied executed failed expired cancelled
on_behalf_of
required
string | null
session
required
string | null
undo

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
undoes
required
string | null
undone_by
required
string | null
pending
string | null
eligible
required
boolean
schedule

S40, additive: the window an approved action runs in, stored once at creation and never changed. Absent when the request carried no schedule.

object
not_before
required
string format: date-time
not_after
required
string format: date-time
decision
required

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
outcome
required
string
Allowed values: allow deny require_approval
code
required

The refusal code (policy_denied, budget_exceeded, agent_stopped, tool_unknown, …), approval_required, or null for an allow.

string | null
source
required

builtin is the Gate’s own decision, such as tool_unknown.

string | null
Allowed values: stop budget rule default builtin
rule_id
required
string | null
reason
required
string | null
message
required

The sentence the agent sees

string | null
policy
required

The policy id (pol_…).

string | null
policy_version
required

The policy version id (pv_…).

string | null
anomaly

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.

string
shadow
required

What the shadow policy would have decided. Recorded, never enforced.

object
outcome
required
string
Allowed values: allow deny require_approval
rule_id
required
string | null
policy_version
required
string | null
policy
required
object
id
required
string | null
version_id
required
string | null
mode
required
string
Allowed values: enforce shadow
decision
required
string | null
Allowed values: allow deny require_approval
rule_id
required
string | null
approval
required

The approval the action waits for, or waited for. null when no rule asked for one.

object
id
required

The approval id (apr_…).

string
status
required
string
Allowed values: pending approved denied expired cancelled
expires_at
required
string format: date-time
decision_reason

S22, additive: the reason a person gave when they denied it. Absent otherwise.

string
execution
required
object
status
required
string | null
Allowed values: succeeded failed unknown
started_at
required
string | null format: date-time
finished_at
required
string | null format: date-time
latency_ms
required
integer | null
error_code
required
string | null
error_message

A short, redacted message from the tool or the Gate (at most 1 KiB).

string | null
<= 1024 characters
result

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.

witness
required

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
object
required
string
Allowed value: witness
level
required
string
Allowed values: L0 L1 L2
verdict
required
string
Allowed values: VERIFIED MISMATCH UNVERIFIABLE
method
required

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).

string | null
required_level
required

The level the policy’s verify: asks for (null on actions recorded before S19).

string | null
Allowed values: L0 L1 L2
summary

One sentence a support engineer can read aloud.

string
reasons
Array<object>

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
witnessed_at
string format: date-time
detail_digest
required

sha256: of JCS(witness_detail): the deed’s witness.detail_digest.

string | null
detail

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
history

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, …).

Array<object>
object
deed
required
string
/^deed_[0-7][0-9a-hjkmnp-tv-z]{25}$/
kind
required
string
Allowed values: action amendment
level
required
string
Allowed values: L0 L1 L2
verdict
required
string
Allowed values: VERIFIED MISMATCH UNVERIFIABLE
at
required
string format: date-time
reason
string
cost
required
object
amount
required
integer
currency
required
string
/^[a-z]{3}$/
request_digest
required

“sha256:” + lowercase hex of SHA-256.

string
/^sha256:[0-9a-f]{64}$/
result_digest
required
string | null
payload_pruned_at
required
string | null format: date-time
deed
required
string | null
next_action
required

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
type
required
string
Allowed values: await_approval execute_at_edge scheduled
approval

await_approval only: the approval id.

string
not_before

scheduled only (S40): an approved action runs from this time.

string format: date-time
not_after

scheduled only (S40): past it the action is cancelled and sealed with schedule_missed; nothing runs.

string format: date-time
expires_at

await_approval only.

string format: date-time
poll_url

await_approval only: /v1/actions/{id}?wait=25.

string
report_url

execute_at_edge only: /v1/actions/{id}/result.

string
deadline

execute_at_edge only: after it, the action is sealed UNVERIFIABLE (edge_lost).

string format: date-time
Example
{
"object": "action",
"id": "act_01k6w6c4e6g8j0m2p4r6t8w0y2",
"created_at": "2026-10-05T04:25:31.208Z",
"livemode": false,
"agent": {
"id": "agt_01k633rrmh3bcz2p39gg4vp46q",
"name": "support-bot"
},
"tool": "fake.write",
"connector": null,
"mode": "gateway",
"state": "pending_approval",
"status": "pending_approval",
"on_behalf_of": "u_4821",
"session": null,
"decision": {
"outcome": "require_approval",
"code": "approval_required",
"source": "rule",
"rule_id": "writes-need-approval",
"reason": "Writes wait for a human.",
"message": "Waiting for approval under policy \"writes-need-approval\": Writes wait for a human.",
"policy": "pol_01k6r2m8q0s2v4x6z8b0d2f4h6",
"policy_version": "pv_01k6r2m9a1c3e5g7j9m1q3s5v7",
"shadow": null
},
"policy": {
"id": "pol_01k6r2m8q0s2v4x6z8b0d2f4h6",
"version_id": "pv_01k6r2m9a1c3e5g7j9m1q3s5v7",
"mode": "enforce",
"decision": "require_approval",
"rule_id": "writes-need-approval"
},
"approval": {
"id": "apr_01k6w6c5f7h9k1n3q5s7v9x1z3",
"status": "pending",
"expires_at": "2026-10-05T04:40:31.210Z"
},
"execution": null,
"witness": null,
"cost": null,
"request_digest": "sha256:f7ee87ae04b701c55919513f07a30d1c1d738b0373f17df44ed99607f3580749",
"result_digest": null,
"payload_pruned_at": null,
"deed": null,
"next_action": {
"type": "await_approval",
"approval": "apr_01k6w6c5f7h9k1n3q5s7v9x1z3",
"expires_at": "2026-10-05T04:40:31.210Z",
"poll_url": "/v1/actions/act_01k6w6c4e6g8j0m2p4r6t8w0y2?wait=25"
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

Deedglass-Version
string

The API version this response follows.

Deedglass-Idempotent-Replayed
string
Allowed values: true

Present, and true, when the response is a stored one replayed for an Idempotency-Key.

validation_failed: a malformed request, not recorded. param names the field (tool, args, mode, wait, connector_type, tool_digest, context.transport, context.client).

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

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": "validation_failed",
"message": "args is 312 KiB; the limit is 256 KiB. Send a reference to the data instead of the data itself.",
"param": "args",
"request_id": "req_01k6w4a3d5f7h9k1n3q5s7v9x1",
"doc_url": "https://docs.deedglass.com/errors/validation_failed"
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

The API key is missing, not valid, revoked or expired. Nothing is recorded.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

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"
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

Refused. policy_denied and policy_unavailable (policy_error), and agent_stopped, agent_suspended and org_stopped (permission_error) are recorded and sealed, and carry the action in error.action. intent_required, intent_invalid and intent_replay (permission_error) and insufficient_scope are identity failures: nothing is recorded and there is no error.action.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

One of the twelve safety checks (S23 §3.3). Available means no check failed. The full UndoCheck schema is in openapi.yaml.

object
Examples

A rule denied it; the refusal is sealed

{
"error": {
"type": "policy_error",
"code": "policy_denied",
"message": "Blocked by policy \"no-bulk-writes\": writes over 100 rows need a person, not an agent.",
"param": null,
"request_id": "req_01k6w4a3d5f7h9k1n3q5s7v9x1",
"doc_url": "https://docs.deedglass.com/errors/policy_denied",
"action": {
"object": "action",
"id": "act_01k6w4a2c4e6g8j0m2p4r6t8v0",
"created_at": "2026-10-05T04:14:52.630Z",
"livemode": false,
"agent": {
"id": "agt_01k633rrmh3bcz2p39gg4vp46q",
"name": "support-bot"
},
"tool": "fake.write",
"connector": null,
"mode": "gateway",
"state": "sealed",
"status": "denied",
"on_behalf_of": null,
"session": null,
"decision": {
"outcome": "deny",
"code": "policy_denied",
"source": "rule",
"rule_id": "no-bulk-writes",
"reason": "writes over 100 rows need a person, not an agent.",
"message": "Blocked by policy \"no-bulk-writes\": writes over 100 rows need a person, not an agent.",
"policy": "pol_01k6r2m8q0s2v4x6z8b0d2f4h6",
"policy_version": "pv_01k6r2m9a1c3e5g7j9m1q3s5v7",
"shadow": null
},
"policy": {
"id": "pol_01k6r2m8q0s2v4x6z8b0d2f4h6",
"version_id": "pv_01k6r2m9a1c3e5g7j9m1q3s5v7",
"mode": "enforce",
"decision": "deny",
"rule_id": "no-bulk-writes"
},
"approval": null,
"execution": null,
"witness": null,
"cost": null,
"request_digest": "sha256:be1b8c0dafafa9da4de5a1acf33834b5d7306ea41eec46ea1f8befb7985332dc",
"result_digest": null,
"payload_pruned_at": null,
"deed": "deed_01k6w4a4e6g8j0m2p4r6t8w0y2",
"next_action": null
}
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

tool_unknown: no connector serves the tool (gateway mode), or the name isn’t a tool name (a look-alike, say). The attempt is recorded and sealed (decision.source: builtin), and error.action carries it.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

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": "tool_unknown",
"message": "No tool named \"fake.ecko\". Tools look like \"connector.tool\", for example \"fake.echo\".",
"param": null,
"request_id": "req_01k6w4a3d5f7h9k1n3q5s7v9x1",
"doc_url": "https://docs.deedglass.com/errors/tool_unknown",
"action": {
"object": "action",
"id": "act_01k6w4a2c4e6g8j0m2p4r6t8v0",
"tool": "fake.ecko",
"state": "sealed",
"status": "denied",
"deed": "deed_01k6w4a4e6g8j0m2p4r6t8w0y2"
}
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

idempotency_key_in_use, rarely: two requests with the same key raced, and the other one’s action can’t be read yet. Retry in a moment with the same key.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

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"
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

idempotency_conflict: this agent used the Idempotency-Key in the last 24 hours with a different request (another tool, other arguments, another on-behalf-of or session). Also validation_failed for a malformed Deedglass-On-Behalf-Of or Deedglass-Session header.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

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": "idempotency_conflict",
"message": "This Idempotency-Key was used with a different request in the last 24 hours. Use a new key for a new request.",
"param": "Idempotency-Key",
"request_id": "req_01k6w4a3d5f7h9k1n3q5s7v9x1",
"doc_url": "https://docs.deedglass.com/errors/idempotency_conflict"
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

budget_exceeded: a budget refused it. The refusal is recorded and sealed, and error.action carries it. Retry-After says when the budget’s window resets.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

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": "rate_limit_error",
"code": "budget_exceeded",
"message": "Budget \"agent-rate\" reached: 60 of 60 calls this minute. Try again in 14 s.",
"param": null,
"request_id": "req_01k6w4a3d5f7h9k1n3q5s7v9x1",
"doc_url": "https://docs.deedglass.com/errors/budget_exceeded",
"action": {
"object": "action",
"id": "act_01k6w4a2c4e6g8j0m2p4r6t8v0",
"state": "sealed",
"status": "denied",
"deed": "deed_01k6w4a4e6g8j0m2p4r6t8w0y2"
}
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

Retry-After
integer
>= 1

Seconds until the budget’s window resets, at least 1.

An error. Every error has this envelope; doc_url explains the code.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error permission_error policy_error rate_limit_error api_error
code
required
string
Allowed values: invalid_api_key api_key_revoked api_key_expired agent_suspended agent_stopped org_stopped insufficient_scope policy_denied approval_required approval_expired budget_exceeded intent_required intent_invalid intent_replay tool_unknown connector_unavailable upstream_error timeout rate_limited idempotency_conflict validation_failed not_found conflict internal_error authentication_required method_not_allowed request_too_large unsupported_media_type invalid_json api_version_invalid idempotency_key_invalid idempotency_key_in_use service_unavailable session_expired csrf_failed insufficient_role login_link_invalid login_code_invalid last_owner policy_unavailable policy_invalid credentials_missing destination_blocked vault_unavailable upstream_auth_failed upstream_not_found upstream_rate_limited response_too_large statement_refused row_limit_exceeded database_role_unsafe database_not_ready witness_not_configured approval_decided already_countersigned approver_not_eligible self_approval approval_needs_person context_changed approval_unsatisfiable approval_link_invalid approval_link_review_only approver_unmapped stripe_live_key_refused stripe_livemode_detected upstream_approval_pending schedule_needs_approval action_executing from_denied undo_unavailable undo_plan_stale already_undone undo_conflict replay_too_large replay_window_invalid suggestion_stale shadow_slot_taken suggestion_decided observe_not_enabled pro_required
message
required

One or more calm sentences with the next step.

string
param
required

The request field, query parameter or header the error is about.

string | null
request_id
required
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/
doc_url
required
string format: uri
diagnostics

On policy_invalid only. Each problem with its line, code and hint.

Array<object>

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
action

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
checks

On undo_unavailable only. Every check of the undo, each with its fix. Additive (S23).

Array<object>

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"
}
}
Deedglass-Request-Id
string
/^req_[0-7][0-9a-hjkmnp-tv-z]{25}$/

This request’s id. Quote it to support; it matches error.request_id.

Deedglass-Version
string

The API version this response follows.