Webhooks

Envie todas as submissões para um endereço seu, em JSON, no momento em que chegam.

Um POST por resposta

Enviado assim que a resposta é guardada, sem deixar o respondente à espera.

Uma estrutura JSON estável

Nomes de tipo públicos e IDs de campo permanentes, para que mudar o nome de uma pergunta nunca quebre o seu código.

10 segundos, uma tentativa

O Fillio espera dez segundos pelo seu endpoint e não volta a tentar depois disso.

Ativar um webhook

Abra o formulário, vá ao separador Definições e ative Webhook. Cole o endereço que deve receber as submissões; o Fillio guarda-o pouco depois de parar de escrever e confirma-o no ecrã. Cada formulário tem um endereço, e desativar o interruptor limpa-o.

O endereço tem de ser HTTPS

O Fillio só contacta endereços que comecem por https://. Um endereço http:// é aceite pelo campo das definições, mas nunca é contactado, pelo que um webhook que parece estar guardado não entrega nada.

Os endereços que apontam para dentro de uma rede privada também são recusados: qualquer anfitrião em 10.x, 127.x, 169.254.x, 172.16-31.x ou 192.168.x, qualquer endereço IPv6 e qualquer nome que seja localhost ou termine em .local ou .internal. O seu endpoint tem de estar acessível a partir da Internet pública.

O pedido

Um POST com um corpo em JSON. Acompanham-no quatro cabeçalhos.

CabeçalhoDescrição
Content-Type: application/jsonO corpo é sempre JSON.
User-Agent: Fillio Webhooks/1.0Identifica quem chama como sendo o Fillio, o que é útil quando um endpoint escuta vários serviços.
X-Fillio-Event: FORM_RESPONSEO nome do evento. FORM_RESPONSE é o único valor que o Fillio envia atualmente.
X-Fillio-Event-IdUm UUID novo para esta entrega, repetido como eventId no corpo.

O payload

Um envelope que descreve o evento e um objeto data que descreve a resposta.

{
  "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
      }
    ]
  }
}
PropriedadeDescrição
eventIdUm ID único para esta entrega.
eventTypeSempre FORM_RESPONSE.
createdAtQuando a resposta foi submetida, como marca temporal ISO 8601 em UTC.
data.responseIdO ID da resposta guardada.
data.formIdO ID do formulário, o mesmo que aparece na sua ligação pública.
data.formNameO título do formulário em texto simples, sem qualquer formatação.
data.fieldsUma entrada por pergunta respondida.

Dentro de fields

Cada entrada tem quatro propriedades, e uma pergunta com opções tem uma quinta.

PropriedadeDescrição
keyO ID permanente da pergunta. Sobrevive a todas as alterações à redação, por isso faça a correspondência por ele e não pela etiqueta.
labelA pergunta tal como está escrita no editor.
typeO tipo de pergunta, retirado da lista abaixo.
valueA resposta, no formato em que essa pergunta a guarda.
optionsApenas em perguntas com opções: o ID e o texto de cada opção, para que possa converter uma resposta de volta numa etiqueta.

Só chegam as perguntas respondidas

Uma pergunta em que o respondente não tocou está ausente do array em vez de ser enviada com um valor vazio, e uma pergunta ocultada pela lógica condicional nunca chega a aparecer. Procure cada resposta pela sua key em vez de depender da posição ou de um número fixo de entradas.

As respostas de escolha trazem IDs, não etiquetas

A resposta de uma lista pendente ou de uma escolha múltipla é o ID da opção escolhida, e a resposta de uma caixa de verificação, seleção múltipla ou ordenação é um array de IDs de opções. Resolva-os face à lista options da mesma entrada. Uma resposta de ordenação mantém a ordem pela qual o respondente colocou os itens.

A opção Outro

Quando um respondente escreve numa caixa Outro, o valor não é um ID de opção, mas sim o texto __OTHER__: seguido do que escreveu. Retire esse prefixo para ler a resposta.

"value": "__OTHER__:Heard about it from a friend"

Ficheiros e assinaturas

A resposta de um carregamento de ficheiro é uma ligação de transferência para o ficheiro no armazenamento do Fillio. Uma resposta de assinatura é um data URL PNG em base64, que pode guardar ou apresentar diretamente.

Tipos de campo

O tipo é um nome público estável, por isso uma alteração dentro do Fillio nunca chega à sua integração. Tudo o que o Fillio não conseguir mapear chega como INPUT_TEXT.

TipoPerguntaValor
INPUT_TEXTResposta CurtaTexto
TEXTAREAResposta LongaTexto
INPUT_EMAILE-mailTexto
INPUT_PHONE_NUMBERNúmero de TelefoneTexto
INPUT_NUMBERNúmeroO número como texto, exatamente como foi escrito
INPUT_LINKLigaçãoTexto
INPUT_DATEDataUma data, no formato YYYY-MM-DD
INPUT_TIMEHoraUma hora, no formato HH:MM em relógio de 24 horas
DROPDOWNLista SuspensaUm ID de opção
MULTIPLE_CHOICEBotão de opçãoUm ID de opção
CHECKBOXESCaixa de SeleçãoUm array de IDs de opções
MULTI_SELECTSeleção MúltiplaUm array de IDs de opções
RATINGAvaliação por EstrelasUm número
LINEAR_SCALEEscala LinearUm número
RANKINGClassificaçãoUm array de IDs de opções, pela ordem do respondente
FILE_UPLOADUpload de ArquivoUma ligação de transferência
SIGNATUREAssinaturaUm data URL PNG em base64

Se o seu endpoint não responder

O Fillio espera dez segundos. Um tempo esgotado, um erro de ligação ou qualquer estado fora do intervalo 2xx conta como entrega falhada, e fica por aí: não há nova tentativa nem fila para repetir.

A resposta em si nunca é afetada. É guardada antes de o pedido ser feito e permanece no seu painel, faça o seu endpoint o que fizer, pelo que o painel continua a ser o registo completo mesmo que uma entrega se perca.

Não existe assinatura

O Fillio não assina o pedido nem envia qualquer segredo partilhado, por isso o corpo por si só não prova de onde veio. Se o seu endpoint precisar de ter a certeza, dê-lhe um endereço que só o utilizador conheça: um caminho ou uma query string longos e impossíveis de adivinhar. Trate como não fiável tudo o que chegar a outro lado.

Cada entrega traz o seu próprio ID de evento, tanto no cabeçalho X-Fillio-Event-Id como no corpo. Registar os que já tratou é a forma mais simples de tornar o seu endpoint seguro para ser chamado duas vezes.

Dica

Aponte o webhook para qualquer endpoint de inspeção de pedidos e submeta o seu próprio formulário uma vez. Verá o payload exato que o seu formulário produz, com os seus próprios IDs de campo. É a forma mais rápida de escrever o mapeamento do seu lado.