Configuración de la API de Integración

¿Para qué sirve esto?

Esta guía explica cómo conectar tu formulario a un sistema externo (como un CRM, una plataforma de marketing o un webhook personalizado) para que cada vez que alguien envíe el formulario, los datos se envíen automáticamente a la URL que especifiques.

Configuración de la Integración

En el Constructor de Formularios, abre el paso Configuración de Integración (opcional). Verás un solo campo:

URL de API de Integración
Introduce la dirección web completa (URL) del punto final (endpoint) que debe recibir los datos del envío del formulario. La URL debe comenzar con http:// o https://.

Requisitos y límites:

  • Máximo 500 caracteres.
  • Debe ser una URL válida y accesible públicamente.
  • Por seguridad, se bloquean direcciones localhost e IPs privadas (ej. 127.0.0.1, 169.254.169.254).
  • La petición caduca a los 5 segundos si tu endpoint no responde.

Cómo configurarlo:

  1. Abre tu formulario en el Constructor de Formularios.
  2. Haz clic en el paso Configuración de Integración (opcional) en la barra lateral.
  3. Pega la URL de tu webhook en el campo URL de API de Integración.
  4. Haz clic en Guardar (o simplemente cambia de paso — los cambios se guardan automáticamente).

Nota: El enlace «mostrar información sobre la integración» junto al campo no muestra ayuda adicional por el momento. Es una limitación conocida que se mejorará en una futura actualización.

Qué Ocurre al Enviar un Formulario

Una vez guardada la URL de Integración y activado el formulario, cada envío dispara una petición POST desde nuestro servidor a tu URL. El cuerpo de la petición es un objeto JSON con la siguiente estructura:

Ejemplo de Payload JSON

{
  "event": "form_submission",
  "form_id": "evt_abc123def456",
  "submitted_at": "2026-07-19T14:32:10.123Z",
  "answers": {
    "email_abc123": "juan.perez@ejemplo.com",
    "first_name_def456": "Juan",
    "last_name_ghi789": "Pérez",
    "company_jkl012": "Empresa SA",
    "newsletter_opt_in_mno345": true,
    "interests_pqr678": "Marketing, Ventas"
  },
  "data": {
    "fields": [
      { "id": "abc123", "label": "Email", "code": "email", "value": "juan.perez@ejemplo.com" },
      { "id": "def456", "label": "Nombre", "code": "first_name", "value": "Juan" },
      { "id": "ghi789", "label": "Apellido", "code": "last_name", "value": "Pérez" },
      { "id": "jkl012", "label": "Empresa", "code": "company", "value": "Empresa SA" },
      { "id": "mno345", "label": "Suscribirse al boletín", "code": "newsletter_opt_in", "value": true },
      { "id": "pqr678", "label": "Intereses", "code": "interests", "value": [{ "name": "Marketing" }, { "name": "Ventas" }] }
    ]
  }
}

Explicación de los Campos

Campo Tipo Descripción
event string Siempre "form_submission". Identifica el tipo de evento.
form_id string ID único del formulario/evento que se envió.
submitted_at string (ISO 8601) Fecha y hora exacta del envío en UTC.
answers object Un mapa plano de clave-valor con todas las respuestas. Las claves siguen el patrón <código_campo>_<id_campo> (ej. email_abc123). Los valores se procesan para fácil lectura: textos/números → string; checkboxes → true/false; select/multi-select → lista separada por comas con los nombres de las opciones.
data.fields array El array original de campos del formulario tal como se guardó en el envío, con valores en bruto (objetos para selects, arrays para multi-selects, etc.). Úsalo si necesitas la estructura completa.

Cómo se Aplanan las Respuestas (answers)

El objeto answers está diseñado para facilitar el parseo en webhooks, Zapier, Make o código personalizado:

  • Texto, Número, Email, Teléfono, URL, Área de texto → valor como string.
  • Checkbox / Interruptortrue o false.
  • Select (simple) → el name de la opción seleccionada como string.
  • Multi-select / Grupo de checkboxes → lista separada por comas de los name de las opciones (ej. "Marketing, Ventas").
  • Campos ocultos / de sistema → incluidos si están presentes.

Detalles Técnicos (Para Tu Desarrollador)

Si vas a reenviar esto a un desarrollador que construirá el endpoint receptor, comparte estos detalles:

  • Método: POST
  • Content-Type: application/json
  • User-Agent: <NombreApp>-Webhook/1.0 (ej. EventReg-Webhook/1.0)
  • Timeout: 5 segundos (la petición se aborta si no hay respuesta)
  • Reintentos: Ninguno — los fallos se registran en logs pero no se reintentan automáticamente.
  • Hosts permitidos: Solo endpoints HTTPS públicos. Se bloquean localhost, 127.0.0.1, 0.0.0.0 y la IP de metadatos AWS (169.254.169.254).
  • Respuesta: Cualquier código 2xx se considera éxito. Códigos distintos a 2xx se registran como advertencia.

Cómo Probar tu Integración

  1. Guarda la URL de Integración en el Constructor de Formularios.
  2. Activa el formulario (clic en Revisar y ActivarActivar).
  3. Abre la vista previa o el enlace público del formulario y envía una entrada de prueba.
  4. Revisa los logs de tu receptor de webhook: deberías ver un payload JSON con la estructura descrita arriba.

Preguntas Frecuentes

¿Por qué mi webhook no recibió nada?

  • Verifica que el formulario esté Activo (no en estado Creado o Borrador).
  • Confirma que la URL es correcta y usa https://.
  • Asegúrate de que tu endpoint acepte POST con application/json.
  • Revisa los logs de tu servidor por timeouts de 5 segundos o IPs bloqueadas.

¿Puedo usar un túnel local (ngrok, Cloudflare Tunnel) para pruebas? Sí, mientras la URL pública HTTPS resuelva hacia tu túnel. http:// está permitido pero se recomienda encarecidamente https://.

¿Qué pasa si mi endpoint devuelve error? El sistema registra el código de estado HTTP y continua. No hay reintento automático. Puedes reenviar el formulario manualmente o implementar un mecanismo de reintento en tu lado.

¿Puedo enviar a varias URLs? Actualmente solo se admite una URL de Integración por formulario. Si necesitas distribuir a varios sistemas, usa un middleware (Zapier, Make, o tu propio endpoint relay).

¿Se envían las subidas de archivos? Los campos de subida de archivos no se incluyen en el payload del webhook. Solo los metadatos del campo aparecen en data.fields. Los archivos reales permanecen en el almacenamiento de la plataforma.