Webhooks

Configure notificações de eventos em tempo real

Webhooks

Um webhook é a entrega de dados a um endpoint quando um evento ocorre. No nosso caso, esse evento é o envio de uma resposta a uma pesquisa. Os webhooks são destinados a usuários avançados com conhecimento de programação.

Como conectar

Para configurar webhooks, acesse a aba Integrações → Webhooks e clique em Conectar.

Baixe a versão em markdown da seção "Webhooks" para usar no ChatGPT ou outros LLMs:

Interface de configuração de webhooks

Passo 1: Acessar integrações

Para configurar webhooks, acesse a aba Integrações → Webhooks e clique em Conectar.

Passo 2: Formulário de configuração do webhook

Uma tela será aberta onde você deverá inserir o nome do webhook, a URL de callback e o tipo de requisição.

Passo 3: Testar o webhook

Você pode testar o webhook usando https://webhook.site

Passo 4: Visualizar registros

Ou visualizando os registros na interface do SurveyNinja.

Configurações do webhook

O formulário de configuração do webhook possui os seguintes parâmetros:

Parâmetro Descrição
Nome Um nome personalizado para identificar o webhook na lista
URL A URL do seu endpoint. O SurveyNinja envia uma requisição POST para ela a cada nova resposta de pesquisa
Cabeçalhos Cabeçalhos HTTP personalizados no formato "chave: valor". Enviados com cada requisição e duplicados no campo headers do corpo do payload para facilitar o registro
Habilitado Alternância de atividade. Um webhook desabilitado não envia requisições, mas mantém todas as configurações

Token secreto via cabeçalho

Adicione um cabeçalho Authorization: Bearer seu-segredo — seu servidor poderá verificar que a requisição veio genuinamente do SurveyNinja.

Quando os webhooks são disparados

No SurveyNinja, os webhooks são disparados quando uma resposta de pesquisa é enviada. Este é o principal evento que você pode rastrear.

Evento: Resposta de pesquisa

O webhook é disparado toda vez que um respondente envia uma resposta à sua pesquisa, fornecendo notificações em tempo real de novas respostas.

Entrega automática

O webhook é enviado automaticamente assim que uma resposta de pesquisa é recebida

Formato do payload

O SurveyNinja envia uma requisição POST com um corpo JSON. A estrutura completa do corpo da requisição está descrita abaixo.

Campos raiz do payload

Campo Tipo Descrição
headers object Cabeçalhos configurados no webhook. Duplicados no corpo para facilitar o registro e a depuração
extra_params object / array Variáveis ocultas e tags UTM enviadas durante a pesquisa. Array vazio [] se não houver variáveis
promo_code string / null Código promocional usado durante a pesquisa, ou null
log_id int ID do registro de entrega deste webhook
score_all int Pontuação máxima possível para toda a pesquisa. 0 se a pontuação não estiver configurada
score_earned int Pontuação total obtida pelo respondente
score_percent float / null Percentual do resultado: (score_earned / score_all) × 100, arredondado para 1 casa decimal. null se score_all = 0
scores object Resumo de pontuação: campos user, max e by_question — um mapa { "uuid": int | null }
{question_uuid} object Resposta à pergunta com este UUID. Cada pergunta da pesquisa tem uma chave de nível superior separada

Campos do objeto de pergunta

Cada pergunta no payload é um objeto identificado pelo UUID da pergunta. Todos os tipos de perguntas compartilham os seguintes campos comuns:

Campo Tipo Descrição
title string Texto da pergunta (título do widget)
type string Tipo de widget: choiceSingle, choiceMultiple, rating, matrix e outros.
question_uuid / uuid string UUID da pergunta (duplicado dentro do objeto)
results object / array Resposta do respondente. O formato depende do tipo de widget — veja a seção abaixo
score_count int / null Pontuação obtida para esta pergunta. null se a pontuação não se aplica a este tipo
score_max int / null Pontuação máxima para esta pergunta. null se a pontuação não se aplica
is_correct_question bool / null Correção geral da resposta: true — correta, false — incorreta, null — não aplicável
other string Texto da opção 'Outro', se selecionada (para widgets de escolha). String vazia se não selecionada
inline_group_id string / null UUID do grupo de perguntas, se a pergunta pertencer a um grupo
inline_group_title string / null Nome do grupo de perguntas
is_inline_group_child bool true se a pergunta estiver dentro de um grupo

