Ir al contenido

Subir Llamadas para Análisis

Cuando un proyecto de llamadas tiene el análisis automático activado, cada grabación se analiza en cuanto termina de transcribirse: no hace falta ninguna llamada adicional para «ejecutar el análisis».

Lo importante: el endpoint de subida de la API es el mismo que usa la aplicación web. Arrastrar un archivo al panel de Conversaciones y enviarlo con POST a /api/files/ recorren exactamente la misma ruta en el servidor, así que una grabación subida por un script se transcribe, obtiene su CallRecord y se pone en cola para el análisis automático igual que una subida a mano. No hay nada específico de la API que activar.

Todos los endpoints requieren una clave de API — consulta Autenticación.


  1. Configura el proyecto una vez — activa el análisis automático y elige los tipos de análisis.
  2. POST /api/files/ — sube cada grabación, opcionalmente con sus metadatos de llamada.
  3. Consulta GET /calls/api/analysis-status/?project_id=… hasta que in_progress sea false.
  4. Lee los resultados desde la API de Informes de Llamadas.

Los pasos 2–4 son los únicos que repites en el día a día.

Todos los pasos necesitan el ID numérico del proyecto. Si no lo tienes, Proyectos explica cómo listar tus proyectos y dónde encontrar el ID en la aplicación web.


El análisis automático se configura en el proyecto, mediante PATCH /api/projects/{id}/. También puedes hacerlo desde el asistente de análisis de la aplicación web: los ajustes son los mismos.

Campos:

CampoTipoDescripción
auto_analysis_enabledboolInterruptor principal. El análisis solo ocurre cuando es true.
auto_analysis_typeslistaQué análisis ejecutar por llamada. Uno o varios de calls_analysis_copc, calls_analysis_no_protocol, custom_questions.
auto_analysis_questionslista de textosEl conjunto de preguntas que se responde por llamada. Obligatorio cuando custom_questions está activo.
evaluation_rubricintID de la rúbrica con la que puntuar. Obligatorio cuando calls_analysis_copc está activo.
auto_analysis_batch_sizeintEnvía un lote cuando haya esta cantidad de llamadas esperando. Por defecto 20, rango permitido 120.
auto_analysis_max_wait_secondsintVacía un lote parcial cuando su llamada más antigua alcanza esta antigüedad. Por defecto 300.

Validación — la petición se rechaza con 400 cuando la configuración produciría ejecuciones inservibles:

  • El audio_type del proyecto no es call — el análisis automático es solo para proyectos de llamadas.
  • auto_analysis_types está vacío.
  • Se solicita calls_analysis_copc sin una evaluation_rubric.
  • Se solicita custom_questions sin ninguna auto_analysis_questions.
  • auto_analysis_batch_size está fuera de 120.

Ejemplo — activar el análisis por llamada sin protocolo más dos preguntas personalizadas:

Ventana de terminal
curl -X PATCH https://app.uspeech.io/api/projects/312/ \
-H "Authorization: Api-Key $USPEECH_KEY" \
-H "Content-Type: application/json" \
-d '{
"auto_analysis_enabled": true,
"auto_analysis_types": ["calls_analysis_no_protocol", "custom_questions"],
"auto_analysis_questions": ["¿Se ofreció una devolución de llamada?", "¿Se mencionó el descuento?"],
"auto_analysis_batch_size": 20,
"auto_analysis_max_wait_seconds": 300
}'

GET /api/projects/{id}/ devuelve los mismos campos, así que puedes consultar la configuración actual antes de cambiarla.


POST /api/files/ — idéntico a la subida de la API de Transcripción, y acepta los metadatos de la llamada en la misma petición.

Content-Type: multipart/form-data

CampoObligatorioDescripción
projectEl ID del proyecto.
fileLa grabación (mp3, wav, m4a, flac, ogg, mp4, …), o una transcripción srt/vtt.
file_typeaudio para grabaciones, o srt / vtt para transcripciones que ya tengas.
call_datetime, agent_id, agent_name, direction, caller_number, campaignnoMetadatos de la llamada — consulta Metadatos de Llamadas.

