Webhooks

7 min de lectura16
Copiar para la IA:

El webhook entrega cada respuesta de un formulario, en el momento en que llega, a una dirección tuya: un flujo en Zapier, Make o n8n, o el sistema de tu empresa. En Clínica Vitta, en Bogotá, cada ficha de anamnesis enviada llega directo al sistema de agendamiento, sin que nadie copie datos a mano.

Dónde está

Formularios › (formulario) › pestaña Integraciones › tarjeta "Webhooks". La pestaña solo aparece para el dueño de la cuenta: un webhook envía respuestas hacia afuera, y esa es una decisión de quien responde por la cuenta. Cada formulario admite hasta 3 webhooks; con los tres creados, el botón Nuevo webhook queda deshabilitado.

Crear un webhook

  1. Haz clic en Nuevo webhook.
  2. En Dirección que recibe las respuestas, pega la URL de tu flujo o sistema. Debe empezar con https:// y ser una dirección pública de internet. Una dirección de red interna, o una URL con usuario y contraseña incluidos, se rechaza.
  3. Haz clic en Crear webhook.

Nace Activado: la próxima respuesta del formulario ya se envía.

El secreto aparece una sola vez

Justo después de crearlo, la tarjeta muestra el Secreto del webhook (empieza con whsec_). Haz clic en Copiar, guárdalo en tu sistema y solo entonces haz clic en Ya lo copié. No se vuelve a mostrar: la lista enseña solo los últimos caracteres ("termina en 4f2a").

¿Perdiste el secreto, o alguien que lo conocía salió del equipo? Usa Cambiar secreto en el menú de la fila. El secreto actual deja de funcionar al instante y el nuevo aparece una vez, igual que antes. Hasta que lo actualices en el sistema que recibe, las entregas llegan con una firma que no reconoce.

Qué llega al destino

Con cada respuesta, un POST con cuerpo JSON y cuatro encabezados:

  • X-WiseData-Signature — la firma, en el formato sha256=….
  • X-WiseData-Timestamp — el momento del envío, en segundos.
  • X-WiseData-Delivery — el id de la entrega.
  • X-WiseData-Event — submission.created (respuesta) o ping (prueba).

Una ficha de anamnesis de Clínica Vitta llega así:

{
  "id": "9b2f6c1e-4d7a-4f0b-8a3e-2c5d1e7f9a10",
  "event": "submission.created",
  "created_at": "2026-10-10T14:32:05-03:00",
  "form": { "id": "Xk29fQa7Lm", "title": "Ficha de anamnesis" },
  "submission": {
    "number": 37,
    "submitted_at": "2026-10-10T14:32:04-03:00",
    "answers": [
      { "field_id": "f_a1b2c3d4e5f6", "label": "Nombre completo", "type": "short_text", "value": "María Gómez" },
      { "field_id": "f_b2c3d4e5f6g7", "label": "Correo", "type": "email", "value": "maria@ejemplo.com" },
      { "field_id": "f_c3d4e5f6g7h8", "label": "Documento de identidad", "type": "document", "value": "0000000000" },
      { "field_id": "f_d4e5f6g7h8i9", "label": "¿Te has hecho algún procedimiento estético?", "type": "yes_no", "value": "Sí" },
      { "field_id": "f_e5f6g7h8i9j0", "label": "Valor del paquete", "type": "currency", "value": "COP 350,000", "currency": "COP", "amount": "350000" },
      { "field_id": "f_f6g7h8i9j0k1", "label": "Firma", "type": "signature", "value": null, "signed": true },
      { "field_id": "f_g7h8i9j0k1l2", "label": "Origen", "type": "hidden", "value": "instagram" }
    ]
  }
}
  • id — el id de la entrega, igual al encabezado X-WiseData-Delivery. Es el mismo en un reenvío: úsalo para no procesar la misma respuesta dos veces.
  • number — la "Respuesta n.º" del formulario, la misma del panel, del correo y del PDF.
  • answers — solo lo que la persona respondió de verdad. La pregunta que la lógica ocultó no viene; los bloques de texto y las secciones tampoco. El campo oculto (origen, campaña) sí viene.
  • value — el texto como aparece en el panel, en el idioma del formulario (la etiqueta de la opción, "Sí"/"No"). Una pregunta sin respuesta viene como null.
  • Dinero — además del value con formato, vienen currency (el código de la moneda) y amount (el número con punto decimal). Para sumar o guardar en una base de datos, usa amount.
  • Firma — viene solo "signed": true, nunca la imagen.
  • field_id — no cambia cuando renombras la pregunta. Mapea por field_id, no por label.

