DeCAya

Webhooks de DeCAya

Un webhook avisa a tu servidor en cuanto cambia el estado de un DeCA, sin que tengas que consultar la API en bucle. Da igual quién haya hecho el cambio: los eventos se emiten tanto si el documento se creó por API como si lo creó una persona en el panel.

Eventos

EventoCuándo se emite
document.generatedSe ha emitido un DeCA y su PDF ya está disponible.
document.modifiedSe ha creado una versión nueva: hay un PDF, una URL y un QR nuevos.
document.completedEl servicio de transporte se ha marcado como finalizado.
document.cancelledEl DeCA se ha anulado.

Formato del evento

El payload es deliberadamente breve: identificadores, estado y tus propias referencias. Los datos del artículo 6 son contenido regulado y no viajan en el webhook; se leen con GET /api/v1/documents/{id} cuando los necesites.

{
  "id": "evt_5f2c9a1b4e7d4c0f8a3b6d9e2c1f4a70",
  "type": "document.generated",
  "version": "2026-08-20",
  "environment": "production",
  "createdAt": "2026-10-05T07:12:44.201Z",
  "data": {
    "documentId": "0f2c…",
    "documentNumber": "DEC-2026-000184",
    "versionNumber": 1,
    "status": "generated",
    "externalId": "SO-4821",
    "externalSource": "sap"
  }
}

El campo version versiona el sobre, no la URL: un mismo endpoint sigue recibiendo eventos cuando el formato evolucione.

Verificar la firma

Cada envío lleva la cabecera DeCAya-Signature con la marca de tiempo y un HMAC-SHA256 del texto <timestamp>.<cuerpo>, calculado con el secreto del endpoint:

DeCAya-Signature: t=1791184364,v1=3f7c…

Verifica siempre antes de procesar. Calcula el HMAC sobre el cuerpo en crudo, no sobre el JSON reserializado, y rechaza marcas de tiempo con más de 5 minutos de antigüedad: el timestamp va dentro de la firma precisamente para que un envío capturado no pueda reproducirse indefinidamente.

import crypto from "node:crypto";

export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((part) => part.trim().split("=")),
  );
  const timestamp = Number(parts.t);
  if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(parts.v1),
  );
}

Rotar el secreto

Al rotar, el secreto anterior sigue siendo válido durante 24 horas, así que puedes desplegar el nuevo valor sin perder los eventos que ya estaban en camino. Durante ese periodo acepta la firma si coincide con cualquiera de los dos.

Responder

Responde 2xx en cuanto hayas guardado el evento, y haz el trabajo pesado después. Cortamos la petición a los 10 segundos, y una respuesta lenta cuenta como fallida.

El mismo evento puede llegar más de una vez. Usa id como clave de deduplicación: es el mismo valor en todos los reintentos y en todos tus endpoints.

Reintentos

Un envío fallido se reintenta hasta 6 veces con espera creciente (10 s, 1 min, 5 min, 30 min, 2 h, 6 h). Después queda marcado como agotado y puedes reenviarlo a mano desde el panel o con POST /api/v1/webhook-deliveries/{id}/replay. Un endpoint que falla de forma continuada se desactiva solo; volver a activarlo reinicia el contador.

Endpoints de gestión

Todo lo siguiente requiere el permiso webhooks:manage. El endpoint pertenece al entorno de la clave que lo crea, de modo que una clave de pruebas nunca puede tocar el endpoint de producción.

  • GET /api/v1/webhook-endpoints
  • POST /api/v1/webhook-endpoints con url (https obligatorio) y enabledEvents
  • PATCH /api/v1/webhook-endpoints/{id} para cambiar la suscripción o desactivarlo
  • DELETE /api/v1/webhook-endpoints/{id}
  • POST /api/v1/webhook-endpoints/{id}/rotate-secret
  • GET /api/v1/webhook-deliveries para el historial de envíos

Crear el primero

curl -X POST https://decaya.es/api/v1/webhook-endpoints \
  -H "Authorization: Bearer $DECAYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://erp.example.com/hooks/decaya",
    "enabledEvents": ["document.generated", "document.modified"]
  }'

La respuesta incluye el secret con el que verificar las firmas. También puedes hacerlo sin escribir código desde Ajustes → Webhooks.

DeCAya llega muy pronto: tu DeCA listo en segundos

Conocer DeCAya →

Fuentes oficiales

La información de esta página se basa en la normativa publicada por el Ministerio de Transportes y Movilidad Sostenible y el Boletín Oficial del Estado.

Última revisión:

Consultar MinisterioConsultar BOE