Recibir webhooks

Drometra le avisa a tu sistema con un POST HTTPS cuando pasa algo en tu empresa, como un pedido nuevo o una entrega hecha. Los avisos siguen el formato de Standard Webhooks y van firmados.

1

Prepara el destino

Necesitas una dirección HTTPS al puerto 443 con un nombre público, sin IP directa, credenciales en la URL ni redirecciones. Drometra no publica IPs fijas de salida, así que la seguridad está en verificar la firma. Los destinos los crea un administrador con verificación en dos pasos.

2

Crea el destino y guarda el secreto

Elige qué eventos quieres recibir. La respuesta trae el secreto de firma (whsec_…) una sola vez: guárdalo en tu gestor de secretos.

POST /v1/webhooks/endpoints
curl -X POST "https://api.drometra.com/v1/webhooks/endpoints" \
  -H "Authorization: Bearer $DROMETRA_TOKEN" \
  -H "x-tenant-id: $DROMETRA_TENANT" \
  -H "idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://empresa.cl/webhooks/drometra",
    "description": "ERP: entregas",
    "eventTypes": ["field.stop.delivered", "field.stop.failed"]
  }'
EventoCuándo llegaEn data
distribution.order.createdSe creó un pedido.orderId, reference, state
distribution.order.cancelledSe canceló un pedido.orderId, reference, state
routing.plan.approvedSe aprobó un plan de recorridos.routePlanId, previewId, routeCount, unassignedCount
field.route.assignedUna ruta quedó asignada a un vehículo.routeId, routePlanId, vehicleRouteId, serviceDate, fleetVehicleId, stopCount, orderIds
field.route.cancelledSe canceló una ruta.routeId, serviceDate
field.route.startedEl conductor empezó la ruta.routeId
field.stop.deliveredSe entregó en una parada.routeId, stopId, orderId, reference, outcomeAt, evidenceCount
field.stop.failedUna entrega no se pudo hacer.routeId, stopId, orderId, reference, outcomeAt, evidenceCount
field.route.finishedTerminó la ruta.routeId, finishedAt, summary
3

Verifica la firma de cada aviso

Cada aviso trae webhook-id, webhook-timestamp y webhook-signature. La firma es un HMAC SHA-256 de id.timestamp.cuerpo, calculado sobre el cuerpo tal cual llegó, antes de leer el JSON.

verificar
import { createHmac, timingSafeEqual } from "node:crypto";

export function verificar(secreto, headers, cuerpoCrudo) {
  const id = headers["webhook-id"], ts = headers["webhook-timestamp"];
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // ±5 minutos
  const clave = Buffer.from(secreto.replace(/^whsec_/, ""), "base64");
  const esperada = createHmac("sha256", clave).update(`${id}.${ts}.${cuerpoCrudo}`).digest();
  return headers["webhook-signature"].split(" ").some((parte) => {
    const dada = Buffer.from(parte.replace(/^v1,/, ""), "base64");
    return dada.length === esperada.length && timingSafeEqual(dada, esperada);
  });
}

El cuerpo lleva identificadores, referencias, estados, conteos y fechas, nunca datos personales. Si necesitas más, consúltalo en la API.

cuerpo
{
  "id": "5f0c1e2a-…",
  "type": "field.stop.delivered",
  "timestamp": "2026-10-21T14:03:11.000Z",
  "tenantId": "7a1d0c44-…",
  "version": 1,
  "data": {
    "routeId": "…", "stopId": "…", "orderId": "…",
    "reference": "1043", "outcomeAt": "2026-10-21T14:02:58.000Z", "evidenceCount": 2
  }
}
4

Responde rápido y procesa una sola vez

Responde 2xx en menos de 10 segundos y haz el trabajo después. Si no, Drometra reintenta a los 5 segundos, 5 minutos, 30 minutos, 2 horas, 5 horas, 10 horas y 10 horas: ocho intentos en unas 28 horas. La entrega es al menos una vez y sin orden garantizado, así que guarda los webhook-id procesados y descarta los repetidos.

Tras 20 entregas fallidas seguidas el destino se desactiva solo; reactívalo cuando tu receptor esté sano.

5

Prueba, revisa y rota

Envía un evento de prueba (webhook.test) con POST /v1/webhooks/endpoints/{id}/test. Cada entrega queda 30 días en el registro (GET /v1/webhooks/deliveries), con cada intento y su resultado, y se puede reintentar a mano. El secreto se rota con POST /v1/webhooks/endpoints/{id}/secrets: durante la gracia, de hasta 7 días, cada aviso lleva dos firmas y vale cualquiera.

Ver las rutas de webhooks