Idempotent writes
A client that retries a write after a timeout can't tell whether the first
try worked. So every route but a GET honours the Idempotency-Key
header: the client sends the same key with each try, and a repeat gets the
first try's answer. The runtime handles the key entirely; the action never
sees it.
HTTP already calls PUT and DELETE idempotent, but a retried DELETE
answers 404 where the first answered 204, and the action behind any write
may raise events or call providers. So the key covers them too.
- Before the action runs, the runtime claims the key, scoped to the caller.
- Afterwards, it keeps the response with a digest (a hash) of the request, in the action's transaction, for 24 hours.
- A repeat gets the kept response.
- The same key with a different request fails
idempotency_key_reused(422). A repeat while the first is still running failsconflict(409). - Successes and failures the action returns are kept.
unavailableand internal failures are not, so a retry runs again. - Calls to outside services in the action send keys derived from the client's key (Calling).
An API can require the key with idempotency: Idempotency.required, and
OpenAPI lists the header. The default is Idempotency.optional. When a
repeat counts as the same request is under
How failures reach the client.
- Whose keys they are. A signed-in caller's keys are kept under their
user id. A route anyone may call keeps its keys under
anonymous. - A request that never finishes. The claim holds no response and lasts only for the route's deadline and five seconds, so it lapses.
- What a repeat answers with. The kept status, body and code, under the
repeat's own
x-request-id. - Where keys are kept. In the store the action writes. An action that
writes no store but emits, or that makes a changing call, keeps them in
the store
events: { store: }names. One that does none of these keeps none, since running it again changes nothing.
Markdown for agents: /docs/idempotent-writes.md.Built from Jadpo main at aee2e8f.