Idempotency
Make create operations safe to retry with the Idempotency-Key header.
Network calls fail and get retried. Without protection, a retried "create payment"
could charge a customer twice. The Idempotency-Key header makes mutating creates
safe to retry.
How to use it
Send a unique key on each logical operation you want to be idempotent:
POST /api/v1/payments
Idempotency-Key: 0f8b6d2e-… # one per attempt-set, not per retry- First request with a given key executes normally and the response is snapshotted against that key.
- A repeat with the same key and same body replays the stored response — the operation runs at most once.
- Idempotency is opt-in: omit the header and the request executes normally every time.
Pick the key per operation, reuse it on retry
Generate one key when you start a "create payment" (or refund, or invoice) operation and reuse that same key for every retry of it. Use a fresh key for a genuinely new operation.
Conflicts
errorCode | HTTP | When |
|---|---|---|
IDEMPOTENCY_KEY_CONFLICT | 409 | The same key was reused with a different request body. |
IDEMPOTENCY_IN_PROGRESS | 409 | A request with the same key is still being processed — retry shortly. |
A 409 IDEMPOTENCY_KEY_CONFLICT almost always means a bug on the client side —
the same key is being used for two different payloads. Generate a new key for a new
operation.
Where it applies
Idempotency is supported on create-style mutations:
POST /payments— create a paymentPOST /payments/{id}/refunds— create a refundPOST /invoices— create an invoice
Reads are naturally idempotent and need no key.