Intégrations

Envoyer les réponses de formulaire via des webhooks

Les webhooks sont le moyen universel de YeetForm pour envoyer les données de réponse n'importe où : votre propre backend, une synchronisation de base de données ou une autre plateforme d'automatisation. Ajoutez un point de terminaison HTTPS dans l'onglet Intégrations d'un formulaire, et YeetForm envoie un payload JSON signé par POST à chaque nouvelle réponse, avec un secret que vous pouvez vérifier via HMAC-SHA256. Les envois échoués sont automatiquement réessayés. Cette page détaille le format exact de la signature, la structure du payload et le calendrier des tentatives pour que vous puissiez construire un récepteur en toute confiance.

Mise en place

1

Ajouter un point de terminaison

Collez l'URL de votre point de terminaison HTTPS dans l'onglet Intégrations du formulaire, sous Webhooks, et cliquez sur Ajouter un webhook. YeetForm génère un secret de signature (whsec_...) pour ce point de terminaison.

2

Vérifier la signature

Chaque envoi porte un en-tête X-YeetForm-Signature : t=<horodatage unix>,v1=<hmac-sha256 hex de `${t}.${body}`>. Vérifiez-le par rapport au corps brut de la requête avant de faire confiance au payload.

import { createHmac, timingSafeEqual } from "crypto";

function verify(secret, signatureHeader, rawBody) {
  const [tPart, v1Part] = signatureHeader.split(",");
  const timestamp = tPart.split("=")[1];
  const signature = v1Part.split("=")[1];

  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  const a = Buffer.from(signature, "hex");
  const b = Buffer.from(expected, "hex");
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}
3

Lire le payload

Les POST se déclenchent sur response.created (et webhook.test via le bouton de test manuel), avec l'id du formulaire, l'id de la réponse, le nombre de réponses et les réponses indexées par id de champ, plus un tableau fields avec le libellé de chaque champ.

{
  "event": "response.created",
  "form_id": "<uuid>",
  "form_title": "Customer Feedback",
  "response_id": "<uuid>",
  "response_count": 42,
  "answers": { "fld_x": "..." },
  "submitted_at": "2026-09-13T12:00:00.000Z"
}
4

Gérer les nouvelles tentatives

Une réponse non-2xx (ou un délai dépassé) déclenche une nouvelle tentative : immédiatement, puis après 30 secondes, puis après 5 minutes - 3 tentatives au total avant que YeetForm marque l'envoi comme échoué. Les redirections ne sont pas suivies, pointez donc l'URL directement vers votre point de terminaison.

Astuces

  • Les libellés des champs figurent dans le tableau fields du payload (id, label, type) - pas besoin de coder en dur les id de champs en aval.
  • Chaque réponse porte un response_id stable - utilisez-le comme clé d'idempotence, car un envoi réessayé reprend le même id.
  • Un envoi échoué est réessayé 3 fois au total (immédiatement, 30 s, 5 min) avant d'être marqué échoué - une réponse 2xx est requise pour compter comme un succès, les redirections ne sont pas suivies.

Créez votre formulaire par IA en quelques secondes

Commencer gratuitement

FAQ

Qu'est-ce qui déclenche un webhook ?+
response.created se déclenche à chaque nouvelle réponse ; webhook.test se déclenche quand vous cliquez sur le bouton de test de l'intégration, pour vérifier votre point de terminaison avant la mise en production.
Comment savoir qu'une requête vient vraiment de YeetForm ?+
Vérifiez l'en-tête X-YeetForm-Signature par rapport au secret de votre point de terminaison avec HMAC-SHA256 sur `${horodatage}.${corps_brut}` - voir l'extrait de vérification ci-dessus.
Que se passe-t-il si mon point de terminaison est indisponible ?+
YeetForm réessaie 3 fois au total : immédiatement, après 30 secondes, puis après 5 minutes. Si les trois échouent, l'envoi est marqué échoué et n'est plus réessayé.
Puis-je ajouter des en-têtes personnalisés ?+
Oui, lors de la configuration du webhook vous pouvez définir des en-têtes personnalisés - ils sont fusionnés, mais les en-têtes Content-Type et X-YeetForm-* propres à YeetForm l'emportent toujours en cas de conflit.