Comprobar la firma en tu sistema

Es lo que garantiza que la llamada vino de Forms y no de alguien que descubrió tu dirección. Quien desarrolla el sistema que recibe hace esto:

  1. Lee el cuerpo exactamente como llegó, antes de convertir el JSON. Reformatearlo cambia los bytes y la cuenta no cuadra.
  2. Arma el texto: el valor de X-WiseData-Timestamp + . + el valor de X-WiseData-Delivery + . + el cuerpo.
  3. Calcula el HMAC-SHA256 de ese texto con el secreto, en hexadecimal, y compáralo con lo que viene después de sha256= en X-WiseData-Signature.
  4. Rechaza llamadas con hora antigua (unos minutos bastan) y los id de entrega que ya procesaste.

Responde con un código 2xx en hasta 10 segundos. Si el procesamiento es pesado, guarda la respuesta, devuelve 200 y procesa después.

Probar antes de la primera respuesta

En el menú de la fila, Enviar prueba llama al destino al instante con el evento ping, number nulo y respuestas de ejemplo: cada pregunta del formulario con el valor "Ejemplo" (o la primera opción, en las de selección), el dinero como 1250.50 (o 1250 en monedas sin centavos, como el peso colombiano) y la firma como firmada. Sirve para armar el mapeo en Zapier, Make o n8n antes de que llegue una respuesta real. El resultado aparece al instante: "El destino respondió 200: la prueba llegó." Si la prueba falla no se repite, y no cuenta para la desactivación automática.

Historial de entregas y reenvío

Ver entregas abre las entregas de los últimos 30 días: Cuándo, Qué se envió (Prueba, "Respuesta n.º 37" o "Respuesta eliminada"), Resultado (Entregada, Reintentando o Falló, con el motivo, el código HTTP y el tiempo) e Intentos. El contenido enviado no se guarda; el historial muestra qué pasó con cada entrega.

Una entrega de respuesta que falló tiene el botón Reenviar, mientras la respuesta exista. El reenvío usa el mismo id de entrega, para que tu sistema reconozca la repetición. La prueba no se reenvía: envía otra.

Cuando el destino falla

  • Sin conexión, demora, o respuesta 408, 429 o 5xx — Forms lo intenta de nuevo solo: al instante, después de 1 minuto, 5 minutos, 30 minutos y 2 horas (5 intentos). Mientras tanto la entrega aparece como Reintentando.
  • Otro código, incluida una redirección (3xx) — falla definitivamente, porque repetir no arregla un error de configuración. Forms no sigue redirecciones: registra la dirección final.
  • 20 fallos seguidos — el webhook se desactiva solo, aparece como Desactivado por fallos y el dueño recibe un correo. Corrige el destino y usa Activar: el conteo empieza de cero. Las respuestas que llegan con el webhook desactivado no generan entrega.

En el mismo menú están Cambiar dirección (cambia solo la URL, sin activar ni desactivar), Desactivar/Activar y Eliminar webhook, que elimina también el historial de entregas y no tiene vuelta atrás.

Crear, cambiar, eliminar, cambiar el secreto, probar y reenviar quedan registrados en Registros, sin la dirección y sin el secreto.

Adónde ir después

  • Google Sheets (colección Integraciones) — cada respuesta como una fila de hoja de cálculo, sin programar.
  • Documento, dirección, teléfono y montos (colección Campos) — cómo el campo de dinero guarda la moneda y el valor.
  • Exportar las respuestas en CSV o XLSX (colección Respuestas) — para llevarte todo el historial de una vez.
  • Registros (colección Seguridad y privacidad) — quién cambió los webhooks y cuándo.

En resumen: en la pestaña Integraciones del formulario, el dueño crea hasta 3 webhooks con dirección https pública; el secreto aparece una vez y le permite a tu sistema comprobar la firma de cada POST; el JSON trae el número de la respuesta y las respuestas visibles, con currency y amount en el campo de dinero; Forms reintenta solo los fallos temporales, desactiva el webhook tras 20 fallos seguidos y te deja reenviar desde el historial de 30 días.

¿Te resultó útil este artículo?