AtendyDocumentación Ir al panel

Webhooks

Los dos webhooks del agente en Atendy: el de entrada (antes de la llamada) y el de fin de llamada, con la estructura del payload y buenas prácticas.

Webhooks (API)

Un webhook es una URL tuya (o de una herramienta como n8n, Make o tu propio servidor) a la que Atendy envía datos de forma automática en un momento concreto de la llamada. Cada agente puede tener dos webhooks, y sirven para cosas distintas: uno se dispara antes de que empiece la conversación y el otro cuando la llamada termina.

Webhook de entrada
Se dispara justo ANTES de que el agente empiece a hablar. Atendy te avisa de quién llama y tú puedes devolver datos de esa persona (nombre, plan, última cita...) para que el agente los use durante la llamada.
Webhook de fin de llamada
Se dispara cuando la llamada TERMINA y se ha analizado. Atendy te envía la transcripción, el resumen y los KPIs, con el mismo formato que el evento call_analyzed de Retell. Ideal para guardar el resultado en tu CRM, hoja de cálculo o base de datos.

Ambos se configuran dentro del agente, en su asistente de herramientas o ajustes del agente, pegando la URL correspondiente. Funcionan tanto en llamadas de teléfono como en las pruebas desde el navegador.

Webhook de entrada (antes de la llamada)

En cuanto entra una llamada (o empiezas una prueba), Atendy hace una petición a tu URL de entrada con los datos que ya conoce, sobre todo el número de teléfono de quien llama. Tu servidor puede usar ese número para buscar a la persona en tu sistema y responder con datos suyos. Todo lo que devuelvas queda disponible como variables dentro del prompt y del saludo.

  1. Prepara una URL en tu servidor o herramienta que reciba una petición POST con JSON.
  2. En el agente, pega esa URL en el campo del webhook de entrada.
  3. Cuando llegue una llamada, Atendy enviará a esa URL el número de origen y el identificador del agente.
  4. Tu servidor responde con un JSON que contenga las variables que quieras usar (por ejemplo el nombre del cliente).
  5. El agente arranca la conversación ya con esos datos cargados.

Esto es un ejemplo de lo que Atendy envía a tu webhook de entrada:

{
  "agent_id": "a1b2c3d4-0000-0000-0000-000000000000",
  "caller_number": "+34600123456",
  "room_name": "call-_+34600123456_a1B2c3"
}
El webhook de entrada solo se dispara en llamadas ENTRANTES. En una llamada saliente lanzada por API, los datos del cliente se los pasas tú directamente en el campo vars de la petición.

Y esto es lo que tu servidor debe responder: un JSON con las variables que quieras poner a disposición del agente. Los nombres de las claves son los que luego usarás entre dobles llaves.

{
  "nombre": "Ana García",
  "plan": "Premium",
  "ultima_cita": "2026-07-02"
}
El número de quien llama siempre está disponible como {{numero_origen}}, aunque no configures ningún webhook de entrada. Úsalo, por ejemplo, para que el agente lo confirme o para identificar al cliente.

Usar las variables en el prompt y el saludo

Cada variable que devuelva el webhook de entrada se escribe entre dobles llaves y Atendy la sustituye por su valor real justo antes de hablar. Puedes usarlas tanto en el prompt del sistema como en el saludo inicial.

Saludo inicial:
Hola {{nombre}}, gracias por llamar. Veo que tienes el plan {{plan}}.

Prompt del sistema:
Atiendes a {{nombre}}, cliente con plan {{plan}}.
Su última cita fue el {{ultima_cita}}. Ayúdale con lo que necesite
sobre su cuenta y confirma sus datos si hace falta.
Si una variable no llega (por ejemplo, porque el webhook no encontró a esa persona), Atendy elimina la etiqueta {{...}} en lugar de leerla en voz alta. Aun así, redacta el saludo para que suene natural con o sin el dato: usa una versión genérica cuando no haya nombre.

Webhook de fin de llamada

Cuando la llamada termina y Atendy ha analizado la conversación, envía a tu URL de fin de llamada un único mensaje con lo ocurrido: la transcripción completa, un resumen, los KPIs que hayas definido y los datos de la llamada. Es el momento ideal para volcar el resultado en tu CRM, avisar a tu equipo o lanzar un flujo en n8n.

El payload usa la misma estructura que el evento call_analyzed de Retell, para que los flujos ya construidos para ese formato funcionen sin cambios. Todo cuelga de un objeto call:

{
  "event": "call_analyzed",
  "call": {
    "call_id": "call-out-4f3a9c2b1d7e",
    "agent_id": "a1b2c3d4-0000-0000-0000-000000000000",
    "agent_name": "Recepción",
    "call_status": "ended",
    "start_timestamp": 1786303502000,
    "end_timestamp": 1786303645000,
    "duration_ms": 143000,
    "from_number": "+34911234567",
    "to_number": "+34600123456",
    "direction": "outbound",
    "disconnection_reason": "agent_hangup",
    "transcript": "Agent: Hola Ana, le llamo por su cita.\nUser: Sí, quería cambiarla.",
    "transcript_object": [
      { "role": "agent", "content": "Hola Ana, le llamo por su cita." },
      { "role": "user", "content": "Sí, quería cambiarla." }
    ],
    "call_analysis": {
      "call_summary": "La clienta pidió cambiar su cita del jueves al viernes por la tarde. Se reprogramó y se le confirmó.",
      "custom_analysis_data": {
        "cita_reprogramada": true,
        "motivo": "cambio de fecha"
      }
    }
  }
}

Campos que recibes, todos dentro de call:

CampoQué contiene
eventSiempre call_analyzed. Va en la raíz, no dentro de call.
call_idIdentificador de la llamada. En una llamada lanzada por API es exactamente el call_id que te devolvió el POST, así que es la forma de casar tu petición con su resultado.
agent_id / agent_nameEl agente que atendió la llamada.
call_statusSiempre ended: este aviso solo se envía con la llamada terminada.
directioninbound en llamadas entrantes, outbound en salientes y web en las pruebas desde el navegador.
from_number / to_numberNúmeros de la llamada según su dirección. En una saliente, from_number es tu número y to_number el de la persona a la que llamaste.
start_timestamp / end_timestampMomentos de inicio y fin en milisegundos desde el 1 de enero de 1970 (epoch), no en texto con fecha. Valen 0 si el inicio no se pudo determinar.
duration_msDuración en MILISEGUNDOS. Ojo si vienes de una integración que esperaba segundos.
disconnection_reasonCómo terminó: agent_hangup, user_hangup, call_transfer o max_duration_reached.
transcriptLa conversación como texto plano, con cada turno en una línea con el prefijo Agent: o User:.
transcript_objectLa misma conversación turno a turno, con role (agent o user) y content. Fíjate en que el texto va en content, no en text.
call_analysis.call_summaryEl resumen de la llamada.
call_analysis.custom_analysis_dataLos datos clave que le pediste extraer al agente (por ejemplo, si se cerró una cita).
El sentimiento, el indicador de transferencia y el enlace a la grabación NO viajan en este payload: se guardan en la llamada y los ves en el Historial del panel. Si necesitas el sentimiento en tu sistema, puedes consultarlo con GET /api/v1/calls/{call_id} una vez el análisis esté listo.
El aviso se envía cuando el análisis de la llamada está terminado, alrededor de un minuto después de colgar. Si tu flujo necesita reaccionar en el instante en que la llamada acaba, no esperes a este webhook.
Las pruebas desde el navegador con Probar agente también disparan los dos webhooks y llegan con la marca de canal web. El widget público embebido (anónimo) no dispara webhooks, pero sí guarda la conversación en tu Historial (canal widget).

Buenas prácticas

El webhook de entrada tiene un límite de espera de unos 8 segundos. Si tu servidor tarda más en responder, Atendy continúa la llamada sin esas variables para no dejar al cliente esperando. Responde siempre lo más rápido posible.
Responde rápido
En el webhook de entrada, devuelve solo los datos imprescindibles y hazlo en menos de 8 segundos. Evita consultas lentas o cadenas de llamadas a otros sistemas antes de responder.
Devuelve un JSON válido
Responde siempre con JSON correcto y con código 200. Si respondes un error o texto no válido, el agente arrancará sin variables.
Trabaja pesado en el fin de llamada
Para procesos lentos (guardar en el CRM, enviar emails, actualizar hojas), usa el webhook de fin de llamada: ahí ya no hay nadie esperando al teléfono.
Prepárate para reintentos
Diseña tu endpoint para que recibir el mismo aviso dos veces no cause duplicados. Usa el call_id como referencia única.
Diseña con datos ausentes
Puede que el webhook no encuentre a la persona. Escribe el prompt y el saludo para que funcionen igual de bien sin las variables.
Usa HTTPS
Publica tus webhooks siempre bajo HTTPS. Atendy no envía datos a direcciones internas o privadas por seguridad.
Si usas n8n, Make o Zapier, crea un nodo Webhook que reciba el payload de fin de llamada y encadena a partir de ahí: guardar en Google Sheets, avisar por Slack o crear una tarea. No necesitas programar nada.