Formato de results por tipo de widget

O campo results tem um formato diferente dependendo do tipo de pergunta.

choiceSingle, choiceMultiple, yesno, dropdown

Array de opções selecionadas. Cada elemento contém o texto da opção, a pontuação e o indicador de correção.

{ "results": [ { "result": "Option A", "score": 10, "is_correct": true } ] }

choiceMedia

Array de opções de mídia selecionadas. O campo result contém a URL da imagem da opção selecionada.

{ "results": [ { "result": "https://app.surveyninja.io/.../image.png", "score": 3, "is_correct": false } ] }

ranking

Array de opções na ordem definida pelo usuário (primeiro elemento = classificado em 1.°). Pontuação e correção não se aplicam a este tipo.

{ "results": [ { "result": "First place", "score": null, "is_correct": null }, { "result": "Second place", "score": null, "is_correct": null }, { "result": "Third place", "score": null, "is_correct": null } ] }

rating

Objeto (não array). Campo is_star: true — modo de estrelas/corações; score_num: false — modo de exibição não numérica.

{ "results": { "result": "4", "is_star": true, "score": 0, "score_num": false, "is_correct": false } }

scale

Objeto com o valor de escala selecionado, a pontuação e a correção.

{ "results": { "result": "6", "score": 0, "is_correct": true } }

slider

Objeto apenas com o valor. A pontuação não se aplica a sliders.

{ "results": { "result": "45" } }

input, email, phone

Objeto com o valor inserido. A pontuação não se aplica. Para entradas multilinha, as quebras de linha são preservadas.

{ "results": { "result": "User's answer text" } }

datetime

Objeto com um valor de data/hora. O formato do valor depende do modo do widget.

// Date + time { "results": { "result": "12.03.2026 21:12" } } // Date only { "results": { "result": "11.03.2026" } } // Time only { "results": { "result": "18:14" } }

file

Array de arquivos enviados. Cada elemento contém uma URL de download e a extensão do arquivo.

{ "results": [ { "result": "https://app.surveyninja.io/.../document.pdf", "file_ext": "pdf" } ] }

matrix

O tipo mais complexo. Contém duas representações: results — visão legível por humanos: objeto aninhado { "linha": { "coluna": { result, score, is_correct } } }. Valor result: "1" — célula marcada, result: "" — vazia. answers — visão por UUID para máquinas: { "row_uuid": { "col_uuid": true | false } }

{ "results": { "Pasta": { "Bad": { "result": "1", "score": 2, "is_correct": false }, "OK": { "result": "", "score": null, "is_correct": false }, "Good": { "result": "", "score": null, "is_correct": true } }, "Potatoes": { "Bad": { "result": "1", "score": 2, "is_correct": true }, "OK": { "result": "", "score": null, "is_correct": true }, "Good": { "result": "", "score": null, "is_correct": false } } }, "answers": { "row-uuid-1": { "col-uuid-1": true, "col-uuid-2": false, "col-uuid-3": false }, "row-uuid-2": { "col-uuid-1": true, "col-uuid-2": false, "col-uuid-3": false } }, "is_bool": true }

Exemplo completo do payload

Um exemplo real do corpo de uma requisição webhook com pontuação, múltiplos tipos de perguntas e cabeçalhos personalizados. Os UUIDs foram abreviados para facilitar a leitura.

