Idempotency-Key

The unofficial Idempotency-Key request header carries a client-chosen unique key letting a server recognize a retried POST or PATCH as a repeat of an earlier request instead of a new operation.

Usage

The Idempotency-Key header exists for safe retries. A payment request timing out leaves the client unsure whether the charge happened, and retrying without protection risks a double charge. Sending the same Idempotency-Key on the retry lets the server match the attempt to the stored outcome of the first request and replay the response instead of executing the operation again.

The header targets the methods lacking idempotency, POST and PATCH. GET, PUT, and DELETE carry idempotency by definition, so a retry needs no key.

The key is unique per operation and never reused with a different payload. A UUID or a similarly random identifier is the recommended form. Servers bound stored keys with an expiry policy, Stripe prunes keys after 24 hours, and some pair the key with a fingerprint of the request payload to detect a reused key carrying different content.

Stripe, Adyen, Dwolla, and other payment and API platforms document the pattern under this header name, predating and informing the draft.

Values

Unique key string

The value is a Structured Fields String holding the client-generated key, quoted on the wire.

Example

A client submits a payment with a UUID key. The request times out, the client retries with the same key, and the server replays the stored response rather than charging twice.

POST /payments HTTP/1.1
Host: api.example.re
Content-Type: application/json
Idempotency-Key: "8e03978e-40d5-43e8-bc93-6894a57f9324"
Content-Length: 48

{"amount": 4900, "currency": "EUR", "ref": "A7"}

Error responses

The draft maps the failure cases to three status codes, each with a problem details body: a keyless request where the server requires one returns 400, a key reused with a different payload returns 422, and a retry arriving while the first request is still processing returns 409, telling the client to wait and retry with the same key. Vendors vary: Stripe answers a reused key carrying different parameters with 400.

See also

Last updated: August 18, 2026