Skip to main content

Idempotency

The API supports idempotency so requests can be safely retried without executing the same operation twice. Useful when a call is interrupted in transit and you don't get a response — for example, a request to create a payable that drops on a network error can be retried with the same key, guaranteeing that only one record is created.

How to use it

Send the X-Idempotency-Key: <key> header on any POST, PUT, or PATCH request. The key is free-form, generated on your side. We recommend UUID v4 or any random string with enough entropy to avoid collisions.

curl -i \
-H "Authorization: Bearer $KOBANA_TOKEN" \
-H 'Content-Type: application/json' \
-H 'X-Idempotency-Key: 8c0f5d6e-3f8b-4cb5-9a47-d8f5b15e9b21' \
-H 'User-Agent: Meu Sistema (contato@example.com)' \
-d '{
"account_id": "00000000-0000-0000-0000-000000000001",
"description": "Aluguel Janeiro/2026",
"amount": "3500.00",
"due_date": "2026-01-10"
}' \
-X POST 'https://api.finance.kobana.com.br/v1/payables'

How it works

When the server receives a request carrying X-Idempotency-Key:

  1. Reserves the key atomically, scoped to the workspace. Two different workspaces can use the same key without conflict.
  2. Computes a request fingerprint — SHA-256 of method + path + raw body. That hash is stored alongside the key.
  3. Runs the handler. If it returns a response, the server records status_code, body, and relevant headers tied to the key.
  4. Marks the key as completed. Any new request with the same key within 24 hours receives the original response verbatim — same status_code, same body, same headers — plus an X-Idempotency-Replayed: true header to indicate that it is a replay.
warning

The layer records the result regardless of whether it succeeded or failed. Retries with the same key return the same result, including 5xx errors — to genuinely try again after a server error, generate a new key.

Limits

  • Maximum key length: 255 characters.
  • Retention: keys expire automatically 24 hours after creation.
  • Scope: per workspace. A key used in one workspace does not interfere with another.
  • Accepted characters: any printable UTF-8 string.

Conflicts

If the same key is reused with a different request (any change in method, path, or body), the API responds 409 conflict with details.reason = "idempotency_key_reused".

{
"error": {
"code": "conflict",
"message": "X-Idempotency-Key was already used with different request parameters. Reuse the original parameters or generate a new key.",
"details": { "reason": "idempotency_key_reused" }
}
}

Accepted methods

MethodAccepts X-Idempotency-Key?
POST✅ Yes
PATCH✅ Yes
GET❌ No (already idempotent by definition)
DELETE❌ No (already idempotent by definition)

Best practices

  • One key per logical operation. Don't reuse the same key to create two different resources — you will get 409 conflict.
  • Persist the key alongside the operation state on your side, so a retry after a crash or restart uses the same key.
  • Pair it with exponential backoff on 5xx or timeout responses.
  • Clean up the key after 24 hours. There is no benefit to keeping it on your side beyond that.