Llamadas salientes (API)
Referencia del endpoint POST /api/v1/calls para lanzar llamadas salientes desde tu código, n8n u otra herramienta.
Llamadas salientes (API)
Esta es la API pública de Atendy para desarrolladores. Con una sola petición HTTP puedes pedirle a la plataforma que llame por teléfono a un número usando uno de tus agentes. Es ideal para conectar Atendy con tus propias aplicaciones o con herramientas de automatización como n8n: cuando ocurre algo en tu sistema (una nueva reserva, un pedido, un aviso), disparas una llamada automática.
Autenticación
Todas las peticiones se autentican con una clave de API que empieza por sk_live_. La creas en la sección Llamadas salientes del panel, en el apartado de claves de API. La clave se muestra completa una sola vez al crearla, así que guárdala en un lugar seguro. Se envía en cada petición mediante la cabecera x-api-key. Cada llamada lanzada con tu clave se factura a la cuenta dueña de esa clave, así que trátala como una contraseña y no la publiques en código del lado del cliente.
Método y URL
POST https://atendy.es/api/v1/callsCabeceras
| Cabecera | Valor |
|---|---|
| Content-Type | application/json |
| x-api-key | sk_live_... (tu clave de API). Como alternativa puedes enviarla en Authorization: Bearer sk_live_... |
| Idempotency-Key | Opcional. Identificador único que tú eliges para esta llamada. Si repites la petición con la misma clave, se te devuelve la respuesta de la primera en lugar de llamar otra vez. Ver el apartado Evitar llamadas duplicadas. |
Cuerpo de la petición
El cuerpo es un objeto JSON con los siguientes campos:
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| agent_id | texto (UUID) | Sí | Identificador del agente que hará la llamada. Lo encuentras en la ficha del agente, dentro de la sección Agentes. |
| to | texto | Sí | Número de destino, la persona a la que llamará el agente. Usa siempre formato internacional (+34600000000). Se admiten espacios, guiones, puntos y paréntesis, que se eliminan antes de marcar. El + es técnicamente opcional, pero sin prefijo de país tu operadora puede no saber enrutar la llamada, así que no lo omitas. |
| from | texto | No | Sirve para elegir CON QUÉ NÚMERO TUYO se marca, cuando tienes varios asignados al mismo agente: se usa la línea que coincida exactamente con este valor. Si lo omites, se usa la primera línea de salida disponible de ese agente. Importante: este campo NO cambia el número que ve el destinatario en su pantalla; ese identificador lo impone la línea SIP de tu operadora. |
| vars | objeto JSON | No | Pares clave-valor que se inyectan en el prompt y el saludo del agente como {{variables}}. Útil para personalizar cada llamada (nombre del cliente, número de pedido, importe, etc.). |
Ejemplo de petición (cURL)
curl -X POST https://atendy.es/api/v1/calls \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_tu_clave_aqui" \
-d '{
"agent_id": "1a2b3c4d-0000-0000-0000-000000000000",
"to": "+34600000000",
"from": "+34910000000",
"vars": {
"nombre": "Ana",
"pedido": "12345"
}
}'Respuesta correcta (200)
Si la llamada se acepta y empieza a marcarse, recibes un código 200 con un cuerpo JSON como este:
{
"call_id": "call-out-4f3a9c2b1d7e",
"room": "call-out-4f3a9c2b1d7e",
"status": "dialing"
}| Campo | Descripción |
|---|---|
| call_id | Identificador único de la llamada, con el formato call-out- seguido de 12 caracteres. Guárdalo: es el mismo valor que usarás para consultar el estado y el que llegará en el webhook de fin de llamada, así que es la forma de relacionar tu petición con su resultado. |
| room | Identificador interno de la sesión. Hoy su valor es idéntico al de call_id; se mantiene por compatibilidad. Usa call_id. |
| status | Estado inicial. dialing significa que la llamada se está marcando. |
Evitar llamadas duplicadas (Idempotency-Key)
Cada petición aceptada llama por teléfono a una persona real y consume minutos de tu plan. Si tu sistema reintenta automáticamente cuando una petición tarda o da timeout, sin más precauciones esa persona recibiría dos llamadas. Para evitarlo, envía la cabecera Idempotency-Key con un identificador único de esa llamada: si repites la petición con la misma clave y los mismos datos, Atendy te devuelve la respuesta de la primera sin volver a marcar.
Usa un valor que identifique el hecho de negocio, no el intento: por ejemplo el identificador del pedido, del aviso o de la fila de tu base de datos. Debe tener entre 8 y 255 caracteres y admite letras, números, punto, guion, guion bajo y dos puntos. La clave se recuerda durante 24 horas.
curl -X POST https://atendy.es/api/v1/calls \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_tu_clave_aqui" \
-H "Idempotency-Key: aviso-2026-08-06-12345" \
-d '{
"agent_id": "1a2b3c4d-0000-0000-0000-000000000000",
"to": "+34600000000"
}'| Situación | Qué recibes |
|---|---|
| Misma clave, mismos datos, la primera llamada ya se lanzó | 200 con la respuesta original y la cabecera Idempotent-Replay: true. No se marca de nuevo. |
| Misma clave, mientras la primera petición sigue en curso | 409. Espera unos segundos y vuelve a consultar; la llamada original sigue su curso. |
| Misma clave, pero con datos distintos | 409. Es señal de que tu sistema está reutilizando la clave para otra llamada: usa una clave nueva. |
| El primer intento falló (por ejemplo, comunicando) | La clave queda libre: puedes reintentar esa misma llamada con la misma clave. |
Cómo se usan las vars como {{variables}}
Cada clave que envíes dentro de vars queda disponible en el prompt y en el saludo del agente escribiéndola entre dobles llaves. Por ejemplo, si envías vars con nombre igual a Ana y pedido igual a 12345, en el prompt o el saludo puedes escribir {{nombre}} y {{pedido}} y el agente dirá los valores reales durante la llamada.
Saludo del agente:
Hola {{nombre}}, le llamo de la tienda por su pedido {{pedido}}.
Con vars = { "nombre": "Ana", "pedido": "12345" } el agente dice:
Hola Ana, le llamo de la tienda por su pedido 12345.Errores
Cuando algo falla, la API devuelve un código de estado distinto de 200:
| Código | Significado | Qué hacer |
|---|---|---|
| 400 | Petición mal formada. | Falta agent_id, no tiene forma de identificador válido, o el número de to no es un número de teléfono reconocible. También si la Idempotency-Key no cumple el formato. Revisa el cuerpo antes de reintentar: reintentar sin cambios volverá a fallar. |
| 401 | Clave de API no válida o ausente. | Revisa que envías la cabecera x-api-key y que la clave existe y no ha sido revocada. Genera una nueva en Llamadas salientes si hace falta. |
| 403 | Plan insuficiente. | La API requiere el plan Escala. Sube de plan para poder lanzar llamadas por API. |
| 404 | Agente no encontrado. | El agent_id no existe o no pertenece a la cuenta dueña de la clave. Comprueba que copiaste el identificador del agente correcto. |
| 409 | Conflicto de Idempotency-Key. | Esa clave ya está en uso para una llamada en curso, o se usó antes con datos distintos. Ver el apartado Evitar llamadas duplicadas. |
| 422 | El agente no tiene línea de salida. | Ese agente no tiene ningún número con llamadas salientes configuradas. Asígnaselo en la sección Números del panel. Es el error más habitual en la primera integración. |
| 429 | Límite de ritmo superado. | El límite es de 30 peticiones por minuto y cuenta. La respuesta incluye la cabecera Retry-After con los segundos que debes esperar. Reparte las llamadas en el tiempo. |
| 502 | Tu operadora rechazó la llamada. | El mensaje concreta la causa: credenciales SIP rechazadas, destino ocupado o número no enrutable. Si son las credenciales, corrígelas en Números; si es el destino, se puede reintentar más tarde. |
| 503 | No se puede garantizar la idempotencia. | Solo ocurre si enviaste Idempotency-Key. La llamada NO se ha lanzado. Reintenta la misma petición al cabo de unos segundos. |
| 500 | Error inesperado. | Reintenta pasado un momento. Si se repite, escríbenos con el momento exacto y el agent_id. |
Límite de peticiones
Puedes lanzar hasta 30 peticiones por minuto con la misma cuenta. Al superarlo recibes un 429 con la cabecera Retry-After. Ten en cuenta que ese límite es de peticiones, no de conversaciones simultáneas: cada llamada ocupa recursos durante varios minutos, así que si vas a lanzar decenas de llamadas seguidas, repártelas en el tiempo o usa las campañas del panel, que tienen ritmo configurable. Si necesitas volumen alto y sostenido, háblalo con nosotros antes para dimensionar la capacidad.