Idempotency
Safely retry requests without performing an operation twice
Overview
The API supports idempotency so you can safely retry a request without accidentally performing the same operation twice — for example, avoiding a double charge or a double refund when a network error hides the response of a request that actually succeeded.
To make a request idempotent, send an Idempotency-Key header with a unique value you
generate (a UUID v4 is a good choice). If the same key is seen again, the API returns the
original response instead of executing the operation a second time.
curl -X POST https://api.settleflow.io/v2/payments \
-H "X-Api-Key: your_api_key" \
-H "Idempotency-Key: 8f2b1c9a-7d3e-4b6a-9c1f-2e5d4a3b7c8d" \
-H "Content-Type: application/json" \
-d '{ "amount": 1000, "currency": "EUR", "reference": "order_12345" }'Where it applies
Idempotency keys apply to all mutating requests — every POST and PUT:
| Endpoint | Why it matters |
|---|---|
POST /payments | Avoid creating a payment twice |
POST /payments/{id}/capture | Avoid capturing twice |
POST /payments/{id}/refund | Avoid a double refund |
POST /payments/{id}/void | Avoid voiding twice |
POST / PUT /webhooks/config | Avoid duplicate webhook endpoints |
GET and DELETE requests are naturally idempotent and ignore the header.
How it works
- First request — the operation runs and its response (status + body) is stored against your key.
- Retry with the same key and the same body — the stored response is replayed; the operation does not run again.
- Reuse a key with a different request body — rejected with
409and anidempotency_error. A key is bound to the exact request that first used it. - Retry while the first request is still in flight — rejected with
409until the first one finishes. 5xxresponses are cached so a retry replays the failure deterministically; a validation error (400) is not cached, so you can fix the body and retry with the same key.
Key lifetime
Keys are retained for 24 hours. After that a key is pruned and reusing it starts a fresh operation, so generate a new key for each distinct operation you want to be able to retry.
Best practices
- Generate one key per logical operation (e.g. one per checkout attempt) and reuse it only for retries of that same operation.
- Use a high-entropy value such as a UUID v4.
- Always retry with the same body you sent originally.