Idempotency-Key and the expected_aggregate_version
you last observed, so two actors cannot both claim the same handoff without
one of them getting a 409.
Wire shape
Reads also include
aggregateVersion — the number you echo back as
expected_aggregate_version on the next transition.
State machine
States:proposed, claimed, returned, fulfilled, escalated,
cancelled. Terminal states: fulfilled and cancelled.
An illegal transition returns
409 handoff_conflict; so does a stale
expected_aggregate_version.
Operations
All routes acceptAuthorization: Bearer oxk_... or a web-app session;
every mutation requires an Idempotency-Key header.
201 (or 200 on idempotent replay) with
{ "data": <handoff>, "meta": { "duplicate", "aggregateVersion", ... } }.
Transition bodies are exactly two fields
return, escalate, and cancel accept only workspace_id and
expected_aggregate_version, both required. The schema is strict: there is no
reason, note, comment, or actor field, and sending one is a 400
rather than being ignored. claim is the same two fields; fulfill adds a
required result (JSON object).
The transition 400 responses carry { "error": { "code", "message" } } with
no details — the code is what tells you which call failed:
All five transitions share
404 handoff_not_found (unknown ID, or a
workspace_id that is not the authed workspace), 409 handoff_conflict
(illegal transition or stale version), 503 handoff_unavailable, and
400 missing_idempotency_key / 400 invalid_handoff_id.
Where the IDs come from
MCP equivalents
No MCP tool operates on this resource today — stage handoffs are REST-first. (The MCPorgx_spawn tool’s handoff action delegates agent tasks, which is
a different mechanism from stage handoffs.)