Los metadatos son opcionales aquí, pero aportarlos es lo que permite agrupar el informe por agente, dirección, campaña y fecha. Para cargas masivas puedes omitirlos al subir y enviar en su lugar un manifiesto CSV: las filas se emparejan con los archivos por nombre, incluidos los archivos subidos más tarde.

Ventana de terminal
curl -X POST https://app.uspeech.io/api/files/ \
-H "Authorization: Api-Key $USPEECH_KEY" \
-F "project=312" \
-F "file_type=audio" \
-F "file=@./call_001.mp3" \
-F "call_datetime=2026-06-15T09:12:00Z" \
-F "agent_id=A-06" \
-F "agent_name=Ana Diaz" \
-F "direction=inbound" \
-F "campaign=Retention"

⚠️ Importante: 201 Created significa que la subida se aceptó y se puso en cola. Tanto la transcripción como el análisis ocurren de forma asíncrona — consulta la sección de sondeo más abajo.

Un archivo subido con un nombre que el proyecto ya tenía se trata como la misma llamada: el nuevo registro sustituye al anterior en vez de añadir un segundo. Esto hace que los reintentos sean seguros: si una subida masiva falla a medias, repetirla no duplicará llamadas en el informe.


Las llamadas no se analizan de una en una, sino en lotes pequeños, y por eso los resultados aparecen en grupos en lugar de uno a uno.

Un lote de un tipo de análisis se envía cuando se cumple cualquiera de estas condiciones:

  • Hay auto_analysis_batch_size llamadas esperando — el lote sale de inmediato.
  • La llamada más antigua en espera alcanza auto_analysis_max_wait_seconds — un barrido que se ejecuta cada 60 segundos vacía el lote parcial.

Así, un lote parcial nunca se queda atascado: con los valores por defecto, una llamada suelta subida al final del día se analiza en unos cinco minutos. Si subes en tandas grandes, baja auto_analysis_max_wait_seconds solo si necesitas resultados antes — los lotes más pequeños cuestan más por llamada.


Hay dos niveles de visibilidad:

Por archivoGET /api/files/{id}/ informa del status de transcripción (transcribingtranscribed | failed) y de un campo auto_analysis_error que expone el motivo por el que se omitió el análisis automático de ese archivo, por ejemplo quota_exceeded cuando la suscripción se quedó sin minutos.

Por proyectoGET /calls/api/analysis-status/?project_id={id} es el endpoint que el propio panel consulta:

{
"analysis_status": {
"calls_analysis_no_protocol": { "completed": 57, "queued": 3 }
},
"analyzed_calls": 57,
"duplicate_uploads": 2,
"in_progress": true,
"reclustering": false,
"last_analyzed_at": "2026-07-29T02:50:11.127124+00:00"
}

Consúltalo hasta que in_progress sea false y entonces descarga el informe. Consulta Informes de Llamadas para la referencia completa de campos.

Ventana de terminal
while :; do
resp=$(curl -sS "https://app.uspeech.io/calls/api/analysis-status/?project_id=312" \
-H "Authorization: Api-Key $USPEECH_KEY")
in_progress=$(echo "$resp" | jq -r .in_progress)
echo "$(date -u +%H:%M:%S) analizadas=$(echo "$resp" | jq -r .analyzed_calls) in_progress=$in_progress"
[ "$in_progress" = "false" ] && break
sleep 30
done

💡 Consejo: consulta cada 30 segundos o más despacio. La transcripción tarda aproximadamente 1/8 de la duración del audio, y el análisis espera a que se llene un lote, así que sondear más rápido no aporta información nueva.


Cuando in_progress sea false, las llamadas analizadas están disponibles a través de la API de Informes de Llamadas:

  • GET /calls/api/report/?project_id={id} — el informe de calidad agregado
  • GET /calls/api/calls/?project_id={id} — el explorador de llamadas
  • GET /calls/api/custom-questions/?project_id={id} — respuestas por llamada a tus preguntas personalizadas
  • GET /calls/api/report/pdf/?project_id={id} — la exportación en PDF

