Webhooks
Transmettez chaque envoi vers une adresse à vous, en JSON, dès qu'il arrive.
Un POST par réponse
Envoyé dès que la réponse est enregistrée, sans faire attendre le répondant.
Une structure JSON stable
Des noms de type publics et des identifiants de champ permanents : renommer une question ne casse jamais votre code.
10 secondes, une seule tentative
Fillio attend votre endpoint pendant dix secondes et ne réessaie pas ensuite.
Activer un webhook
Ouvrez le formulaire, allez dans l'onglet Paramètres et activez Webhook. Collez l'adresse qui doit recevoir les envois ; Fillio l'enregistre un instant après que vous avez fini de taper et vous le confirme à l'écran. Chaque formulaire porte une seule adresse, et désactiver l'interrupteur l'efface.
L'adresse doit être en HTTPS
Fillio n'appelle que les adresses commençant par https://. Une adresse http:// est acceptée par le champ des paramètres mais n'est jamais appelée : un webhook qui semble enregistré ne livrera donc rien, sans rien dire.
Les adresses qui pointent à l'intérieur d'un réseau privé sont refusées elles aussi : tout hôte en 10.x, 127.x, 169.254.x, 172.16-31.x ou 192.168.x, toute adresse IPv6, et tout nom valant localhost ou se terminant par .local ou .internal. Votre endpoint doit être joignable depuis l'internet public.
La requête
Un POST avec un corps JSON. Quatre en-têtes l'accompagnent.
| En-tête | Description |
|---|---|
| Content-Type: application/json | Le corps est toujours du JSON. |
| User-Agent: Fillio Webhooks/1.0 | Identifie l'appelant comme Fillio, ce qui est utile quand un même endpoint écoute plusieurs services. |
| X-Fillio-Event: FORM_RESPONSE | Le nom de l'événement. FORM_RESPONSE est aujourd'hui la seule valeur envoyée par Fillio. |
| X-Fillio-Event-Id | Un UUID tout neuf pour cette livraison, repris comme eventId dans le corps. |
Le payload
Une enveloppe qui décrit l'événement, et un objet data qui décrit la réponse.
{
"eventId": "8f2c1d7a-4b09-4e5c-9a13-6d0f8b2e77c4",
"eventType": "FORM_RESPONSE",
"createdAt": "2026-08-26T09:14:22.481Z",
"data": {
"responseId": "Qh3Rk9wZm1sVtY7cN2xP",
"formId": "7bTn4Kq2Wx",
"formName": "Workshop signup",
"createdAt": "2026-08-26T09:14:22.481Z",
"fields": [
{
"key": "V1StGXR8_Z5jdHi6B-myT",
"label": "Full name",
"type": "INPUT_TEXT",
"value": "Mira Kaya"
},
{
"key": "kM4pQz7LxAe2Rn0BsTvUw",
"label": "Which session?",
"type": "MULTIPLE_CHOICE",
"value": "c9XbNf3JdQ",
"options": [
{ "id": "c9XbNf3JdQ", "text": "Morning" },
{ "id": "eR2mYt8KpL", "text": "Afternoon" }
]
},
{
"key": "zA6cWn1FyH4tXd9QrLbEs",
"label": "How likely are you to recommend us?",
"type": "LINEAR_SCALE",
"value": 9
}
]
}
}| Propriété | Description |
|---|---|
| eventId | Un identifiant unique pour cette livraison. |
| eventType | Toujours FORM_RESPONSE. |
| createdAt | La date d'envoi de la réponse, sous forme d'horodatage ISO 8601 en UTC. |
| data.responseId | L'identifiant de la réponse enregistrée. |
| data.formId | L'identifiant du formulaire, le même que celui qui apparaît dans son lien public. |
| data.formName | Le titre du formulaire en texte brut, sans aucune mise en forme. |
| data.fields | Une entrée par question répondue. |
À l'intérieur de fields
Chaque entrée porte quatre propriétés, et une question à options en porte une cinquième.
| Propriété | Description |
|---|---|
| key | L'identifiant permanent de la question. Il survit à toutes les modifications de formulation : faites la correspondance là-dessus plutôt que sur le libellé. |
| label | La question telle qu'elle est écrite dans l'éditeur. |
| type | Le type de la question, pris dans la liste ci-dessous. |
| value | La réponse, dans la forme sous laquelle cette question l'enregistre. |
| options | Uniquement sur les questions à options : l'identifiant et le texte de chaque option, pour retransformer une réponse en libellé. |
Seules les questions répondues arrivent
Une question à laquelle le répondant n'a pas touché est absente du tableau plutôt qu'envoyée avec une valeur vide, et une question masquée par la logique conditionnelle n'apparaît jamais. Retrouvez chaque réponse par sa key plutôt que de vous fier à sa position ou à un nombre d'entrées fixe.
Les réponses à choix portent des identifiants, pas des libellés
Une réponse de liste déroulante ou de choix multiple est l'identifiant de l'option choisie, et une réponse de cases à cocher, de sélection multiple ou de classement est un tableau d'identifiants d'options. Résolvez-les avec la liste options de la même entrée. Une réponse de classement conserve l'ordre dans lequel le répondant a placé les éléments.
L'option Autre
Quand un répondant écrit dans un champ Autre, la valeur n'est pas un identifiant d'option mais le texte __OTHER__: suivi de ce qu'il a saisi. Retirez ce préfixe pour lire la réponse.
"value": "__OTHER__:Heard about it from a friend"Fichiers et signatures
Une réponse Envoi de fichier est un lien de téléchargement vers le fichier dans le stockage de Fillio. Une réponse de signature est une data URL PNG en base64, que vous pouvez enregistrer ou afficher directement.
Types de champ
Le type est un nom public stable : un changement interne à Fillio n'atteint donc jamais votre intégration. Tout ce que Fillio ne sait pas faire correspondre arrive en INPUT_TEXT.
| Type | Question | Valeur |
|---|---|---|
| INPUT_TEXT | Réponse courte | Du texte |
| TEXTAREA | Réponse longue | Du texte |
| INPUT_EMAIL | Du texte | |
| INPUT_PHONE_NUMBER | Numéro de téléphone | Du texte |
| INPUT_NUMBER | Nombre | Le nombre en texte, exactement tel qu'il a été saisi |
| INPUT_LINK | Lien | Du texte |
| INPUT_DATE | Date | Une date, au format YYYY-MM-DD |
| INPUT_TIME | Heure | Une heure, au format HH:MM sur 24 heures |
| DROPDOWN | Liste déroulante | Un identifiant d'option |
| MULTIPLE_CHOICE | Bouton radio | Un identifiant d'option |
| CHECKBOXES | Case à cocher | Un tableau d'identifiants d'options |
| MULTI_SELECT | Sélection multiple | Un tableau d'identifiants d'options |
| RATING | Notation par étoiles | Un nombre |
| LINEAR_SCALE | Échelle linéaire | Un nombre |
| RANKING | Classement | Un tableau d'identifiants d'options, dans l'ordre du répondant |
| FILE_UPLOAD | Envoi de fichier | Un lien de téléchargement |
| SIGNATURE | Signature | Une data URL PNG en base64 |
Si votre endpoint ne répond pas
Fillio attend dix secondes. Un dépassement de délai, une erreur de connexion ou tout statut hors de la plage 2xx compte comme une livraison échouée, et l'affaire s'arrête là : aucune nouvelle tentative, aucune file d'attente à rejouer.
La réponse elle-même n'est jamais affectée. Elle est enregistrée avant l'envoi de la requête et reste dans votre tableau de bord quoi que fasse votre endpoint : le tableau de bord demeure donc l'enregistrement complet, même si une livraison se perd.
Il n'y a pas de signature
Fillio ne signe pas la requête et n'envoie aucun secret partagé : le corps à lui seul ne prouve donc pas d'où il vient. Si votre endpoint doit en être certain, donnez-lui une adresse que vous seul connaissez : un chemin ou une chaîne de requête longue et indevinable. Et considérez comme non fiable tout ce qui arrive ailleurs.
Chaque livraison porte son propre identifiant d'événement, à la fois dans l'en-tête X-Fillio-Event-Id et dans le corps. Enregistrer ceux que vous avez déjà traités est le moyen le plus simple de rendre votre endpoint sûr à appeler deux fois.
Pointez le webhook vers n'importe quel service d'inspection de requêtes et envoyez votre propre formulaire une fois. Vous verrez le payload exact que produit votre formulaire, avec vos propres identifiants de champ dedans. C'est le moyen le plus rapide d'écrire le mapping de votre côté.