Ir al contenido

Enviar una grabación

POSThttps://api.caller.ee/v1/calls

Envía una grabación y lo que sepas de ella. Caller crea la llamada, la pone en cola para transcribirla y responde con su identificador. Una petición por llamada.

El cuerpo es multipart/form-data: un formulario con el archivo y, si quieres, campos de texto. La única cabecera que tienes que poner es la de autenticación; la biblioteca que uses pone el Content-Type del formulario.

curl https://api.caller.ee/v1/calls \
-H "Authorization: Bearer $CALLER_API_KEY" \
-F "file=@grabaciones/pbx-000123.mp3" \
-F "external_id=pbx-000123" \
-F "agent_code=AG1143" \
-F "campaign=Retención" \
-F "started_at=2026-10-09T10:42:11+02:00" \
-F "customer_phone=+34600000000" \
-F "direction=inbound"

Solo file es obligatorio. Los campos de texto se recortan a 300 caracteres.

Campo Tipo Descripción
file archivo Obligatorio. La grabación. Ver formatos.
external_id texto El identificador de la llamada en tu sistema, de hasta 200 caracteres. Enviar dos veces el mismo no duplica la llamada. Ver reintentos.
agent_code texto El código del agente en tu centralita. Se compara con el Código en la centralita de cada agente de Equipo, sin distinguir mayúsculas, guiones, guiones bajos ni espacios.
agent_name texto El nombre del agente, tal como está en Equipo. Se usa si no hay código o si nadie lo tiene.
campaign texto El nombre de una campaña que ya exista en la cuenta. No distingue mayúsculas ni tildes.
started_at fecha Cuándo empezó la llamada: ISO 8601 con su desfase (2026-10-09T10:42:11+02:00) o tiempo Unix en segundos o en milisegundos.
customer_phone texto El teléfono del cliente.
customer_name texto El nombre del cliente.
direction texto inbound si la llamada fue entrante, outbound si fue saliente.
language texto El código del idioma de la llamada, para no dejarlo a la detección automática. Ver idioma.

Lo que no envíes se lee del nombre del archivo

Sección titulada «Lo que no envíes se lee del nombre del archivo»

Si faltan el agente, la fecha, el teléfono o la dirección, Caller intenta leerlos del nombre del archivo, igual que al subir a mano. Un campo enviado gana siempre al nombre. Las reglas están en Nombres de archivo.

Todo lo demás es opcional, pero cada grabación tiene que decir de quién es, y esa persona tiene que estar ya en Equipo. Vale cualquiera de estas tres formas: agent_code, agent_name o el código del agente en el nombre del archivo.

  • Si la grabación no dice de quién es, la respuesta es 422 con agent_required.
  • Si lo dice pero nadie de Equipo tiene ese código o ese nombre, la respuesta es 422 con unknown_agent.

En los dos casos la grabación no se guarda y no gasta minutos. Los agentes se dan de alta en la app, en Equipo, con el mismo código que usa tu centralita; cada uno ocupa una plaza de tu plan.

Con una centralita que ya nombra bien sus grabaciones, la petición mínima es el archivo y su external_id.

Salvo el agente, que es obligatorio, la API no rechaza una petición por un dato que no reconoce: crea la llamada sin ese dato. Conviene saberlo, porque no verás un error.

Situación Qué pasa
campaign no existe o está archivada La llamada entra sin campaña y se puntúa con la plantilla predeterminada. Las campañas no se crean solas.
started_at no se entiende como fecha Se ignora. Si el nombre del archivo trae fecha, se usa esa; si no, la llamada queda fechada en el momento de la subida.
started_at es anterior al año 2000 o está a más de un día en el futuro Se ignora, y en este caso tampoco se mira el nombre del archivo: la llamada queda fechada en el momento de la subida.
direction tiene otro valor Se ignora.

201 Created cuando la llamada se ha creado:

{ "id": "k57e2xq9m4hc8w1t6b0z5y2e97c4n1ad", "status": "queued" }

200 OK cuando ya existía una llamada con ese external_id. No se crea nada nuevo y el archivo recibido se descarta:

{ "id": "k57e2xq9m4hc8w1t6b0z5y2e97c4n1ad", "status": "exists" }
Campo Descripción
id El identificador de la llamada en Caller. Es el mismo que aparece en el webhook y en la dirección de la llamada en la app: https://app.caller.ee/calls/{id}.
status queued si se acaba de crear y está en cola; exists si ya existía.

Cualquier otro código es un error, con este cuerpo:

{ "error": { "code": "not_audio", "message": "The file is not an audio recording." } }

La lista completa está en Errores.

Las redes fallan. Si una petición se corta y no sabes si llegó, vuelve a enviarla con el mismo external_id:

  • Si la primera no llegó, se crea la llamada y recibes 201.
  • Si sí había llegado, recibes 200 con "status": "exists" y el id de la llamada que ya estaba.

En ninguno de los dos casos se cobra dos veces. Usa como external_id el identificador único que tu centralita da a cada llamada.

Sin external_id, cada petición crea una llamada nueva, aunque el archivo sea idéntico.

  • Formatos: MP3, WAV, OGG y M4A son los habituales. También se aceptan AAC, FLAC, Opus, WebM, WMA y AMR. Si tu centralita graba en uno de estos últimos, prueba con algunas llamadas antes de automatizar el envío.
  • Tamaño máximo: la petición entera, con el archivo y los campos, tiene que pesar menos de 20 MB. Es un tope de la API, menor que el máximo por archivo de algunos planes: una grabación de entre 20 MB y el máximo de tu plan se puede subir desde la app, pero no por la API.
  • Si te pasas: una petición de 20 MB o más se rechaza con 400 bad_request, el mismo código que un cuerpo mal formado. Comprueba el tamaño antes de enviar y comprime lo que no quepa: para voz, MP3 a 64 kbps en mono ocupa cerca de medio megabyte por minuto.
  • Tipo del archivo: si tu sistema lo envía como application/octet-stream, Caller se guía por la extensión del nombre. Un archivo sin extensión de audio y sin tipo audio/… se rechaza con not_audio.

Sin language, se usa el idioma de la campaña y, si no tiene, se detecta en cada llamada. Fíjalo cuando lo sepas con certeza: la detección puede confundir idiomas parecidos y necesita cerca de un minuto de conversación para acertar.

Códigos admitidos:

ca es en pt gl eu fr de it nl ar zh ru ja ko pl ro tr uk sv no da fi cs el hu he hi id th vi bg hr sk sr fa ur ms ta

Cada llamada aceptada ocupa su tamaño en el almacenamiento y reserva minutos de audio. Su análisis va incluido en esos minutos.

La reserva se hace por el tamaño del archivo, a razón de un minuto por megabyte, y se ajusta a la duración real cuando termina la transcripción. Con MP3 la reserva se parece a la duración. Con WAV sin comprimir puede ser varias veces mayor, y una grabación puede rechazarse con no_minutes aunque su duración real sí cupiera. Si vas justo de minutos, envía audio comprimido.

La llamada sigue el mismo camino que una subida a mano: se transcribe, se analiza y aparece en la app. Cuando queda analizada, Caller envía el resultado a tu webhook, si tienes uno.

No hay una petición para consultar el estado de una llamada. Si una grabación no se puede transcribir, lo verás en la app, en la vista Fallidas; no se envía ningún aviso.