Faithful to the live Deck API v2.0.0 (captured 2026-06-09). The object shapes, event names, error
envelope, IDs and formats below are exactly what real Deck returns — this page is the vocabulary to
assert against, not a tutorial on Deck. If you know the API, the only new surface is the
control layer at the bottom.
https://api.deck.co/v2 — repointing it is a one-line base-URL change (Interception).
Objects
- task
- task_run
- session
- event
- event_destination
Events
object.action. data is a frozen subset snapshot, and it differs from the REST view: empty fields
serialize as "" (not null) and some fields are dropped — workflow_id is the canonical divergence
(null over REST, "" in the event).
| Resource | Event types |
|---|---|
agent | created · updated · deleted |
source | created · updated · deleted |
credential | created · unverified · verified · invalid · deleted |
session | queued · running · idle · completing · completed · failed |
task | created · updated · reset · deleted |
task_run | queued · running · interaction_required · review_required · completed · failed · canceling · canceled |
storage | created |
event_destination | activated · deactivated |
user | created |
task_run.**canceling** is spelled with one L in the event name, while the run status is cancelling
(two L). /event-types is the only unpaginated list. Deliveries are signed with the
Standard Webhooks scheme (webhook-id / webhook-timestamp /
webhook-signature).Errors
The{ type, code, message, field? } element is the same everywhere, but it surfaces in two places —
which one you get depends on whether the call failed or the run failed.
1 · A call fails → HTTP error response. Status 401/403/404/409/422/429/500, body is the envelope:
| code | HTTP |
|---|---|
request / api_key_invalid | 401 |
request / task_not_found (any *_not_found) | 404 |
idempotency / idempotency_error | 409 |
rate_limit / rate_limit_exceeded | 429 |
400 validation errors are the one exception — a different, RFC-9110-style shape (not the envelope):
404 with an empty body (no envelope); a bad filter value or
over-range Limit is lenient → 200, never 400.
2 · A run fails → the call succeeds (HTTP 200), the error lives inside the run. result: "failure",
output: null, and errors[] holds the same element:
| code | When the run fails because… |
|---|---|
task / blocked | the site blocked automated access |
task / task_failed | the run failed |
task / timeout | it exceeded the 30-min run timeout |
task / task_result_unknown | the outcome couldn’t be determined |
auth / auth_invalid | the credentials were rejected by the source |
source / source_blocked · source_not_available | the source itself failed |
type taxonomy (full set): api · auth · idempotency · interaction · organization ·
rate_limit · request · session · source · storage · task. Note api_key_invalid is type
request, not auth — auth is only for credential-vs-source failures.
Pinnable values
The fields that originate outside Deck’s logic — the only ones you supply. Everything else (status,
result, runtime_ms, ids, timestamps) is engine-derived and unfakeable.
| Path | What | Binds at | null when |
|---|---|---|---|
output | run result body (shape = task’s output_schema) | completed | run fails / cancels |
output.<field> | one output field | completed | agent couldn’t fill it |
errors | failed run’s errors[] | failed | success arm → [] |
interaction | mid-run challenge (mfa / security_question / account_selection) | interaction_required | not paused → null |
result | success / failure / unknown | terminal | non-terminal → null |
Formats & conventions
| IDs | lowercase prefix + 16-char base62 suffix (trun_Ijz17mHzBrps2bt0), immutable |
| Credentials | only username reads back; secrets are write-only |
| Pagination | { data[], has_more, next_cursor, request_id }; param Limit (capital L), clamped at 100 |
| Auth | Authorization: Bearer sk_live_… (sandbox: the printed pbw_… key) |
| Content-Type | application/json; charset=utf-8 |
Control (prod-break)
The only surface that isn’t real Deck. Everything above is the vendor’s; this is how you make a given outcome happen on demand.- Event names and behavior are pack-declared — the engine is generic; the Deck vocabulary above lives in this pack.
- Control calls hit
/__admin__/*. Their errors (e.g. atask_run_idthat doesn’t exist →409) go to your test, not the app under test, and are not Deck’s error envelope.sandbox.world.next()lists the world events whose preconditions currently hold. - No magic test inputs — Deck has none; force outcomes through this surface, never reserved input values.
- Concepts: exogenous values · force a branch · world events · the clock · HTTP API.