Eventos y webhooks
Lo que cambia, en orden, y avisos firmados a tus sistemas.
En esta página
Actualizado el 1 de enero de 1970
Privacidad y analítica
Utilizamos cookies técnicas necesarias y, solo si das tu consentimiento, analítica y pixels de marketing para mejorar la web y medir campañas.
Lo que cambia, en orden, y avisos firmados a tus sistemas.
Actualizado el 1 de enero de 1970
Cada cambio que se hace en Nömad (por la pantalla, la API, el MCP o Nödo) deja un evento ordenado: <entidad>.<verbo>, quién lo hizo, dónde y qué registros tocó (sus ids y los nombres de los campos, nunca sus valores). Los eventos se leen con events.list desde un cursor, o se reciben en tu sistema con un webhook firmado. El registro guarda 30 días.
{
"id": "1042",
"object": "event",
"type": "works.tasks.update",
"schema_version": 1,
"operation": "works.tasks.update",
"plane": "client",
"occurred_at": "2026-10-26T12:00:00Z",
"actor": {
"kind": "person",
"id": "…",
"client": null
},
"door": "web",
"scope": "brand",
"brand_id": "…",
"workspace_id": "…",
"data": {
"object_ids": [
"…"
],
"changed_fields": [
"title",
"status"
]
},
"request_id": "…"
}Solo ves los eventos de lo que puedes leer, con las mismas claves que los registros. Para los datos, lee el registro con su operación.
events.list con after = el último id que leíste; next_cursor es el siguiente. Avanza aunque no haya nada que puedas ver.from_now: true da el cursor actual: tómalo antes de copiar el estado y sigue desde él.cursor_expired: tu cursor es más viejo que el registro. Vuelve a copiar el estado.workspace.webhooks.create): una dirección HTTPS pública y los tipos que quieres: *, uno exacto o un prefijo como works.*. Puedes limitarlo a unas marcas.whsec_…) se muestra una sola vez. Si lo rotas, el anterior sigue firmando 24 h.Nomad-Signature: t=<unix>,v1=<hex>, un HMAC-SHA256 de <t>.<cuerpo>. Rechaza las firmas de más de 300 s. También llegan Nomad-Event-Id, Nomad-Event-Type, Nomad-Delivery-Id y Nomad-Delivery-Attempt.Nomad-Event-Id para no procesar dos veces el mismo evento: un reintento o un reenvío lo repiten.import { createHmac, timingSafeEqual } from 'node:crypto'
// header = request.headers['nomad-signature'], body = the raw request body
export function verify(body, header, secret, now = Math.floor(Date.now() / 1000)) {
const pairs = header.split(',').map((part) => part.split('='))
const t = Number(pairs.find(([key]) => key === 't')?.[1])
if (!t || Math.abs(now - t) > 300) return false
const expected = createHmac('sha256', secret).update(`${t}.${body}`).digest()
return pairs.filter(([key]) => key === 'v1').some(([, value]) => {
const given = Buffer.from(value, 'hex')
return given.length === expected.length && timingSafeEqual(given, expected)
})
}