Validar una petición de webhook y responder con JSON en n8n
Un webhook es una URL que recibe una petición HTTP y la convierte en datos para un workflow. En este tutorial construirás un endpoint pequeño para recibir un posible lead, comprobar sus campos y devolver una respuesta JSON clara. El resultado es útil para formularios, scripts o integraciones que necesiten saber inmediatamente si n8n aceptó o rechazó la petición.
Prueba documentada: n8n 2.36.7 con Node.js 24.19.0, el 31 de agosto de 2026. En una instancia local aislada se comprobaron las respuestas HTTP 200 y 400, la normalización de los datos válidos y la ausencia de datos del lead en la respuesta inválida. El workflow quedó inactivo al terminar. No se conectaron servicios externos.
Resultado que obtendrás
- Una URL de webhook
POSTque aceptanombre,emailytema. - Una validación en un nodo Code que normaliza el correo y devuelve los errores sin procesar datos inválidos.
- Una respuesta
200para un registro válido y400para uno inválido, siempre en JSON.
Antes de comenzar
- Una instancia de n8n Cloud o self-hosted con los nodos Webhook, Code, IF (condición) y Respond to Webhook disponibles.
- PowerShell 7 o posterior para ejecutar el ejemplo con
Invoke-RestMethod. Comprueba la versión con$PSVersionTable.PSVersion; Windows PowerShell 5.1 no admite los parámetros usados aquí. - Un payload de prueba sin datos personales. Este artículo usa
Ana Demo <ana@example.com>. - No necesitas credenciales de Google, un proveedor de correo ni un servicio de pago.
El nodo Webhook tiene una URL de prueba y otra de producción. La URL de prueba solo responde mientras el editor está escuchando una ejecución; la de producción requiere que el workflow esté activo. Usa primero la de prueba y no copies una URL real a un artículo o captura.
Flujo completo
Webhook «Recibir datos» (POST /flujoteca-intake-v1)
|
v
Code «Validar y normalizar»
|
v
IF «¿Datos válidos?» ---- no ----> «Responder 400»
|
sí
v
«Responder 200»
El contrato canónico del flujo usa ok, data y errores en la salida del nodo de validación. La rama válida devuelve los campos normalizados dentro de lead; la rama inválida devuelve solo mensajes de validación, nunca el payload ni los datos normalizados.
Paso 1: crear el webhook
- Crea un workflow nuevo y añade un nodo Webhook.
- En HTTP Method, selecciona
POST. - En Path, escribe
flujoteca-intake-v1. - En Respond, selecciona Using "Respond to Webhook" Node. Así el status code y el cuerpo se controlan al final del flujo.
- Para una prueba local, deja la autenticación en None y no expongas la URL fuera de tu entorno de prueba. Para un endpoint real, configura Basic Auth, Header Auth o JWT y guarda el secreto solo en la credencial de n8n.
- Pulsa Listen for test event y conserva la URL de prueba que muestra n8n solo en tu sesión. No la publiques.
El cuerpo suele estar disponible como $json.body cuando la petición llega al nodo Webhook. El código del siguiente paso acepta también $json como respaldo para que puedas reutilizarlo con datos fijados en el editor.
Paso 2: validar y normalizar los datos
Conecta un nodo Code al Webhook. Déjalo en Run Once for All Items y pega este código. El try/catch evita que un cuerpo de texto que no sea JSON detenga el workflow con un error poco claro.
const raw = $json.body ?? $json;
let body = raw;
if (typeof raw === 'string') {
try {
body = JSON.parse(raw);
} catch {
return [{
json: {
ok: false,
errores: ['El cuerpo no contiene JSON válido'],
},
}];
}
}
if (!body || typeof body !== 'object' || Array.isArray(body)) {
return [{
json: {
ok: false,
errores: ['El cuerpo debe ser un objeto JSON'],
},
}];
}
const data = {
nombre: String(body.nombre ?? '').trim(),
email: String(body.email ?? '').trim().toLowerCase(),
tema: String(body.tema ?? '').trim(),
};
const errores = [];
if (data.nombre.length < 2) errores.push('nombre debe tener al menos 2 caracteres');
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
errores.push('email no tiene un formato válido');
}
if (data.tema.length < 2) errores.push('tema debe tener al menos 2 caracteres');
if (errores.length > 0) {
return [{ json: { ok: false, errores } }];
}
return [{ json: { ok: true, data, errores: [] } }];
La salida válida tiene la forma { ok: true, data, errores: [] }; la inválida, { ok: false, errores } y no incluye data. La expresión regular es una comprobación básica, no una prueba de que el buzón exista. En una aplicación real también conviene aplicar límites de longitud y una protección contra abuso antes de enviar el dato a otros sistemas.
Paso 3: separar las ramas
Añade el nodo IF «¿Datos válidos?» después de Validar y normalizar:
- Primera condición: Boolean.
- Valor:
={{ $json.ok }}. - Operador: is true.
Conecta la salida verdadera al nodo Responder 200 y la salida falsa a Responder 400. Comprueba el nombre de cada salida en el lienzo: una conexión invertida puede devolver 200 para datos rechazados.
Paso 4: responder al cliente
En la rama verdadera, el nodo Responder 200 usa esta configuración:
-
Respond With:
JSON. -
Response Code:
200. -
Response Body:
={{ { ok: true, lead: $json.data, message: "Validación correcta" } }}
Si la versión de tu editor muestra el cuerpo como texto, usa JSON.stringify({ ok: true, lead: $json.data, message: 'Validación correcta' }) como expresión. No escribas el correo de prueba directamente en el nodo.
En la rama falsa, el nodo Responder 400 usa esta configuración:
-
Respond With:
JSON. -
Response Code:
400. -
Response Body:
={{ { ok: false, errores: $json.errores, message: "Revisa los campos enviados" } }}
Guarda el workflow. Para usar la URL de producción más adelante, activa o publica el workflow según la interfaz de tu instancia y vuelve a comprobar que la autenticación está configurada.
Cómo comprobar que funciona
El registro anterior confirma las ramas válida e inválida mediante una URL local con el workflow publicado temporalmente. Los siguientes pasos permiten repetir la comprobación con la URL de prueba del editor; esa modalidad debe comprobarse en tu instancia. Con el webhook en modo de escucha, sustituye <URL_DE_PRUEBA> por la URL que n8n muestra en tu editor y ejecuta una sola petición:
$payload = @{
nombre = 'Ana Demo'
email = 'ana@example.com'
tema = 'Webhooks en n8n'
} | ConvertTo-Json
$respuesta = Invoke-RestMethod `
-Method Post `
-Uri '<URL_DE_PRUEBA>' `
-ContentType 'application/json' `
-Body $payload `
-SkipHttpErrorCheck `
-StatusCodeVariable codigoHttp
$codigoHttp
$respuesta | ConvertTo-Json -Depth 5
Debes observar el código HTTP 200 y un objeto con ok: true, lead.email: "ana@example.com" y lead.nombre: "Ana Demo". Antes de la segunda petición, pulsa de nuevo Listen for test event y comprueba la URL de prueba. Cambia el email del bloque inicial a 'no-es-un-correo' y ejecuta el bloque completo una sola vez para reconstruir el JSON. El resultado esperado es código 400, ok: false, un arreglo errores y ningún campo lead. -SkipHttpErrorCheck permite inspeccionar el cuerpo de la respuesta 400; no convierte el error en éxito ni omite la validación TLS. Si la primera petición llega al Webhook pero no obtiene respuesta, revisa que ambos caminos terminen en Respond to Webhook.
No pases a la URL de producción hasta revisar el resultado y eliminar cualquier dato de prueba. Si usas una herramienta que reintenta automáticamente, desactiva los reintentos durante esta comprobación para no crear varias ejecuciones.
Errores habituales
Recibes 404 o n8n no muestra la petición
- Causa probable: usaste el path equivocado, la URL de prueba cambió o el editor no estaba escuchando.
- Comprobación: copia de nuevo la URL de prueba visible en el nodo Webhook y pulsa Listen for test event.
- Corrección mínima: vuelve a enviar una única petición al endpoint recién generado. La URL de producción solo funciona con el workflow activo.
Recibes 401 o 403
- Causa probable: la autenticación del Webhook está activa y el cliente no envía el encabezado esperado.
- Comprobación: revisa el tipo de autenticación configurado y prueba únicamente con un valor de ejemplo.
- Corrección mínima: configura la credencial en n8n y usa el método de autenticación documentado; no pegues el secreto en el código ni en una captura.
Todos los datos caen en la rama inválida
- Causa probable: el cliente envía un nombre de campo diferente (
correoen vez deemail) o un cuerpo no JSON. - Comprobación: abre la entrada del nodo Webhook y verifica si los campos están dentro de
body. - Corrección mínima: ajusta el payload al contrato
nombre,email,tema; conserva la validación en el servidor.
El endpoint devuelve 200 aunque falte un campo
- Causa probable: las conexiones del nodo IF están invertidas o el Respond de error tiene código
200. - Comprobación: ejecuta la petición inválida y revisa la ruta resaltada en el lienzo.
- Corrección mínima: conecta
trueal Respond200,falseal Respond400y guarda otra vez.
La petición es rechazada por tamaño
- Causa probable: el payload supera el límite documentado del Webhook.
- Comprobación: mide el cuerpo y elimina archivos o campos innecesarios.
- Corrección mínima: envía metadatos pequeños y almacena archivos en un sistema apropiado; el Webhook de n8n documenta un máximo de 16 MB.
Seguridad y privacidad
- Un endpoint sin autenticación debe considerarse público. Úsalo solo en una prueba local o añade autenticación antes de ponerlo en producción.
- No registres tokens, contraseñas ni el cuerpo completo si contiene datos personales. El ejemplo usa
example.comy no representa un buzón real. - Valida siempre en n8n aunque el cliente ya valide. La validación del navegador no es un control de seguridad.
- Define límites de longitud, protección contra repetición y un mecanismo de rate limiting en el proxy o infraestructura cuando el endpoint vaya a Internet.
- No reflejes en la respuesta campos que no necesitas. Si procesas datos personales, documenta la finalidad, retención y quién tiene acceso.