Recibe cada llamada
en tu servidor
Cuando termina una llamada, se apunta una cita o avanza una campaña, enviamos un POST con JSON a la dirección que elijas. Aquí tienes cómo recibirlo y cómo comprobar que viene de nosotros.
Todavía no hay una API pública. Hoy los datos salen de CallHalla por webhooks y, para tu asistente de IA, por MCP.
Cómo se da de alta
- 1En tu panel, entra en Webhooks y crea uno con la URL de tu servidor.
- 2Elige los eventos que quieres recibir.
- 3Copia el secreto de firma que aparece en la tarjeta del webhook.
- 4Pulsa Probar. Te mandamos un envío de ejemplo, firmado igual que los de verdad.
Qué recibes
Cada envío es un POST con JSON y siempre tiene la misma forma: el evento, la hora y los datos. Este es el de una llamada terminada:
{
"event": "call.completed",
"timestamp": "2026-10-11T10:30:00.000Z",
"data": {
"contact": { "phone": "+34600000000" },
"call": {
"id": "…",
"status": "completed",
"duration": 94,
"phoneNumber": "+34960000000",
"fromNumber": "+34600000000",
"endedAt": "2026-10-11T10:30:00.000Z",
"transcript": [ … ]
}
}
}Lo que va en data depende del evento. Para ver el de cada uno, mira el registro de envíos del panel.
Eventos que puedes recibir
Llamadas
call.startedSale la llamada de prueba de una campaña. Las llamadas que contesta Halla no lo mandan.call.completedHalla termina una llamada. Incluye la transcripción.call.failedUna llamada no llega a completarse.
Campañas
campaign.startedEmpieza una campaña, o se reanuda tras una pausa.campaign.pausedSe pausa una campaña, a mano o al salir de su horario.campaign.completedTermina una campaña. Incluye cuántas llamadas salieron bien y cuántas no.campaign.failedUna campaña se detiene por un error.campaign.cancelledSe cancela una campaña.
Flujos de conversación
flow.completedTermina bien una llamada atendida con un flujo de conversación.flow.failedFalla una llamada atendida con un flujo de conversación.
Citas
appointment.bookedHalla apunta una cita en firme, o aceptas una solicitud en el panel.appointment.confirmedSe confirma una cita: la marcas en el panel, o la persona lo dice en la campaña de confirmar citas.appointment.cancelledSe anula una cita.appointment.rescheduledSe cambia una cita de día u hora.appointment.completedMarcas una cita como hecha en el panel.appointment.no_showMarcas en el panel que la persona no vino.appointment.reminder_sentSe anota en una cita que se le ha mandado un recordatorio. CallHalla no los manda por su cuenta.
Formularios
form.submittedUn agente con flujo de conversación rellena un formulario durante una llamada.
Firma
Cada envío lleva la cabecera X-Webhook-Signature. Su valor es sha256= seguido del HMAC-SHA256, en hexadecimal, del cuerpo tal cual llega. Se calcula con el secreto de tu webhook.
También enviamos X-Webhook-Event, con el nombre del evento, y X-Webhook-Delivery, que identifica el envío y es el mismo en todos sus reintentos. Si te llega dos veces, puedes descartar el duplicado.
Reintentos
Esperamos hasta 30 segundos una respuesta 2xx. Si no llega, lo intentamos cinco veces más, esperando 1, 5, 15, 30 y 60 minutos entre un intento y el siguiente: seis intentos en unas dos horas.
Los reintentos pendientes se guardan en nuestra base de datos, así que un reinicio del servidor no los pierde. En el registro del panel ves cada intento y puedes reenviarlo.
const crypto = require("crypto");
function verifyWebhook(rawBody, signatureHeader, secret) {
// signatureHeader = "sha256=<hex>"
const expected =
"sha256=" +
crypto.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return (
typeof signatureHeader === "string" &&
signatureHeader.length === expected.length &&
crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected)
)
);
}
// rawBody: el cuerpo tal cual llega, antes de JSON.parse
app.post("/webhooks/callhalla", (req, res) => {
const ok = verifyWebhook(
req.rawBody,
req.headers["x-webhook-signature"],
process.env.CALLHALLA_WEBHOOK_SECRET
);
if (!ok) return res.status(401).end();
res.status(200).end();
});Conecta tu asistente de IA
CallHalla tiene un servidor MCP en https://callhalla.io/mcp. Claude, ChatGPT o cualquier asistente compatible se conecta a tu cuenta con OAuth: entras en CallHalla y pulsas «Permitir». Está en todos los planes.
Cómo se conecta
- 1En claude.ai o en Claude Desktop: Ajustes → Conectores → «Añadir conector personalizado», con la dirección https://callhalla.io/mcp.
- 2En ChatGPT: crea un conector con la misma dirección.
- 3Se abre CallHalla: entras con tu cuenta y pulsas «Permitir». Si quieres, quitas los cambios y le dejas solo leer.
claude mcp add --transport http callhalla https://callhalla.io/mcp
claude mcp login callhallaQué puede hacer
- Leer el resumen del mes, tus llamadas con su resumen y su transcripción, tu agenda, tus contactos con sus notas y lo que sabe tu recepcionista.
- Si se lo permites: apuntar, mover, confirmar y anular citas, con las mismas reglas de horario y solapes que el teléfono; añadir notas a un contacto y enseñar textos nuevos a tu recepcionista.
- Nunca: hacer llamadas, lanzar campañas ni tocar tus números, tu facturación o los ajustes de tu cuenta.
get_monthly_summary
list_calls
get_call
list_appointments
create_appointment
update_appointment
search_contacts
get_contact
add_contact_note
list_knowledge
add_knowledgeEl permiso dura una hora y se renueva solo, y solo sirve para el MCP: no abre el resto de CallHalla. Lo ves y lo desconectas cuando quieras en Ajustes → Perfil → Apps conectadas.