Webhooks
Un webhook es un destino tuyo, una URL https, al que Datrus manda un aviso cuando pasa algo con el consentimiento de una persona o con una solicitud de derechos. Los eventos son los doce del catálogo: seis de consentimiento y seis de derechos (recibida, acusada, prorrogada, bloqueo ordenado, por vencer y resuelta). El resto de los módulos se consulta por la API y la bitácora.
Crear un destino
curl -X POST https://www.datrus.cl/api/v1/webhooks \
-H "Authorization: Bearer dtr_live_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: …" \
-d '{ "name": "CRM", "url": "https://crm.miempresa.cl/datrus", "events": ["consentimiento.otorgado", "consentimiento.revocado"] }'
La respuesta trae el secret una sola vez. Con él verificarás cada entrega. Si lo pierdes, POST /webhooks/{id}/rotate-secret entrega uno nuevo y las entregas pendientes se firman con él.
Qué recibe tu servidor
POST /datrus HTTP/1.1
Content-Type: application/json
X-Datrus-Firma: t=1757894400,v1=5f0c…e2a1
{
"id": "…",
"evento": "consentimiento.otorgado",
"emitidoEn": "2026-09-14T12:00:00.000Z",
"tenantId": "…",
"datos": {
"acuerdoId": "…", "acuerdoVersionId": "…", "evidenciaId": "…",
"version": 3, "origen": "formulario", "hashVersion": "…",
"creados": 2, "removidos": 0, "extendidos": 0, "acortados": 0, "fuentesRetiradas": 0,
"terceros": []
}
}
Y cuando entra una solicitud de derechos
Los seis eventos de derechos comparten destino, firma, reintentos y bitácora de entregas; lo que cambia es datos: el código de la solicitud, el canal por el que entró, los derechos pedidos, el estado y las fechas del plazo del art. 11. solicitud.por_vencer sale a los 5 días, a los 2 y el día del vencimiento, con diasRestantes. Es lo que deja orquestar el reloj desde tu mesa de ayuda sin consultar la API.
{
"id": "…",
"evento": "solicitud.recibida",
"emitidoEn": "2026-10-08T14:02:11.000Z",
"tenantId": "…",
"datos": {
"solicitudId": "…", "codigo": "SD-4K7M",
"canal": "correo_admision",
"derechos": ["acceso", "supresion"],
"estado": "esperando_verificacion",
"recibidaEl": "2026-10-08", "acuseEl": null,
"venceEl": "2026-11-07", "prorrogaEl": null,
"diasRestantes": null,
"version": 1
}
}
acuerdoId, el mismo id que ves en la consola y en las exportaciones. Correlacionarlo con tu cliente es trabajo del receptor, con el dato que tú ya tienes y nosotros no. Así un webhook interceptado no expone a nadie.Verificar la firma
La cabecera X-Datrus-Firma trae la marca de tiempo en segundos (t) y la firma (v1): un HMAC-SHA256 del secreto sobre la cadena t + "." + cuerpo, con el cuerpo tal cual llegó, sin reformatear. Rechaza lo que tenga más de 300 segundos de diferencia con tu reloj.
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verificar(cuerpoCrudo, cabecera, secreto) {
const partes = Object.fromEntries(cabecera.split(',').map((p) => p.split('=')))
const t = Number(partes.t)
if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > 300) return false
const esperada = createHmac('sha256', secreto).update(`${t}.${cuerpoCrudo}`).digest('hex')
const recibida = String(partes.v1 ?? '')
return recibida.length === esperada.length && timingSafeEqual(Buffer.from(recibida), Buffer.from(esperada))
}
Responde 2xx rápido y procesa después. Cualquier otra respuesta, o no responder, cuenta como fallo.
Reintentos
Una entrega que falla se reintenta hasta 8 veces, esperando 60, 300, 900, 3600, 21600, 43200, 86400 segundos entre intentos. Cada intento se registra: GET /webhooks/{id}/deliveries muestra el estado, el código recibido y el próximo intento. Cuando se agotan, la entrega queda marcada y no se vuelve a mandar sola.
Las entregas salen en el momento en que ocurre el evento. Si necesitas forzar el despacho de lo pendiente, POST /webhooks/dispatch lo hace y te dice cuántas intentó, entregó y falló.
Reenviar un aviso
Si tu receptor perdió un aviso (un despliegue a mitad de una entrega, una cola que se vació del otro lado), pídelo de nuevo: POST /webhooks/{id}/deliveries/{deliveryId}/resend encola una entrega nueva con el mismo cuerpo, incluido el id del aviso, y la manda en el acto firmada con el secreto vigente. La entrega original no se toca: su historia de intentos es evidencia de lo que pasó. Un receptor que deduplica por id lo reconoce como el mismo evento.
Pausar y editar
PATCH /webhooks/{id} cambia nombre, URL o eventos, y pausa o reanuda el destino. Un destino pausado no encola entregas nuevas.