Skip to main content

Idempotency

The operations that start paid or visible work accept a deduplication key:

A request carrying a key that already names a resource runs nothing and answers with that resource, in whatever state it has reached.

This page is the canonical definition. Module pages describe what their own replay returns and link here.

Operations that accept a key​

OperationScopeFirst requestRetry under the keySame key, different request
POST /api/v1/agents/{agent_id}/generateprojectruns as usual202 with the generation handle409 IDEMPOTENCY_KEY_REUSED
POST /api/v1/orchestration-runsproject201200 with the run409 IDEMPOTENCY_KEY_REUSED
POST /api/v1/sessions/{session_id}/messagessession201200 with the original message409 IDEMPOTENCY_KEY_REUSED
POST /api/v1/tasksproject201200 with the task as it is now409 IDEMPOTENCY_KEY_REUSED
POST /api/v1/tasks/{task_id}/transitionstask200200 with the task as it is now409 IDEMPOTENCY_KEY_REUSED

A retry that arrives while the original is still running replays it too. What each operation compares to decide "same request" is on its module page: agents, orchestrations, sessions, task creates, task transitions.

Sending a key​

The key travels in the idempotency_key body field or the Idempotency-Key header:

soat start-orchestration-run \
--orchestration-id "$ORCH_ID" \
--idempotency-key "dispatch-2026-09-18-activation-42"
RuleRefusal
A non-empty string of at most 255 characters, stored verbatim400 VALIDATION_FAILED
Header and body field together must name the same key400 VALIDATION_FAILED
The header is sent once400 VALIDATION_FAILED

MCP tool calls send the body field: tool schemas carry no headers.

How long a key lasts​

A key is claimed by the record its first request wrote, for as long as that record exists. There is no expiry window, so a retry never finds the key released and runs a second time.

Keys the server sets​

WhereKeyPurpose
Orchestration node executions{orchestration_run_id}:{node_id}:{attempt}A redelivered node reuses its stored output; an http tool node forwards the key as its Idempotency-Key request header
Event trigger firings<event_id>:<trigger_id>One firing per event and trigger