SDKs
Idempotency
A write that times out may still have succeeded. Retrying it can create a second charge, a second user, a second order. Every generated client sends an idempotency key on writes so your server can recognise a repeat and return the original result instead of doing the work twice.
The mechanism already ships in the client. These settings configure it, in SDK Studio.
Defaults
Configure nothing and you get:
| Generate an idempotency key | On |
| Header name | Idempotency-Key |
| Methods | POST and PATCH |
Idempotency-Key is the Stripe convention, and the one most API consumers already recognise.
The settings
| Setting | What it does |
|---|---|
| Generate an idempotency key | Turn key generation off entirely |
| Header name | The header the key travels in |
| Methods | Which HTTP methods get a key: POST, PUT, PATCH, DELETE |
A per-endpoint override merges over your project default field by field, so an endpoint that only turns generation off keeps your custom header name.
When to change it
Your server has to honour it
This is the part that catches people out.
The client generating a key is half the contract. Your server has to store the key and, on a repeat, return the original response instead of performing the write again. Without that, the header is an ignored string and a retried POST still double-charges.
Turning this on doesn't make your API idempotent. It makes your clients ready for an API that is.
A workable server-side implementation:
- Read the key
Take the header off the request. No key means process normally.
- Claim it atomically
Insert it with a unique constraint before doing the work. A conflict means this is a repeat.
- Replay the stored response
Store the status and body against the key on first completion, and return it for repeats. Scope keys per account so one tenant can't probe another's.
- Expire them
Keys only need to outlive a client's retry window. 24 hours is generous.
Relationship to retries
Idempotency is what makes retries safe on writes. If you widen your retry status codes to cover POST on 500, this is what stops that retry duplicating the write.