Idempotency support for POST requests via the optional Idempotency-Key header, enforced globally at the middleware level
All POST endpoints on this API support idempotent requests via the optional Idempotency-Key request header.
This is enforced at the middleware level and applies globally — no endpoint-specific configuration is needed.
| Header | Type | Required | Max length |
|---|---|---|---|
Idempotency-Key |
string |
Optional | 255 characters |
Recommended value: a UUID v4 generated per logical operation by the client (e.g. 7f3e4c2a-1b5d-4f8e-9c6a-2d7b0e3f1a4c).
| Scenario | Response |
|---|---|
| First call | Processed normally. Response cached against the key for 24 hours. |
| Retry — same key, same payload | Cached response returned immediately. No business logic re-executed. |
| Retry — same key, different payload | 409 Conflict with conflictReason: hash_mismatch. |
| Concurrent retry while first call is in flight | 409 Conflict with conflictReason: processing and Retry-After: 30. |
| Key exceeds 255 characters | 422 Unprocessable Entity with conflictReason: invalid_key. |
| Idempotency store unavailable | Request is processed without idempotency protection (fail-open). |
processingReturned when the same key is submitted while the original request is still being processed.
The Retry-After response header and the retryAfterSeconds meta field indicate how many seconds to wait before retrying.
{
"errors": [
{
"id": "de4e1bd5-9223-435a-b56d-1b0190a12313",
"status": "409",
"title": "Conflict",
"detail": "The original request is still being processed. Retry after the specified interval.",
"meta": {
"conflictReason": "processing",
"retryAfterSeconds": 30
}
}
]
}
hash_mismatchReturned when the key is reused with a different request payload. The original key cannot be reused with a different body.
{
"errors": [
{
"id": "de4e1bd5-9223-435a-b56d-1b0190a12314",
"status": "409",
"title": "Conflict",
"detail": "An idempotency key was reused with a different request payload.",
"meta": {
"conflictReason": "hash_mismatch"
}
}
]
}
invalid_keyReturned when the Idempotency-Key header value exceeds 255 characters.
{
"errors": [
{
"id": "de4e1bd5-9223-435a-b56d-1b0190a12315",
"status": "422",
"title": "Unprocessable Entity",
"detail": "Idempotency-Key must not exceed 255 characters.",
"meta": {
"conflictReason": "invalid_key"
}
}
]
}
This is documentation only - not a real endpoint