Desarrolladores
Webhooks
Recibe notificaciones HTTPS firmadas cuando terminan las llamadas, se toman mensajes, cambian las citas, pedidos y reservas, o termina una campaña, y verifica que cada una viene realmente de Ringhum.
6 min de lectura Actualizado el 24 septiembre 2026
En esta página
Un webhook envía una solicitud HTTPS a tu servidor en el momento en que algo ocurre en tu espacio de trabajo. Usa webhooks en lugar de consultar la API repetidamente: cuando termina una llamada, recibes el resumen, el resultado, los datos recopilados y la transcripción al instante. Cada entrega se firma con un secreto que solo conocéis tú y Ringhum, así que tu servidor puede rechazar cualquier cosa que no venga de Ringhum.
Añade un endpoint
Solo el Propietario y los Administradores del espacio de trabajo pueden añadir, probar y quitar endpoints.
- Abre Desarrolladores en el menú lateral.
- En la tarjeta Webhooks, haz clic en Añadir endpoint.
- Introduce la URL del endpoint. Debe empezar por
https://. - En Eventos, marca los que quieras.
call.endedviene marcado por defecto. - Haz clic en Añadir endpoint.
- Copia el secreto de firma del recuadro verde (empieza por
whsec_) y guárdalo en tu servidor. Haz clic en Listo.
Importante: El secreto de firma se muestra solo una vez. Si lo pierdes, quita el endpoint y añádelo de nuevo para obtener uno nuevo.
Puedes añadir tantos endpoints como necesites. Los webhooks cubren todos los asistentes del espacio de trabajo. También puedes gestionar endpoints a través de la API, con POST /webhooks y una clave con el permiso de escritura.
Eventos
| Evento | Cuándo se envía |
|---|---|
call.started |
Un asistente respondió una llamada |
call.ended |
Una llamada terminó y se resumió (incluye transcripción y resumen) |
call.transferred |
Una llamada se transfirió a una persona |
message.taken |
El asistente tomó un mensaje |
appointment.booked |
El asistente reservó una cita |
appointment.rescheduled |
Una cita se movió a una nueva hora |
appointment.cancelled |
Se canceló una cita |
order.created |
Se hizo un pedido (por un asistente, a mano o a través de la API) |
order.updated |
Un pedido pasó a un nuevo estado |
order.cancelled |
Se canceló un pedido |
reservation.created |
Se reservó una habitación (por un asistente, a mano o a través de la API) |
reservation.updated |
Una reserva pasó a un nuevo estado (confirmada, entrada registrada, salida registrada, no presentado) |
reservation.cancelled |
Se canceló una reserva |
campaign.completed |
Una campaña saliente terminó de llamar a su lista |
test.ping |
Hiciste clic en Enviar prueba |
Cómo es una entrega
Cada entrega es un POST con un cuerpo JSON y estas cabeceras:
POST https://example.com/hooks/ringhum
Content-Type: application/json
User-Agent: Ringhum-Webhooks/1.0
X-Ringhum-Event: call.ended
X-Ringhum-Timestamp: 1789250000
X-Ringhum-Signature: v1=5f1a…
{
"id": "evt_8f2k…",
"type": "call.ended",
"created_at": "2026-09-24T14:03:11+00:00",
"data": {
"call_id": 4812,
"direction": "inbound",
"from": "+14155550132",
"to": "+14155550100",
"assistant_id": 3,
"status": "completed",
"outcome": "message_taken",
"sentiment": "neutral",
"duration_seconds": 94,
"summary": "Caller asked for a quote for a kitchen repair…",
"extracted": { "name": "Dana Lee", "reason": "Quote" },
"transcript": [
{ "role": "assistant", "content": "Hello, you've reached…" },
{ "role": "user", "content": "Hi, I'd like a quote…" }
]
}
}
El objeto data depende del evento:
call.endedymessage.taken: los campos de llamada anteriores.call.startedycall.transferred:call_id,direction,from,to,assistant_id,statusystarted_at.appointment.*:appointment_id,title,status,starts_at,ends_at,timezone,customer(nombre, teléfono, correo),contact_id,service,staff,call_idynotes.order.*:order_id,number,status,fulfillment,customer,address,itemscon opciones y precios,currency,subtotal,fee,total,source,call_idy, en las cancelaciones,cancel_reason.reservation.*:reservation_id,number,status,room,check_in,check_out,nights,adults,children,guest,currency,nightly,totalysource.campaign.completed:campaign_id,namey los contadores de progreso de la campaña.
Nota: Cuando el asistente reserva una cita durante una llamada, puedes recibir
appointment.bookeddos veces. Una se envía en el momento de la reserva, con los campos de la cita. La otra se envía después de resumir la llamada, con los campos de la llamada. Comprueba sidatatieneappointment_idocall_idy usa el campoidpara evitar procesar una entrega dos veces.
Verifica la firma
La firma es un HMAC-SHA256 de la marca de tiempo, un punto, y el cuerpo bruto de la solicitud, con clave tu secreto de firma del endpoint. Se envía como v1= seguido del resumen hexadecimal.
- Lee el cuerpo bruto exactamente como se recibió, antes de cualquier análisis JSON.
- Construye la cadena
{X-Ringhum-Timestamp}.{cuerpo bruto}. - Calcula el HMAC-SHA256 con tu secreto y anteponle
v1=. - Compáralo con
X-Ringhum-Signatureusando una comparación de tiempo constante. - Rechaza la solicitud si la marca de tiempo tiene más de cinco minutos, para bloquear solicitudes repetidas.
Node.js:
const crypto = require('crypto');
function isValid(req, rawBody, secret) {
const ts = req.header('X-Ringhum-Timestamp');
const sig = req.header('X-Ringhum-Signature') || '';
const expected = 'v1=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
return fresh && sig.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
PHP:
$ts = $_SERVER['HTTP_X_RINGHUM_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_RINGHUM_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac('sha256', $ts . '.' . file_get_contents('php://input'), $secret);
if (! hash_equals($expected, $sig) || abs(time() - (int) $ts) > 300) {
http_response_code(400);
exit;
}
Respuestas, tiempos de espera y reintentos
- Responde con cualquier estado
2xxpara confirmar la entrega. Haz el trabajo lento después de responder. - Ringhum espera hasta 10 segundos tu respuesta.
- Si tu endpoint no responde con un
2xx, la entrega se intenta hasta 3 veces en total: de inmediato, otra vez unos 10 segundos después, y una última vez unos 60 segundos más tarde. Después de eso se descarta. - Las entregas pueden llegar desordenadas. Usa
created_aty los ids endatapara ordenarlas.
La tabla Webhooks muestra el último estado HTTP de cada endpoint y cuándo se envió. Un endpoint fallido sigue activo; Ringhum no lo desactiva por ti.
Prueba, pausa y elimina
- Enviar prueba envía un evento
test.pingal instante, y un mensaje muestra el estado HTTP que devolvió tu endpoint. - El interruptor Activo pausa un endpoint. Los eventos que ocurren mientras está desactivado no se envían después.
- Quitar elimina el endpoint y su secreto.
Preguntas frecuentes
¿Cuál es la diferencia con las aplicaciones de Zapier, Make y n8n en Integraciones? Esas conexiones usan la página Integraciones y sus seis tipos de evento. Su cuerpo es {"event", "workspace", "sent_at", "data"}, y cuando configuras un secreto la cabecera de firma es X-Ringhum-Signature: sha256=…, un HMAC-SHA256 solo del cuerpo. Los webhooks de desarrollador, descritos aquí, cubren más eventos y usan la firma v1= con una marca de tiempo. Consulta Elegir qué se envía.
Mi endpoint devuelve 2xx pero mi código no ve nada. Comprueba que el evento esté marcado para ese endpoint, que el endpoint esté activo, y que tu cortafuegos permita solicitudes de internet.
¿Por qué falla la comprobación de la firma? Lo más habitual es que el cuerpo se analizara y volviera a codificar antes de calcular el hash. Calcula el hash de los bytes brutos exactamente como se recibieron.
← Anterior
Claves de API y permisos
Siguiente →
Conecta Ringhum con Claude y otras herramientas de IA (MCP)
Artículos relacionados
Claves de API y permisos
Crea y revoca claves de API en la página Desarrolladores, elige acceso de lectura o escritura, y conoce lo básico de la API REST de Ringhum - URL base, autenticación, paginación, errores y límites de peticiones.
Conecta Ringhum con Claude y otras herramientas de IA (MCP)
Añade Ringhum como conector en Claude, ChatGPT, Cursor, VS Code y otras aplicaciones de IA compatibles con el Model Context Protocol, elige acceso de solo lectura o de lectura y modificación, y desconecta una aplicación.
Elegir qué se envía
Elige qué llamadas, elementos de la bandeja de entrada, citas y pedidos recibe cada aplicación conectada, y limita las actualizaciones de llamadas a las que necesitan que alguien actúe.
Conectar una aplicación
Cómo conectar Slack, tu CRM, mesa de ayuda, herramienta de tareas, hoja de cálculo, tienda o calendario con Ringhum, qué tipo de conexión usa cada aplicación, y cómo comprobar que funciona.
¿Sigues con dudas?
Escribe a [email protected] o envíanos un mensaje. Los planes Team y Scale tienen soporte prioritario.