Idempotencia
Reintentar sin miedo — la misma llave es el mismo pedido.
El problema que resuelve
Mandaste un POST /v1/transfers y se cayó la conexión antes de la respuesta.
¿Se movió el dinero o no? Sin idempotencia, reintentar puede pagar dos veces; no
reintentar puede no pagar nunca. Con idempotencia, reintentas siempre y duermes
tranquilo.
Cómo funciona
Todo endpoint que mueve dinero exige el header Idempotency-Key: un UUID que
generas tú, uno por operación lógica.
curl -X POST https://api.tikin.is/v1/transfers \
-H "Authorization: Bearer tk_live_…" \
-H "Idempotency-Key: 3f6f4ac2-8f5e-4c1b-9d0a-6a1c2b3d4e5f" \
-H "Content-Type: application/json" \
-d '{
"source_account": "7b0d0f52-3f3e-4bf0-9d5a-111111111111",
"destination": { "type": "account", "account_id": "b937b865-32ad-44a5-a654-067154480465" },
"amount": { "raw": "2500000", "asset": "COPM" },
"description": "almuerzo"
}'Los tres desenlaces:
| Respuesta | Qué pasó |
|---|---|
201 | La operación se ejecutó por primera vez |
200 | Replay — esta llave ya ejecutó; te devolvemos la operación original, no nació nada nuevo |
409 | La misma llave con otro cuerpo — eso no es un reintento, es un bug tuyo, y te lo decimos |
Idempotent-Replay: true
Todo replay (el 200 de la tabla) trae el header Idempotent-Replay: true.
La respuesta es la misma que la original a propósito — este header es la única
diferencia, y es tu observabilidad del reintento: cuéntalos en tus métricas y
sabrás cuántas veces tu red se cayó a mitad de un pago sin que se pagara dos
veces. Una respuesta sin el header fue la ejecución original.
Las reglas de uso
- Una llave por operación lógica, no por request HTTP. "El pago de nómina de María de septiembre" es UNA llave, la reintentes las veces que la reintentes.
- Guarda la llave ANTES de mandar el request. Si la generas al vuelo en cada intento, no tienes idempotencia — tienes UUIDs decorativos.
- Sin el header →
400. No es opcional en nada que mueva dinero: transferencias, bonos, payouts, disparar lotes, crear cuentas.
El patrón de reintento
Timeout o 5xx → reintenta con la misma llave, con backoff. Un 503 significa
"no se supo" — jamás asumas que falló: reintenta y la respuesta te dirá si ya
había pasado (200) o si pasó ahora (201).