Configura el proyecto, sube una carpeta de grabaciones, adjunta sus metadatos de llamada, espera al análisis y descarga el informe.

El paso de los metadatos importa: sin ellos las llamadas se analizan igualmente, pero el informe no tiene nada por lo que agruparlas — sin agente, sin dirección, sin campaña, y con la hora de subida haciendo de hora de la llamada. Hay dos formas de aportarlos, y puedes combinarlas:

  • Por archivo al subir, como campos adicionales del formulario en POST /api/files/ — ideal cuando tu sistema ya conoce los datos de cada llamada al subirla. Es lo que muestra el paso 2 más arriba.
  • Por proyecto, como manifiesto CSV en POST /api/projects/{id}/call-manifest/ — ideal para cargas masivas y para rellenar datos a posteriori. Las filas se emparejan con los archivos por nombre, y las que aún no coinciden con ninguno se guardan y se aplican a los archivos subidos más tarde, así que el manifiesto puede enviarse antes o después de las grabaciones.

El ejemplo de abajo usa el manifiesto, porque encaja con subir una carpeta entera de una vez. Consulta Metadatos de Llamadas para la referencia completa de campos, los formatos de fecha aceptados y cómo corregir los metadatos después.

#!/usr/bin/env bash
set -euo pipefail
BASE_URL="https://app.uspeech.io"
AUTH="Authorization: Api-Key ${USPEECH_KEY}"
project_id=312
# 1. Activar el análisis automático
curl -sS -X PATCH "${BASE_URL}/api/projects/${project_id}/" \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{"auto_analysis_enabled": true, "auto_analysis_types": ["calls_analysis_no_protocol"]}' \
> /dev/null
# 2. Subir todas las grabaciones de ./calls/
for path in ./calls/*.mp3; do
curl -sS -X POST "${BASE_URL}/api/files/" \
-H "$AUTH" \
-F "project=${project_id}" \
-F "file_type=audio" \
-F "file=@${path}" \
| jq -r '"subido \(.original_filename) -> \(.id)"'
done
# 3. Adjuntar los metadatos de llamada de todo el lote.
# llamadas_junio.csv: filename,call_datetime,agent_id,agent_name,direction,campaign
curl -sS -X POST "${BASE_URL}/api/projects/${project_id}/call-manifest/" \
-H "$AUTH" -F "file=@./llamadas_junio.csv" \
| jq -r '"\(.matched) asociadas, \(.unmatched | length) esperando su archivo"'
# 4. Esperar a que el análisis termine
while :; do
resp=$(curl -sS "${BASE_URL}/calls/api/analysis-status/?project_id=${project_id}" -H "$AUTH")
[ "$(echo "$resp" | jq -r .in_progress)" = "false" ] && break
sleep 30
done
# 5. Descargar el informe
curl -sS "${BASE_URL}/calls/api/report/?project_id=${project_id}" -H "$AUTH" > report.json
echo "informe escrito en report.json"

SíntomaCausa probable
El archivo llega a transcribed pero nunca se analiza nadaauto_analysis_enabled es false, o auto_analysis_types está vacío. Comprueba GET /api/projects/{id}/.
auto_analysis_error es quota_exceededLa suscripción se quedó sin minutos. El análisis se omite, no se reintenta automáticamente.
400 en la subida con un campo de metadatos en el cuerpoEl proyecto no es de llamadas, o file_type no es audio/srt/vtt.
400 al activar el análisis automáticoFalta la rúbrica para COPC, faltan preguntas para custom_questions, o el tamaño de lote está fuera de 120.
El recuento de llamadas del informe es menor que los archivos subidosLos nombres reutilizados sustituyen a la llamada anterior. duplicate_uploads en la respuesta de estado del análisis los cuenta.

Consulta Códigos de estado y errores para la lista completa de códigos de respuesta.