Idempotency-Key header on any
request that changes something, and a retry with the same key returns the
stored answer instead of doing the work again.
Coverage
A key is scoped to your token, the method and the path. The same key used on a different endpoint is a different key, and one organization’s keys are invisible to another’s. It is not scoped to the body. Reusing a key with different content returns the first call’s answer; it does not perform the second call and it does not report a conflict. Generate a fresh key per logical operation — a UUID per attempt-group is the usual shape — rather than reusing one per session or per day.Rules
After 24 hours the record is gone and the same key acts for the first time
again. That is long enough to cover any retry a client should be making, and
short enough that the table does not grow forever.
Not covered
A refusal. If a call is rejected — bad input, missing scope, rate limited — no answer is stored, so your retry is a real attempt rather than a replay of a failure. That is why a rate limit refusal is safe to retry: the429 did not consume
your key.
Without a key
Writes still work; they are just not replay-safe.POST .../events with no key
sends the message, and sending it twice sends it twice.
The one case worth a key even in simple clients is POST /v1/sessions. A
network timeout on session creation is otherwise indistinguishable from a
failure, and retrying leaves you with two sandboxes and a concurrency limit you
are now closer to.
Next
Two calls, one key, at the same time
A dropped connection followed by an immediate retry is the case this header exists for, and most HTTP clients retry in parallel with the request they think died. So the key is claimed before the work starts, not recorded after it finishes. The second caller gets409 conflict: