Idempotency key is a unique value a client attaches to an API request so that, if the same request arrives more than once, the server performs the action only once and returns the original result for every repeat. In payment APIs it prevents double charges when a response is lost after a timeout. The client generates one value per operation, usually a UUID v4, sends it in a header and reuses it on every retry; the server stores the key with its response, returns a conflict while the original is in progress and rejects reuse with changed parameters. Payouts, refunds and transfers need the same protection, and reviewers test it on every money-moving endpoint.
What is an idempotency key for
An operation is idempotent if doing it several times has the same effect as doing it once. Reading a balance is naturally idempotent; creating a charge is not. The problem arises from timeouts: a merchant's server sends "charge €250", the payment succeeds at the provider, but the response is lost. From the merchant's side, success and failure look identical. Without protection, the safe-looking retry creates a second €250 charge.
How does an idempotency key work
- The client generates a unique value per operation, usually a UUID v4, and sends it in a header, commonly named Idempotency-Key.
- The server checks whether it has seen that key before.
- If not, it processes the request and stores the key together with the response.
- If the key already exists and the original request finished, the server returns the stored response without processing again.
- If the original request is still in progress, the server returns a conflict error and the client waits.
Servers also compare the request body. Reusing a key with different parameters, for example a changed amount, should be rejected as an error rather than silently return the old result. Keys are kept for a limited time; Stripe, for instance, retains them for at least 24 hours. An IETF draft standardises the Idempotency-Key HTTP header for REST APIs generally.
Idempotency key in payment API design
On the client side, the key must be created and saved before the first attempt, tied to the business operation such as order 88412, and reused on every retry of that operation. Generating a fresh key on each retry defeats the purpose. A good retry logic implementation uses exponential backoff and stops after a fixed number of attempts, while the key guarantees at most one charge whatever happens.
Idempotency matters beyond card charges: payouts, refunds and transfers between accounts all need it, and the damage from a duplicated payout is usually harder to recover than a duplicated charge.
Idempotency keys and webhooks
The same principle applies in the other direction. Providers may deliver a webhook event more than once, so the merchant stores event IDs and ignores duplicates, otherwise a repeated "payment succeeded" event might ship an order twice.
What reviewers check
In technical due diligence on a PSP or payment API, reviewers test whether every money-moving endpoint accepts idempotency keys and how long keys persist. Missing idempotency on payouts is a common source of reconciliation losses.