{ "headers": { "Authorization": "Bearer my-secret-token", "X-Source": "surveyninja" }, "extra_params": { "utm_source": "email", "utm_campaign": "spring2024" }, "promo_code": null, "log_id": 1916713, "score_all": 52, "score_earned": 29, "score_percent": 55.8, "scores": { "user": 29, "max": 52, "by_question": { "uuid-choice-1": 0, "uuid-choice-2": 3, "uuid-rating-1": 0, "uuid-scale-1": 0, "uuid-matrix-1": 6 } }, "uuid-choice-1": { "title": "Select one option", "type": "choiceSingle", "question_uuid": "uuid-choice-1", "uuid": "uuid-choice-1", "results": [ { "result": "Option B", "score": 0, "is_correct": false } ], "score_count": 0, "score_max": 4, "is_correct_question": false, "other": "", "inline_group_id": null, "inline_group_title": null, "is_inline_group_child": false }, "uuid-choice-2": { "title": "Check all that apply", "type": "choiceMultiple", "question_uuid": "uuid-choice-2", "uuid": "uuid-choice-2", "results": [ { "result": "Option A", "score": 3, "is_correct": true } ], "score_count": 3, "score_max": 3, "is_correct_question": true, "other": "", "inline_group_id": null, "inline_group_title": null, "is_inline_group_child": false }, "uuid-rating-1": { "title": "Rate the service", "type": "rating", "question_uuid": "uuid-rating-1", "uuid": "uuid-rating-1", "results": { "result": "4", "is_star": true, "score": 0, "score_num": false, "is_correct": false }, "score_count": 0, "score_max": 2, "is_correct_question": false, "inline_group_id": null, "inline_group_title": null, "is_inline_group_child": false }, "uuid-scale-1": { "title": "On a scale of 1 to 10", "type": "scale", "question_uuid": "uuid-scale-1", "uuid": "uuid-scale-1", "results": { "result": "6", "score": 0, "is_correct": true }, "score_count": 0, "score_max": 3, "is_correct_question": true, "inline_group_id": null, "inline_group_title": null, "is_inline_group_child": false }, "uuid-input-1": { "title": "Leave a comment", "type": "input", "question_uuid": "uuid-input-1", "uuid": "uuid-input-1", "results": { "result": "Everything is great!" }, "score_count": null, "score_max": null, "is_correct_question": null, "inline_group_id": null, "inline_group_title": null, "is_inline_group_child": false }, "uuid-file-1": { "title": "Attach a file", "type": "file", "question_uuid": "uuid-file-1", "uuid": "uuid-file-1", "results": [ { "result": "https://app.surveyninja.io/.../document.pdf", "file_ext": "pdf" } ], "score_count": null, "score_max": null, "is_correct_question": null, "inline_group_id": null, "inline_group_title": null, "is_inline_group_child": false }, "uuid-matrix-1": { "title": "Rate the dishes", "type": "matrix", "question_uuid": "uuid-matrix-1", "uuid": "uuid-matrix-1", "results": { "Pasta": { "Bad": { "result": "1", "score": 2, "is_correct": false }, "Good": { "result": "", "score": null, "is_correct": true } }, "Potatoes": { "Bad": { "result": "1", "score": 2, "is_correct": true }, "Good": { "result": "", "score": null, "is_correct": false } } }, "answers": { "row-uuid-1": { "col-uuid-1": true, "col-uuid-2": false }, "row-uuid-2": { "col-uuid-1": true, "col-uuid-2": false } }, "is_bool": true, "score_count": 6, "score_max": 6, "is_correct_question": false, "inline_group_id": null, "inline_group_title": null, "is_inline_group_child": false } }

Compatibilidade retroativa

Os campos de pontuação (score_max, is_correct_question, is_correct dentro de results) são adicionados sobre o formato base. Os campos existentes não são removidos nem renomeados.

Testar webhooks

Você pode usar as seguintes ferramentas para testar os webhooks:

webhook.site

Serviço recomendado para testar webhooks

https://webhook.site

Acesse o site, obtenha uma URL única e use-a para testar seus webhooks.

Visualizar registros

Você pode verificar o funcionamento do webhook pelos registros

A interface do SurveyNinja fornece registros de entrega de webhooks para rastrear seu funcionamento.

Segurança

Para a segurança dos webhooks, recomenda-se usar HTTPS e verificar a autenticidade das requisições.

Recomendações de segurança

  • Use HTTPS para a URL de callback
  • Verifique as assinaturas das requisições para confirmar sua autenticidade
  • Restrinja o acesso ao endpoint apenas aos endereços IP do SurveyNinja
  • Implemente tempos limite para o processamento de webhooks