Envía los envíos a un webhook y reintenta lo que tu receptor se perdió
Añade un endpoint de webhook a un formulario, verifica la firma en tu receptor y usa Reintentar entregas fallidas tras una caída. Qué reintenta FormFlow por sí solo y qué no reenviará.
Esta publicación se tradujo automáticamente. Lee el original en inglés

Un webhook envía cada envío aceptado a una URL tuya, en cuestión de segundos, para que un contacto pueda llegar a tu CRM o a tu propio código sin esperar a un resumen por correo. Los webhooks forman parte de FormFlow desde la v1.0.0. Este tutorial añade un endpoint, muestra qué recibe tu receptor y cómo comprobarlo, y luego cubre lo que importa el día en que tu receptor está caído: qué reintenta FormFlow por sí solo y cómo reenviar el resto con Reintentar entregas fallidas.
Qué necesitas
Un receptor que controles y que acepte un POST con un cuerpo JSON. Su dirección debe ser https y debe resolverse solo a direcciones públicas. El panel rechaza cualquier otra cosa al guardar, así que una dirección localhost no funciona, y un túnel es la forma habitual de probar.
Añade el endpoint
Abre el formulario en el panel y ve a la pestaña Entrega.
En Puntos finales de webhook, pulsa Agregar punto final.
Deja Enviar como en FormFlow JSON (firmado). La otra opción, Mensaje de Slack, toma la URL de un webhook entrante de Slack.
Pega la dirección de tu receptor en URL de punto final y deja Entregando activado.
Guarda el formulario. Una notificación titulada Copie sus secretos de firma de webhook ahora muestra la URL y el secreto de cada endpoint nuevo. Permanece en pantalla hasta que la descartes, y dice que los secretos no se vuelven a mostrar. Guarda el secreto en tu gestor de secretos. Para obtener uno nuevo, elimina y vuelve a añadir el endpoint.
Pulsa Enviar prueba en la fila del endpoint. Obtienes Prueba entregada, o La entrega de la prueba falló con el texto de error de tu propio receptor. Primero hay que guardar la fila, y el botón está limitado a 20 entregas de prueba por hora.
Después envía un envío real y ábrelo en el panel. Su tabla Solicitudes de entrega enumera cada destino al que se le debe ese envío, con un estado de Pendiente, Arrendado, Entregado o Muerto, el número de intentos, el ID de entrega y el último error.
Qué recibe tu receptor
Un POST por cada envío que no es spam. El cuerpo es un documento JSON pequeño, y lo acompañan tres cabeceras. Esta es la forma, con valores de ejemplo:
{
"id": "SUBMISSION_UUID",
"form": { "id": "FORM_UUID", "name": "Contact Us" },
"submitted_at": "2026-10-08T09:00:00+00:00",
"data": { "name": "Ada Lovelace", "email": "ada@example.com" }
}X-FormFlow-Timestamp es la hora del intento, en segundos.
X-FormFlow-Signature-256 es sha256= seguido de un HMAC-SHA256 de la marca de tiempo, un punto y el cuerpo sin procesar, con el secreto del endpoint como clave.
X-FormFlow-Delivery-Id identifica la entrega. Es el mismo en cada reintento.
Verifica la firma antes de fiarte de una solicitud, sobre el cuerpo sin procesar y no sobre una copia recodificada. Una versión en PHP, tal como la da la documentación de la API de FormFlow:
function formflow_verify(string $rawBody, string $timestamp, string $signature, string $secret): bool
{
if (abs(time() - (int) $timestamp) > 300) {
return false;
}
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
return hash_equals($expected, $signature);
}
Qué reintenta FormFlow por sí solo
FormFlow espera hasta 10 segundos una respuesta. Cualquier respuesta 2xx cuenta como entregada. Un tiempo de espera agotado, una conexión cortada, un 408, un 429 o una respuesta 5xx se reintenta, hasta seis intentos en total, con esperas de 10 segundos, 1 minuto, 5 minutos, 30 minutos y 2 horas entre ellos. Cualquier otra respuesta, incluidas un 3xx o un 4xx, se trata como un rechazo permanente y no se reintenta automáticamente. FormFlow no sigue redirecciones, así que un endpoint que responde con una redirección cuenta como fallido. Apunta el endpoint a su dirección final.
Si un endpoint sigue pidiendo reintentos y se queda sin intentos, FormFlow desactiva Entregando para él y avisa por correo a los propietarios del equipo. Una entrega que se ha quedado sin intentos aparece como Muerto. El panel de control también sigue listando un webhook cuyo reenvío está apagado, con su racha de fallos, hasta que una entrega tiene éxito.
Reintenta lo que tu receptor se perdió
Antes de la v1.33, cada envío perdido necesitaba su propio Reintentar ahora. Ahora una pulsación cubre un endpoint. La versión está en el Registro de cambios. El orden importa:
Arregla primero el receptor. Cada entrega fallida recibe un intento más, así que un reintento contra un receptor que sigue roto solo vuelve a fallar.
En la pestaña Entrega, comprueba el interruptor Entregando del endpoint. Si FormFlow lo apagó, actívalo y guarda el formulario. Reintentar un endpoint apagado se rechaza con "Active Entregando y guarde el formulario, luego vuelva a intentarlo."
Pulsa Reintentar entregas fallidas en la fila del endpoint y confirma. El diálogo dice que cada entrega fallida que todavía se pueda enviar vuelve a ponerse en cola, con su ID de entrega y su carga originales.
Una notificación te dice cuántas se pusieron en cola. Una pulsación pone en cola como máximo 500. Si quedan más, te indica que pulses de nuevo.
Abre un envío y revisa su tabla Solicitudes de entrega. El número de intentos ha subido y el estado debería llegar a Entregado.
Si cambias la URL, el secreto o el formato de un endpoint, empieza de cero. Las entregas hechas antes del cambio no se reenvían, y desde la v1.35.1 el panel de control ya no cuenta los fallos antiguos contra la nueva dirección. Apagar y encender un endpoint sin cambiarlo conserva su historial de fallos.
Límites que conviene conocer
Un endpoint nuevo recibe solo los envíos que llegan después de configurarlo. No se le envían los que ya tienes.
El spam no se reenvía.
Reintentar entregas fallidas reenvía solo las entregas que todavía se pueden enviar, y solo al endpoint tal como está ahora.
La entrega es al menos una vez. Tu receptor debe tolerar una repetición.