Skip to content

Idempotencia

En toda operación que crea o muta datos (POST, PATCH, PUT) puedes mandar el header Idempotency-Key. Si por cualquier motivo (red intermitente, doble-click, reintento de un job) el mismo request llega dos veces, te devolvemos la respuesta de la primera vez en lugar de duplicar.

Cómo usarla

Genera un identificador único por intento conceptual de la operación. Mándalo en el header:

Idempotency-Key: f1a2b3c4-d5e6-7890-abcd-ef0123456789

Recomendación: usa un UUID v4 o un hash del payload + timestamp.

Reglas

  1. La key vive 24 horas desde el primer uso. Después de eso, la cache se libera y la misma key puede reusarse para un request distinto.
  2. La cache está scopada por empresa: la misma key entre dos cuentas distintas no colisiona.
  3. Si reusas una key con un body idéntico, te devolvemos la respuesta cacheada y agregamos el header Idempotent-Replayed: true.
  4. Si reusas una key con un body distinto, recibes 422 idempotency_key_reused. Cambia la key o iguala el body.
  5. Solo cacheamos respuestas con status 2xx. Si el primer intento dio 422 o 500, no hay caché y un retry pasa por el flujo normal.
  6. El body máximo idempotency-keyed es 100 KB. Bodies más grandes recibirán 413 idempotency_body_too_large y debes quitar el header.

Ejemplo

javascript
const idempotencyKey = crypto.randomUUID()

async function createLead(payload) {
  return fetch('https://developers.fi-nova.com/api/v1/leads', {
    method: 'POST',
    headers: {
      'Authorization':   `Bearer ${SECRET}`,
      'Content-Type':    'application/json',
      'Idempotency-Key': idempotencyKey,
    },
    body: JSON.stringify({ data: payload }),
  })
}

// Primer intento (red flaky) — falla en la red, pero el server ya creó el lead.
await createLead({ name: 'Laura' }).catch(() => null)

// Reintento. Misma key, mismo body. NO duplicamos — devolvemos la respuesta original.
const res = await createLead({ name: 'Laura' })
res.headers.get('Idempotent-Replayed') // → 'true'

Por qué no idempotencia automática

Podríamos hashear el body y deduplicar implícitamente, pero eso sería frágil — dos requests con el mismo contenido pero distinto intent conceptual (ej. dos formularios enviados por personas distintas con coincidentemente el mismo email) se colapsarían a uno. Pedir explícitamente la key te deja el control.

Mejores prácticas

  • Genera la key del lado del cliente, no del servidor que despacha. Si tu frontend hace doble-click, ambas requests llevan la misma key — perfecto. Si tu lambda regenera la key en cada invocación, perdiste la idempotencia.
  • Persiste la key con el form data mientras el usuario llena el formulario. Así, si refresca, la próxima envío con el mismo contenido sigue siendo el mismo request.
  • No reuses keys entre operaciones distintas. create-lead-abc no debe usarse luego para create-customer-xyz.

¿GETs?

Los GET son ya idempotentes por definición HTTP — no necesitas el header. Lo ignoramos si lo mandas.

Hecho con cuidado por Finova.