Webhook
Invii ogni risposta a un indirizzo suo, in JSON, nel momento in cui arriva.
Un POST per risposta
Inviato appena la risposta viene salvata, senza far attendere chi risponde.
Una struttura JSON stabile
Nomi di tipo pubblici e ID di campo permanenti, così rinominare una domanda non rompe mai il suo codice.
10 secondi, un tentativo
Fillio attende dieci secondi il suo endpoint e poi non riprova.
Attivare un webhook
Apra il modulo, vada alla scheda Impostazioni e attivi Webhook. Incolli l'indirizzo che deve ricevere gli invii; Fillio lo salva poco dopo che ha smesso di scrivere e glielo conferma a schermo. Ogni modulo porta un solo indirizzo, e disattivando l'interruttore lo cancella.
L'indirizzo deve essere HTTPS
Fillio chiama solo indirizzi che iniziano con https://. Un indirizzo http:// viene accettato dal campo delle impostazioni ma non viene mai chiamato, quindi un webhook che sembra salvato non consegnerà nulla, in silenzio.
Anche gli indirizzi che puntano dentro una rete privata vengono rifiutati: qualsiasi host su 10.x, 127.x, 169.254.x, 172.16-31.x o 192.168.x, qualsiasi indirizzo IPv6 e qualsiasi nome che sia localhost o termini in .local o .internal. Il suo endpoint deve essere raggiungibile dalla rete pubblica.
La richiesta
Un POST con un corpo JSON. Lo accompagnano quattro header.
| Intestazione | Descrizione |
|---|---|
| Content-Type: application/json | Il corpo è sempre JSON. |
| User-Agent: Fillio Webhooks/1.0 | Identifica il chiamante come Fillio, utile quando un endpoint ascolta più servizi. |
| X-Fillio-Event: FORM_RESPONSE | Il nome dell'evento. FORM_RESPONSE è l'unico valore che Fillio invia oggi. |
| X-Fillio-Event-Id | Un UUID nuovo per questa consegna, ripetuto come eventId nel corpo. |
Il payload
Una busta che descrive l'evento e un oggetto data che descrive la risposta.
{
"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
}
]
}
}| Proprietà | Descrizione |
|---|---|
| eventId | Un ID univoco per questa consegna. |
| eventType | Sempre FORM_RESPONSE. |
| createdAt | Quando la risposta è stata inviata, come timestamp ISO 8601 in UTC. |
| data.responseId | L'ID della risposta salvata. |
| data.formId | L'ID del modulo, lo stesso che compare nel suo link pubblico. |
| data.formName | Il titolo del modulo come testo semplice, senza alcuna formattazione. |
| data.fields | Una voce per ogni domanda con risposta. |
Dentro fields
Ogni voce porta quattro proprietà, e una domanda con opzioni ne porta una quinta.
| Proprietà | Descrizione |
|---|---|
| key | L'ID permanente della domanda. Sopravvive a ogni modifica del testo, quindi faccia corrispondere questo invece dell'etichetta. |
| label | La domanda così come è scritta nell'editor. |
| type | Il tipo di domanda, preso dall'elenco qui sotto. |
| value | La risposta, nella forma in cui quella domanda la salva. |
| options | Solo sulle domande con opzioni: l'ID e il testo di ogni opzione, così può ricondurre una risposta alla sua etichetta. |
Arrivano solo le domande con risposta
Una domanda che chi risponde non ha toccato è assente dall'array invece di essere inviata come valore vuoto, e una domanda nascosta dalla logica condizionale non compare affatto. Cerchi ogni risposta tramite la sua key invece di affidarsi alla posizione o a un numero fisso di voci.
Le risposte a scelta portano ID, non etichette
La risposta a un menu a tendina o a una scelta multipla è l'ID dell'opzione scelta, mentre la risposta a caselle di controllo, selezione multipla o classifica è un array di ID di opzione. Li risolva confrontandoli con l'elenco options della stessa voce. Una risposta di tipo classifica conserva l'ordine in cui chi risponde ha messo gli elementi.
L'opzione Altro
Quando chi risponde scrive in un campo Altro, il valore non è l'ID di un'opzione ma il testo __OTHER__: seguito da quello che ha digitato. Rimuova quel prefisso per leggere la risposta.
"value": "__OTHER__:Heard about it from a friend"File e firme
La risposta a un caricamento file è un link di download al file nello spazio di archiviazione di Fillio. La risposta a una firma è un data URL PNG in base64, che può salvare o mostrare direttamente.
Tipi di campo
Il tipo è un nome pubblico stabile, quindi un cambiamento interno a Fillio non raggiunge mai la sua integrazione. Tutto ciò che Fillio non riesce a mappare arriva come INPUT_TEXT.
| Tipo | Domanda | Valore |
|---|---|---|
| INPUT_TEXT | Risposta breve | Testo |
| TEXTAREA | Risposta lunga | Testo |
| INPUT_EMAIL | Testo | |
| INPUT_PHONE_NUMBER | Numero di telefono | Testo |
| INPUT_NUMBER | Numero | Il numero come testo, esattamente come è stato digitato |
| INPUT_LINK | Link | Testo |
| INPUT_DATE | Data | Una data, nel formato YYYY-MM-DD |
| INPUT_TIME | Ora | Un orario, nel formato HH:MM su 24 ore |
| DROPDOWN | Menu a tendina | Un ID di opzione |
| MULTIPLE_CHOICE | Pulsanti radio | Un ID di opzione |
| CHECKBOXES | Caselle di controllo | Un array di ID di opzione |
| MULTI_SELECT | Selezione multipla | Un array di ID di opzione |
| RATING | Valutazione a stelle | Un numero |
| LINEAR_SCALE | Scala lineare | Un numero |
| RANKING | Classifica | Un array di ID di opzione, nell'ordine scelto da chi risponde |
| FILE_UPLOAD | Caricamento file | Un link di download |
| SIGNATURE | Firma | Un data URL PNG in base64 |
Se il suo endpoint non risponde
Fillio attende dieci secondi. Un timeout, un errore di connessione o qualsiasi stato fuori dall'intervallo 2xx conta come consegna fallita, e finisce lì: non c'è alcun nuovo tentativo né una coda da cui riprovare.
La risposta in sé non ne risente mai. Viene salvata prima che la richiesta parta e resta nella sua dashboard qualunque cosa faccia il suo endpoint, così la dashboard rimane il registro completo anche se una consegna va persa.
Non c'è una firma
Fillio non firma la richiesta e non invia alcun segreto condiviso, quindi il corpo da solo non prova da dove arriva. Se il suo endpoint deve esserne certo, gli dia un indirizzo che conosce solo lei: un percorso o una query string lunghi e non indovinabili. E consideri non attendibile tutto ciò che arriva altrove.
Ogni consegna porta il proprio ID evento, sia nell'header X-Fillio-Event-Id sia nel corpo. Registrare quelli che ha già gestito è il modo più semplice per rendere il suo endpoint sicuro anche se chiamato due volte.
Punti il webhook a un qualsiasi endpoint di ispezione delle richieste e invii una volta il suo stesso modulo. Vedrà il payload esatto che il suo modulo produce, con dentro i suoi ID di campo: il modo più rapido per scrivere la mappatura dalla sua parte.