Automatizaciones y webhooks
Automatizaciones
Las automatizaciones permiten que nuzur llame a tus sistemas cuando tus datos cambian — por ejemplo, cuando el status de un registro pasa a PUBLISHED, nuzur puede enviar un webhook firmado a tu API para que reaccione (enviar una notificación, lanzar un proceso, sincronizar otro servicio).
La propiedad clave: las automatizaciones solo se disparan con cambios aprobados. Toda modificación de datos en nuzur pasa por una solicitud de cambio, y una automatización solo se ejecuta cuando la solicitud es aprobada y aplicada. Nadie — ni un compañero de equipo, ni un agente de IA — puede disparar tu webhook sin que ese cambio haya pasado por revisión. Tu sistema receptor solo ve cambios que una persona aprobó.
Crear una automatización
Abre el Gestor de Datos de tu proyecto y cambia a la pestaña Automatizaciones en el panel izquierdo (junto a Entidades), luego haz clic en Nueva automatización.
Una automatización tiene:
- Nombre — una etiqueta legible, p. ej.
Episodio publicado → puntuación. - Entidad — la tabla a observar.
- Operación — disparar en
create,update,deleteoany. - Condiciones (opcional) — una o más reglas de "cuando el campo X cambia a Y", combinadas con AND (todas deben cumplirse en el mismo cambio; por defecto) u OR (basta con una). La transición de un solo campo es el patrón más común para automatizaciones de ciclo de vida: un registro se crea como borrador y después se actualiza a
PUBLISHED. Para campos enum, el campo "cambia a" ofrece directamente las opciones del enum. Una condición solo se dispara con una transición real — una actualización que deja el campo en un valor que ya tenía no cuenta. Si necesitas algo más complejo que transiciones con AND/OR, deja las condiciones vacías y filtra en el lado receptor — tu endpoint puede recibir eventos que no le interesan; revisa el payload. - URL del webhook — a dónde nuzur envía el evento. Debe ser
httpsy accesible públicamente (se rechazan direcciones privadas o locales).
Al crear la automatización, nuzur te muestra el secreto de firma exactamente una vez. Cópialo y guárdalo en la configuración de tu servicio receptor — sirve para verificar que las entregas realmente vienen de nuzur, y no se puede recuperar después.
Si el secreto se pierde o pudo haberse filtrado, abre la automatización y haz clic en Rotar secreto (o usa la herramienta MCP rotateAutomationSecret). Se genera un secreto nuevo que se muestra una vez; el anterior deja de firmar nuevas entregas en aproximadamente un minuto. No hay solapamiento de secretos, así que actualiza la configuración de tu receptor inmediatamente después de rotar — las entregas que fallen durante el cambio se reintentan automáticamente con la nueva firma.
También puedes gestionar automatizaciones desde tus herramientas de IA a través del servidor MCP de nuzur — las herramientas createAutomation, testAutomation y listAutomationEvents reflejan todo lo descrito aquí.
Lo que recibe tu endpoint
nuzur envía por POST un cuerpo JSON con esta forma:
{
"event_uuid": "5f0c2f6e-6a41-4e6e-9b1a-2f8f6f2f7c11",
"sent_at": "2026-07-13T18:04:05Z",
"automation": { "uuid": "…", "name": "Episodio publicado → puntuación" },
"project_uuid": "…",
"entity": { "uuid": "…", "identifier": "episode" },
"operation": "update",
"record": {
"keys": { "uuid": "d3b1…" },
"changes": {
"status": { "old": "DRAFT", "new": "PUBLISHED" }
}
},
"change_request": {
"uuid": "…",
"title": "Publicar episodio 12",
"approved_by_uuid": "…",
"applied_at": "2026-07-13T18:04:01Z"
}
}
record.keysidentifica la fila;record.changeslleva valores antiguos/nuevos en actualizaciones; las creaciones llevanrecord.values; las eliminaciones solokeys.change_requestte dice quién lo aprobó y cuándo — una procedencia que ninguna herramienta de CDC a nivel de base de datos puede darte.- Las entregas de prueba (del botón Enviar entrega de prueba) llevan además
"test": true.
Reglas de entrega:
- Cualquier respuesta 2xx cuenta como éxito. Responde rápido y haz tu trabajo de forma asíncrona — la petición expira a los 10 segundos.
- La entrega es al-menos-una-vez y sin orden garantizado. Puede haber duplicados; deduplica por
event_uuid. - Las entregas fallidas se reintentan con backoff (1m, 5m, 30m, 2h, 12h) y después se marcan como muertas. Puedes inspeccionarlas y reintentarlas desde el registro de Entregas de cada automatización.
- No se siguen redirecciones.
Verificar la firma
Cada entrega incluye dos cabeceras:
X-Nuzur-Event-Id: 5f0c2f6e-6a41-4e6e-9b1a-2f8f6f2f7c11
X-Nuzur-Signature: sha256=8f2c1a…
La firma es el HMAC-SHA256 en hexadecimal del cuerpo crudo de la petición, calculado con tu secreto de firma. Verifícala antes de confiar en el payload:
- Lee los bytes crudos del cuerpo — antes de cualquier parseo JSON o middleware. Un JSON re-serializado no coincidirá.
- Calcula
HMAC-SHA256(cuerpo_crudo, secreto)y codifícalo en hexadecimal. - Compara contra el valor de la cabecera (tras el prefijo
sha256=) usando una comparación de tiempo constante. - Rechaza lo que no coincida y deduplica por
event_uuid. Opcionalmente rechaza eventos cuyosent_attenga más de unos minutos para acotar la ventana de replay.
Go
func verifyNuzurSignature(rawBody []byte, header, secret string) bool {
sig, ok := strings.CutPrefix(header, "sha256=")
if !ok {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(rawBody)
expected := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(sig))
}
func handler(w http.ResponseWriter, r *http.Request) {
rawBody, _ := io.ReadAll(http.MaxBytesReader(w, r.Body, 1<<20))
if !verifyNuzurSignature(rawBody, r.Header.Get("X-Nuzur-Signature"), os.Getenv("NUZUR_SIGNING_SECRET")) {
http.Error(w, "invalid signature", http.StatusUnauthorized)
return
}
// parsea rawBody, deduplica por event_uuid y haz tu trabajo async
w.WriteHeader(http.StatusOK)
}
Node
import crypto from "node:crypto";
import express from "express";
const app = express();
// captura el cuerpo CRUDO — express.json() por sí solo lo re-parsea y la
// firma no coincidirá
app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }));
function verifyNuzurSignature(rawBody, header, secret) {
if (!header?.startsWith("sha256=")) return false;
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const received = header.slice("sha256=".length);
return (
expected.length === received.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))
);
}
app.post("/hooks/nuzur", (req, res) => {
if (!verifyNuzurSignature(req.rawBody, req.get("X-Nuzur-Signature"), process.env.NUZUR_SIGNING_SECRET)) {
return res.status(401).send("invalid signature");
}
// deduplica por req.body.event_uuid y haz tu trabajo async
res.sendStatus(200);
});
Prueba antes de publicar
Usa el botón Enviar entrega de prueba (o la herramienta MCP testAutomation) para enviar a tu endpoint un evento sintético completamente firmado — el payload tiene exactamente la forma de una entrega real con valores de ejemplo y "test": true. Puedes construir y verificar tu receptor de extremo a extremo antes de que exista ninguna solicitud de cambio real.
Monitorizar entregas
Cada automatización tiene un registro de Entregas: cada evento con su estado (pending, delivering, delivered, failed, dead), número de intentos, último error y el payload congelado. Los eventos fallidos y muertos se pueden reintentar manualmente.
Dos cosas a tener en cuenta:
- Si un endpoint falla repetidamente, la automatización se marca como requiere atención tras varios eventos muertos consecutivos y deja de dispararse — la configuración se conserva y aparece un aviso en la pestaña de Automatizaciones. Arregla el endpoint y guarda la automatización para reactivarla.
- Si un cambio de esquema elimina la entidad o el campo de condición que una automatización observa, también se marca como requiere atención al publicar, en lugar de dispararse incorrectamente.