Reintentos idempotentes
Cómo repetir una creación en la API de Notificado sin crear dos veces: el encabezado Idempotency-Key, qué responde un reintento y cuándo cambiar de clave.
Actualizado:
La red puede fallar después de que el servidor hizo el trabajo: el proceso existe, pero su programa nunca vio la respuesta. Repetir a ciegas lo crearía dos veces. Estas operaciones aceptan el encabezado Idempotency-Key para que un reintento sea seguro:
| Operación | Alcance | Crea | Un reintento con la misma clave responde |
|---|---|---|---|
POST /v1/create-case |
cases:write |
un proceso | el mismo proceso |
POST /v1/add-party |
cases:write |
una parte | la misma parte |
POST /v1/save-party-address |
cases:write |
una dirección en la libreta de la parte | la misma dirección |
POST /v1/request-upload |
cases:write |
un permiso de carga | el mismo permiso: la misma url y la misma key |
POST /v1/confirm-upload |
cases:write |
un documento con su SHA-256 | el mismo documento |
POST /v1/request-import-upload |
cases:write |
un permiso de carga de un CSV | el mismo permiso |
POST /v1/confirm-import-upload |
cases:write |
una importación | la misma importación |
POST /v1/create-notification |
notifications:write |
un borrador de notificación | el mismo borrador |
POST /v1/attach-document |
notifications:write |
un adjunto del borrador | el mismo adjunto |
POST /v1/create-message-template |
notifications:write |
una plantilla de mensaje | la misma plantilla |
POST /v1/send-notification |
notifications:write |
una solicitud de envío para el abogado | la misma solicitud pendiente: el mismo confirmUrl y el mismo expiresAt |
POST /v1/create-memorial |
notifications:write |
un memorial para el juzgado | el mismo memorial |
POST /v1/report-court-outcome |
notifications:write |
la decisión del juzgado sobre la notificación | el mismo registro |
Cada una lleva la insignia Idempotency-Key en la referencia. create-webhook-endpoint no está en la lista a propósito: su respuesta trae el secreto de firma (whsec_…), que se entrega una sola vez y no se guarda para repetirlo. Si esa llamada falla por la red, liste los webhooks con list-webhook-endpoints; si el nuevo está, rote su secreto con rotate-webhook-secret en lugar de crear otro.
La regla
Una clave por solicitud lógica. Genere un valor aleatorio nuevo (un UUID) cuando decida crear algo, y envíe esa misma clave en cada reintento de esa misma solicitud, con el mismo cuerpo.
KEY=$(uuidgen)
curl -X POST 'https://www.notificado.co/v1/create-case' \
-H "authorization: Bearer $NOTIFICADO_TOKEN" \
-H "idempotency-key: $KEY" \
-H 'content-type: application/json' \
-d '{"radicado":"05001310300320260012300","juzgado":"Juzgado 3 Civil del Circuito de Medellín","juzgadoEmail":"j03cctomed@cendoj.ramajudicial.gov.co","ciudad":"Medellín","especialidad":"Civil","claseProceso":"Verbal","cliente":"Inversiones Andinas S.A.S."}'
# ¿se agotó el tiempo? repita el mismo comando con la misma $KEYconst key = crypto.randomUUID(); // una vez, antes del primer intento
for (let attempt = 1; attempt <= 3; attempt += 1) {
try {
const response = await fetch('https://www.notificado.co/v1/create-notification', {
method: 'POST',
headers: {
authorization: `Bearer ${process.env.NOTIFICADO_TOKEN}`,
'content-type': 'application/json',
'idempotency-key': key,
},
body: JSON.stringify({
orgId: '<orgId>',
caseId: '<caseId>',
template: 'art8-personal',
providencia: 'Auto admisorio de la demanda',
providenciaFecha: '2026-09-21',
}),
});
if (response.status !== 429 && response.status < 500) return await response.json();
const wait = Number(response.headers.get('retry-after') ?? attempt * 2);
await new Promise((done) => setTimeout(done, wait * 1000));
} catch {
await new Promise((done) => setTimeout(done, attempt * 2000));
}
}Qué responde un reintento
| Caso | Respuesta |
|---|---|
| Misma clave, mismo cuerpo, primer intento terminado | El primer resultado, idéntico, con x-ultimate-replayed: 1. No se crea nada de nuevo. |
| Misma clave, mismo cuerpo, primer intento aún en curso | 409 X_IDEMPOTENCY_CONFLICT: espere y repita con la misma clave. Una clave nueva aquí crearía dos veces. |
| Misma clave, cuerpo distinto | 409 X_IDEMPOTENCY_CONFLICT: una clave nombra una sola solicitud. Use una clave nueva para una solicitud nueva. |
| Misma clave, el primer intento fue rechazado | El mismo rechazo, repetido. Corrija la causa y envíe una clave nueva. |
| Una clave vacía o de más de 255 caracteres | 400 X_IDEMPOTENCY_KEY_INVALID. |
Una primera respuesta trae x-ultimate-replayed: 0. Las claves se recuerdan 24 horas; pasado ese tiempo, la misma clave es una solicitud nueva.
Qué no cubre
- Las operaciones fuera de la tabla ignoran el encabezado: las lecturas, las ediciones (
update-*), las que quitan (remove-*,discard-draft) ycreate-webhook-endpoint. - Sin clave, una repetición es una solicitud nueva.
attach-documentrepetido respondeX_ATTACHMENT_DUPLICATE, que puede tratarse como hecho;send-notificationrepetido registra otra solicitud pendiente (solo una puede enviar, pero el abogado ve dos). - Una clave no confirma un envío:
send-notificationsolo pide; el abogado confirma en el panel dentro de 24 horas. Repetirlo con la misma clave después deawaiting_confirmationno envía nada ni cambia el plazo. - Una clave no reemplaza leer la negativa:
X_CASE_RADICADO_TAKENsignifica que el proceso ya existe; búsquelo en lugar de reintentar.
Vea también Errores y Autenticación de la API.