Idempotencia
El header Idempotency-Key hace que reintentar un POST mutante
sea seguro: si tu red se cae después de mandar la petición pero antes de recibir la
respuesta, reintentas con la misma key y AllSign te devuelve el resultado original en vez de crear un
segundo documento (o cobrar dos veces). Usa un UUID v4 nuevo por cada operación
lógica.
Idempotency-Key: 3f1a9c7e-2b6d-4a51-9f0c-8d2e1b4a6c90
Qué POST la requieren
La Idempotency-Key es requerida en los POST que crean o
disparan algo con efectos secundarios reales:
| Operación | Idempotency-Key |
|---|---|
POST /v3/documents | Requerida |
POST /v3/documents/{id}/send | Requerida |
POST /v3/documents/{id}/void | Requerida |
POST /v3/documents/bulk-sends | Requerida |
POST /v3/signing-sessions | Requerida |
POST /v3/webhooks (create) | Opcional |
POST /v3/webhooks/{id}/rotate-secret | Opcional |
No la usan (ni la aceptan como garantía de idempotencia):
GET— ya son idempotentes por naturaleza.PATCHyDELETE— idempotentes por definición (el estado final es el mismo).- Recordatorio a firmante (
remind signer) — tiene su propio límite: un throttle de 4 horas por firmante que evita el spam sin necesidad de key.
Cómo funciona
La primera vez que llega una key, AllSign procesa la petición normalmente y guarda la
respuesta asociada a esa key. Si vuelve a llegar la misma key con el mismo
cuerpo, no reprocesa: te devuelve la respuesta guardada íntegra (mismo status, mismo
body), con el header Idempotency-Replayed: true para que sepas que fue un replay.
HTTP/1.1 201 Created
Idempotency-Replayed: true
Content-Type: application/json
{ "id": "doc_...", "status": "draft" }
Para decidir si dos peticiones son "la misma", AllSign calcula un fingerprint sobre los bytes crudos del cuerpo (no sobre el JSON normalizado). Reintenta con exactamente el mismo payload que enviaste la primera vez — un cambio de espacios o de orden de campos cuenta como cuerpo distinto.
Respuestas de conflicto
| Código | Cuándo | Qué hacer |
|---|---|---|
409 IDEMPOTENCY_KEY_REUSED |
Reusaste una key con una petición distinta (cuerpo o query string) en el mismo endpoint. | Usa una key nueva para la petición nueva; no mezcles operaciones bajo una misma key. |
409 IDEMPOTENCY_KEY_IN_PROGRESS |
La petición original sigue procesándose. | Espera y reintenta; trae retryAfter (segundos) para saber cuánto. |
400 IDEMPOTENCY_KEY_REQUIRED |
El endpoint la exige y no la mandaste. | Agrega el header Idempotency-Key con un UUID v4. |
400 IDEMPOTENCY_KEY_INVALID |
La key no tiene el formato esperado (UUID v4). | Genera un UUID v4 válido. |
HTTP/1.1 409 Conflict
Content-Type: application/problem+json
{
"type": "https://developers.allsign.io/errors#IDEMPOTENCY_KEY_IN_PROGRESS",
"title": "Conflict",
"status": 409,
"code": "IDEMPOTENCY_KEY_IN_PROGRESS",
"detail": "A request with this Idempotency-Key is still in progress.",
"retryAfter": 2,
"requestId": "req_..."
}
Qué se cachea y por cuánto
No todas las respuestas se guardan para replay. Solo se cachean los resultados determinísticos: si reintentar puede dar un resultado distinto, no tiene sentido guardar el anterior.
| Respuesta | ¿Se cachea? | Por qué |
|---|---|---|
2xx (éxito) | Sí | El resultado es final; reintentar debe devolver lo mismo. |
4xx de validación determinista (p.ej. 422) | Sí | El mismo cuerpo fallará igual; se replica el error. |
402 (pago requerido) | No | Transitorio: reintentar tras arreglar el pago debe poder tener éxito. |
429 (rate limited) | No | Transitorio: reintentar más tarde debe funcionar. |
5xx (error del servidor) | No | Transitorio: reintentar puede tener éxito. |
Las keys se retienen 24 horas. Dentro de esa ventana, reintentar con la misma key te devuelve la respuesta guardada; después, esa key se libera y una petición nueva se procesa desde cero. Genera una key por operación lógica y no la reutilices para operaciones diferentes.