Saltar al contenido principal

Idempotencia

La API soporta idempotencia para repetir mutaciones con seguridad, sin ejecutar la misma operación dos veces. El caso clásico: un POST /api/v1/charges se cae por un error de red y no sabes si el cobro se creó — reenvía con la misma clave y vuelve la respuesta original, sin crear un segundo cobro.

Cómo usarla

Envía el header en cualquier POST, PUT o PATCH:

X-Idempotency-Key: <clave>

La clave se genera de tu lado — recomendamos UUID v4. Máximo de 255 caracteres.

curl -i \
-H "Authorization: Bearer $DUNNING_TOKEN" \
-H 'Content-Type: application/json' \
-H 'X-Idempotency-Key: 8c0f5d6e-3f8b-4cb5-9a47-d8f5b15e9b21' \
-d '{ "personId": "cmd8k1x2y0009cd4e", "amount": 1500.00, "dueDate": "2026-08-10" }' \
-X POST 'https://api.dunning.kobana.com.br/api/v1/charges'

Cómo funciona

  1. La clave se reserva atómicamente, acotada a tu organización (organizaciones distintas pueden usar la misma clave sin conflicto).
  2. El servidor calcula la huella digital de la request: hash de método + ruta + body crudo.
  3. El handler se ejecuta y la respuesta (status, body, headers) queda grabada vinculada a la clave — incluso cuando es un error.
  4. Una nueva request con la misma clave dentro de 24 horas recibe la respuesta original textual, con el header extra:
X-Idempotent-Replay: true

Pasadas las 24 horas la clave expira y la misma clave genera una ejecución nueva.

Conflictos

EscenarioStatuscode
Misma clave con método/ruta/body distinto409IDEMPOTENCY_KEY_REUSED
Otra request con la misma clave en curso409IDEMPOTENCY_REQUEST_IN_PROGRESS
Clave vacía o con más de 255 caracteres400VALIDATION_ERROR

Ejemplo de respuesta de conflicto:

{
"message": "X-Idempotency-Key já foi usado com parâmetros diferentes. Reenvie os parâmetros originais ou gere uma nova chave",
"code": "IDEMPOTENCY_KEY_REUSED"
}

En IDEMPOTENCY_REQUEST_IN_PROGRESS, espera un instante y reenvía la misma request: o la primera ejecución termina y recibes el replay, o la reserva se liberó y tu intento se ejecuta.

Cuándo el resultado no se graba

Es seguro reenviar cuando el handler ni siquiera llegó a correr:

  • Request rechazada antes del handler (JSON inválido, autenticación ausente).
  • El handler lanzó una excepción — la reserva se libera para que el próximo reintento corra limpio.

Métodos aceptados

Método¿Acepta X-Idempotency-Key?
POST / PUT / PATCH✅ Sí
GET / DELETE❌ No — ya son idempotentes por definición; el header se ignora

Buenas prácticas

  • Una clave por operación de negocio; repítela solo en reintentos de la misma operación.
  • Persiste la clave junto con el estado de la operación de tu lado — el reintento post-crash usa la misma clave.
  • Combínala con backoff exponencial en 5xx/timeout: la clave garantiza que el reintento no duplica nada.
  • Como los errores también se graban, un replay de error es señal para corregir la request y generar una clave nueva — no insistir con la misma.
  • Descarta claves con más de 24 horas de tu lado; el servidor ya las expiró.