Overview
When creating a transaction, a network drop, client timeout, or unexpected5xx response can leave you unsure whether the operation was processed. Retrying the request without a safeguard can result in duplicate transactions.
The Idempotency-Key header lets you retry any transaction-creation POST safely. If Capa receives a request with a key it has already seen, it replays the original response β no duplicate transaction is created. The header is opt-in: if omitted, the request is processed normally with no idempotency guarantee.
Supported Endpoints
The header is recognized on the followingPOST endpoints only. All other endpoints ignore it.
How It Works
- Generate a unique
Idempotency-Key(UUIDv4 recommended) for each logical operation and include it as an HTTP header. - Capa processes the request and caches the response under the
(userId, key)pair. - On retry, send the identical request body with the same key. Capa detects the duplicate and returns the original response β the handler is not invoked again.
- Failed originals can be retried. If the first attempt resulted in an error (non-2xx), the record is marked
FAILEDand a subsequent request with the same key reprocesses normally. - The guarantee window is 48 hours. After that the key expires, the record is reclaimed, and the next request is treated as a new operation. It is the callerβs responsibility to avoid duplicates beyond this window.
Header Reference
| Field | Value |
|---|---|
| Name | Idempotency-Key |
| Required | No (opt-in) |
| Format | 16β128 printable ASCII characters |
| Recommended value | UUIDv4 |
| Scope | (userId, idempotencyKey) β scoped per user, not per endpoint |
Behavior Matrix
| Scenario | Behavior | HTTP Status |
|---|---|---|
| New key | Request is processed; response cached under key | Handlerβs status (2xx) |
| Same key + same body, original completed | Cached response replayed; handler not invoked | Original status |
| Same key + same body, original in-flight | Request rejected β wait and retry | 409 Conflict |
| Same key + different body | Rejected β request body hash mismatch | 422 |
| Same key + original failed (non-2xx) | Record marked FAILED; request reprocessed | Handlerβs status |
| Key older than 48h | Record reclaimed; request treated as new | Handlerβs status (2xx) |
Errors
| HTTP Status | Code | Message |
|---|---|---|
400 | INVALID_USER_INPUT_ERROR | Malformed Idempotency-Key header (format violation) |
409 Conflict | β | Same key is already being processed; retry after a short delay |
422 | INVALID_USER_INPUT_ERROR | Idempotency-Key was already used with a different request body |
Best Practices
- Generate a fresh UUIDv4 per logical operation. Never hardcode or reuse keys across distinct operations.
- Persist the key client-side until you receive a confirmed terminal response for that operation.
- Retry with the identical body. Changing any field in the request body is treated as a different operation and results in a
422. - Do not share a key across endpoints for the same user. Keys are scoped to
(userId, key), so the same key on a different endpoint collides on a body hash mismatch. - Omit the header on
GET,PUT,PATCH, andDELETErequests β it has no effect on those methods. - Plan for the 48-hour window. Retries after expiry are reprocessed as new requests; implement your own deduplication logic for long-lived operations.
Example
Idempotency-Key. Capa will return the original response without creating a second transaction.