Webhooks

Configure notificaciones de eventos en tiempo real

Webhooks

Un webhook es la entrega de datos a un endpoint cuando ocurre un evento. En nuestro caso, ese evento es el envío de una respuesta a una encuesta. Los webhooks están destinados a usuarios avanzados con conocimientos de programación.

Cómo conectar

Para configurar los webhooks, vaya a la pestaña Integraciones → Webhooks y haga clic en Conectar.

Descargue la versión en markdown de la sección "Webhooks" para usarla en ChatGPT u otros LLMs:

Interfaz de configuración de webhooks

Paso 1: Ir a integraciones

Para configurar los webhooks, vaya a la pestaña Integraciones → Webhooks y haga clic en Conectar.

Paso 2: Formulario de configuración del webhook

Se abrirá una pantalla donde deberá introducir el nombre del webhook, la URL de callback y el tipo de solicitud.

Paso 3: Probar el webhook

Puede probar el webhook usando https://webhook.site

Paso 4: Ver registros

O consultando los registros en la interfaz de SurveyNinja.

Configuración del webhook

El formulario de configuración del webhook tiene los siguientes parámetros:

Parámetro Descripción
Nombre Un nombre personalizado para identificar el webhook en la lista
URL La URL de su endpoint. SurveyNinja envía una solicitud POST por cada nueva respuesta a la encuesta
Cabeceras Cabeceras HTTP personalizadas en formato "clave: valor". Se envían con cada solicitud y se duplican en el campo headers del cuerpo del payload para facilitar el registro
Habilitado Interruptor de actividad. Un webhook deshabilitado no envía solicitudes pero conserva toda la configuración

Token secreto mediante cabecera

Añada una cabecera Authorization: Bearer su-secreto — su servidor podrá verificar que la solicitud proviene auténticamente de SurveyNinja.

Cuándo se activan los webhooks

En SurveyNinja, los webhooks se activan cuando se envía una respuesta a una encuesta. Este es el principal evento que puede rastrear.

Evento: Respuesta a encuesta

El webhook se activa cada vez que un encuestado envía una respuesta a su encuesta, proporcionando notificaciones en tiempo real de nuevas respuestas.

Entrega automática

El webhook se envía automáticamente tan pronto como se recibe una respuesta a la encuesta

Formato del payload

SurveyNinja envía una solicitud POST con un cuerpo JSON. La estructura completa del cuerpo de la solicitud se describe a continuación.

Campos raíz del payload

Campo Tipo Descripción
headers object Cabeceras configuradas en el webhook. Duplicadas en el cuerpo para facilitar el registro y la depuración
extra_params object / array Variables ocultas y etiquetas UTM enviadas durante la encuesta. Array vacío [] si no hay variables
promo_code string / null Código promocional utilizado durante la encuesta, o null
log_id int ID del registro de entrega de este webhook
score_all int Puntuación máxima posible para toda la encuesta. 0 si la puntuación no está configurada
score_earned int Puntuación total obtenida por el encuestado
score_percent float / null Porcentaje del resultado: (score_earned / score_all) × 100, redondeado a 1 decimal. null si score_all = 0
scores object Resumen de puntuación: campos user, max y by_question — un mapa { "uuid": int | null }
{question_uuid} object Respuesta a la pregunta con este UUID. Cada pregunta de la encuesta tiene una clave de nivel superior independiente

Campos del objeto de pregunta

Cada pregunta en el payload es un objeto identificado por el UUID de la pregunta. Todos los tipos de preguntas comparten los siguientes campos comunes:

Campo Tipo Descripción
title string Texto de la pregunta (título del widget)
type string Tipo de widget: choiceSingle, choiceMultiple, rating, matrix y otros.
question_uuid / uuid string UUID de la pregunta (duplicado dentro del objeto)
results object / array Respuesta del encuestado. El formato depende del tipo de widget — véase la sección a continuación
score_count int / null Puntuación obtenida para esta pregunta. null si la puntuación no aplica a este tipo
score_max int / null Puntuación máxima para esta pregunta. null si la puntuación no aplica
is_correct_question bool / null Corrección general de la respuesta: true — correcta, false — incorrecta, null — no aplicable
other string Texto de la opción 'Otro', si fue seleccionada (para widgets de selección). Cadena vacía si no fue seleccionada
inline_group_id string / null UUID del grupo de preguntas, si la pregunta pertenece a un grupo
inline_group_title string / null Nombre del grupo de preguntas
is_inline_group_child bool true si la pregunta está dentro de un grupo

Formato de results por tipo de widget

El campo results tiene un formato diferente según el tipo de pregunta.

choiceSingle, choiceMultiple, yesno, dropdown

Array de opciones seleccionadas. Cada elemento contiene el texto de la opción, la puntuación y el indicador de corrección.

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

choiceMedia

Array de opciones de medios seleccionadas. El campo result contiene la URL de la imagen de la opción seleccionada.

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

ranking

Array de opciones en el orden establecido por el usuario (primer elemento = clasificado 1.°). La puntuación y la corrección no se aplican 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 (no array). Campo is_star: true — modo estrellas/corazones; score_num: false — modo de visualización no numérica.

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

scale

Objeto con el valor de escala seleccionado, la puntuación y la corrección.

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

slider

Objeto solo con el valor. La puntuación no aplica a los sliders.

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

input, email, phone

Objeto con el valor introducido. La puntuación no aplica. Para entradas multilínea, los saltos de línea se conservan.

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

datetime

Objeto con un valor de fecha/hora. El formato del valor depende del modo del 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 archivos subidos. Cada elemento contiene una URL de descarga y la extensión del archivo.

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

matrix

El tipo más complejo. Contiene dos representaciones: results — vista legible por humanos: objeto anidado { "fila": { "columna": { result, score, is_correct } } }. Valor result: "1" — celda marcada, result: "" — vacía. answers — vista 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 }

Ejemplo completo del payload

Un ejemplo real del cuerpo de una solicitud webhook con puntuación, múltiples tipos de preguntas y cabeceras personalizadas. Los UUID se han acortado para mayor legibilidad.

{ "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 } }

Compatibilidad con versiones anteriores

Los campos de puntuación (score_max, is_correct_question, is_correct dentro de results) se añaden sobre el formato base. Los campos existentes no se eliminan ni se renombran.

Probar webhooks

Puede utilizar las siguientes herramientas para probar los webhooks:

webhook.site

Servicio recomendado para probar webhooks

https://webhook.site

Visite el sitio, obtenga una URL única y úsela para probar sus webhooks.

Ver registros

Puede verificar el funcionamiento del webhook a través de los registros

La interfaz de SurveyNinja proporciona registros de entrega de webhooks para rastrear su funcionamiento.

Seguridad

Para la seguridad de los webhooks, se recomienda usar HTTPS y verificar la autenticidad de las solicitudes.

Recomendaciones de seguridad

  • Use HTTPS para la URL de callback
  • Verifique las firmas de las solicitudes para confirmar su autenticidad
  • Restrinja el acceso al endpoint únicamente a las direcciones IP de SurveyNinja
  • Implemente tiempos de espera para el procesamiento de webhooks