A request lost in transit leaves the client unable to tell whether the operation ran. Retrying it may duplicate the effect. The Idempotency-Key header removes that ambiguity: it identifies the attempt, not the request.

Idempotency-Key: order-4f3a2b1c

The key is chosen by the caller. It accepts letters, digits, hyphen and underscore, with a length of 1 to 255 characters; a value outside that pattern answers 400 with invalid_idempotency_key.

The header is optional: without it, each request executes independently. Operations that accept it declare so on their reference page.

Scope and lifetime

Each key is bound to the triple account, operation and key. The same key used against two different operations identifies two different attempts, and two accounts may use the same value without interfering.

The record is kept for 24 hours. Past that window the key is free again, and a request carrying it is treated as new.

Behaviour

situationresponse
New keyThe operation executes normally and its response is recorded
Repeated key, identical bodyThe original response is returned with the Idempotent-Replayed: true header. The operation does not run again
Repeated key, different body422 with idempotency_key_reused
Key in flight409 with idempotency_key_in_progress: the first request is still running

A replay returns the stored response verbatim, status code included. A replayed 201 is still a 201, with the same body and the same resource identifier.

A request ending in a server error does not keep the key taken: the record is discarded so the retry can execute.

The key should be derived from the business attempt — the identifier of the order, batch or transaction being recorded — rather than generated at random on each send. A random key per retry defeats the protection: every attempt looks new.

A 409 means the first request is still running; the correct handling is to wait and check again, not to resend under a different key.