Ir al contenido

API de Informes de Llamadas

Todo lo que muestra el Informe del Centro de Atención está disponible como JSON: métricas principales, cuadro de calidad, tendencia semanal, motivos de contacto, desempeño de agentes y comparación de turnos, además de una tabla de llamadas que puedes recorrer y detallar.

Los usos habituales son llevar las cifras de cumplimiento a tu propia herramienta de BI, replicar las puntuaciones por llamada en un sistema de gestión de personal, y consultar el progreso mientras se analiza un lote de subidas.

Todos los endpoints aceptan una sesión de navegador o una clave API — consulta Autenticación. Los resultados se limitan a lo que puede ver quien llama, igual que en la aplicación web: tus proyectos, los proyectos compartidos contigo y todos los proyectos de los equipos que administras.


ParámetroTipoDescripción
project_idintLimita a un solo proyecto. Omítelo para agregar todos los proyectos de llamadas que puedas ver
teamintId del equipo, para acceso por equipo. Se ignora si no eres miembro de ese equipo
start_datedateInicio de la ventana, YYYY-MM-DD (inclusive)
end_datedateFin de la ventana, YYYY-MM-DD (inclusive, hasta las 23:59:59)
date_rangestringRango predefinido en lugar de fechas explícitas: mtd, last_month, last_30_days, last_90_days, ytd

project_id y team se aplican a todos los endpoints de esta página. Los parámetros de fecha se aplican al informe, a la exportación en PDF y a la lista de llamadas; los endpoints de detalle, estado del análisis, preguntas personalizadas y reagrupación se limitan por proyecto y los ignoran.

date_range tiene prioridad cuando se envía junto con fechas explícitas. Sin ningún parámetro de fecha se devuelve todo el histórico, a diferencia del informe web, que usa los últimos 30 días por defecto.


El informe agregado para los proyectos y la ventana seleccionados.

Respuesta (200 OK) — abreviada, con los arrays largos recortados a dos entradas:

{
"date_range": {
"start": "2026-05-01T00:00:00+00:00",
"end": "2026-07-30T00:00:00+00:00",
"preset": "last_90_days"
},
"total_calls_all_time": 57,
"headline": {
"total_calls": 57,
"analyzed_hours": 7.3,
"average_score": 74.2,
"weighted_compliance": 78.4,
"scored_calls": 57,
"critical_error_pct": 7.0,
"negative_sentiment_pct": 32.5,
"goal_reached_pct": 75.0,
"calls_with_metadata": 57
},
"scorecard": [
{
"criterion_id": "verification",
"name": "Verificación de identidad",
"section": "Apertura",
"weight_pct": 15.4,
"average_pct": 75.4,
"previous_pct": 71.0,
"delta_pct": 4.4,
"critical_errors": 0,
"calls": 40
}
],
"trend": [
{ "week": "2026-06-29", "calls": 10, "average_score": 65.0, "negative_sentiment_pct": 30.0 }
],
"contact_reasons": [
{ "topic": "Disputa de facturación", "calls": 8, "volume_pct": 20.0 }
],
"agents": [
{
"agent": "Ana Diaz",
"agent_id": 1,
"calls": 26,
"average_score": 72.7,
"critical_error_pct": 7.7,
"negative_sentiment_pct": 50.0,
"goal_reached_pct": 76.9
}
],
"shifts": [
{ "shift": "day", "total_calls": 46, "average_score": 74.8, "calls_with_metadata": 46 }
],
"shift_hours": { "day_start": 8, "day_end": 20 }
}

Cómo leer cada sección:

CampoSignificado
total_calls_all_timeLlamadas dentro del alcance antes del filtro de fechas. Si headline.total_calls es 0 y este no lo es, tu ventana está mal elegida
headlineResumen de volumen y calidad de la ventana. average_score es la media simple de las puntuaciones; weighted_compliance son los puntos obtenidos sobre los posibles, para que las rúbricas largas no se diluyan
scorecardUna fila por criterio de la rúbrica. previous_pct y delta_pct comparan con la ventana anterior inmediata de la misma duración, y son null salvo que envíes start_date y end_date
trendCubos semanales; week es el lunes de cada cubo
contact_reasonsMotivos principales por volumen. Una fila final con topic vacío y un recuento other_topics es el grupo «todo lo demás»
agentsResumen por agente. agent_id es el id interno del agente en Uspeech —el que se pasa al filtro agent del explorador— no tu propio agent_id de los metadatos
shiftsLa misma forma que headline más shift (day / night). Solo se clasifican las llamadas con fecha y hora reales
shift_hoursLa franja de turno día utilizada, según la configuración del proyecto

Los campos porcentuales son null en lugar de 0 cuando no había nada que medir en la ventana: ninguna llamada puntuada, ningún sentimiento, ningún resultado conocido.

Ejemplo:

Ventana de terminal
curl -H "Authorization: Api-Key $USPEECH_KEY" \
"https://app.uspeech.io/calls/api/report/?project_id=312&date_range=last_30_days"

Una tabla paginada y filtrable de las llamadas analizadas, que abarca todos los lotes de análisis de los proyectos seleccionados.

Parámetros adicionales:

ParámetroTipoDescripción
agentint / noneId de agente en Uspeech (el agents[].agent_id del informe), o none para llamadas sin agente
sentimentstringpositive, neutral o negative
directionstringinbound u outbound
criticalbooltrue devuelve solo las llamadas con error crítico
searchstringBusca en nombre de archivo, tema, motivo de contacto, número del cliente y campaña
orderingstringcall_datetime, score_percentage, mistake_count o agent__name, con - opcional delante. Por defecto -call_datetime
pageintNúmero de página; el tamaño de página es 25

Los valores desconocidos de sentiment, direction y ordering se ignoran en lugar de rechazarse.

Respuesta (200 OK):

{
"count": 57,
"next": "https://app.uspeech.io/calls/api/calls/?page=2",
"previous": null,
"results": [
{
"id": 28,
"file_id": 458,
"file_name": "call_027.mp3",
"call_datetime": "2026-07-28T09:15:00Z",
"agent": "Luis Gomez",
"direction": "inbound",
"campaign": "Retencion",
"topic": "Cambio de dirección",
"sentiment": "positive",
"score_percentage": 66.3,
"has_critical_error": false,
"mistake_count": 0,
"missing_prompt_count": 1,
"goal_reached": true
}
]
}

id es el id de la llamada para el endpoint de detalle; file_id es el archivo subido, que es lo que usan los endpoints de Transcripción y Metadatos de llamadas. topic es el motivo de contacto codificado una vez agrupado, y el tema extraído en bruto antes de eso.

Ejemplo — las llamadas entrantes peor puntuadas del mes:

Ventana de terminal
curl -H "Authorization: Api-Key $USPEECH_KEY" \
"https://app.uspeech.io/calls/api/calls/?date_range=mtd&direction=inbound&ordering=score_percentage"

Todo lo que se sabe de una llamada, combinado entre tipos de análisis.

Respuesta (200 OK):

{
"record": {
"id": 28,
"file_id": 458,
"file_name": "call_027.mp3",
"call_datetime": "2026-07-28T09:15:00Z",
"call_datetime_source": "manifest",
"agent": "Luis Gomez",
"direction": "inbound",
"campaign": "Retencion",
"caller_number": "+34600111222",
"topic": "Cambio de dirección",
"sentiment": "positive",
"score_percentage": 66.3,
"total_points": 19.89,
"max_possible_points": 30.0,
"has_critical_error": false,
"mistake_count": 0,
"missing_prompt_count": 1,
"goal_reached": true
},
"copc": { "…": "puntuaciones por criterio, justificaciones y citas" },
"no_protocol": { "…": "errores detectados y preguntas omitidas" },
"custom_questions": { "…": "respuestas a las preguntas personalizadas del proyecto" }
}

record es la fila del explorador más el número del cliente, los puntos en bruto y call_datetime_source. Las otras tres claves contienen el texto libre de cada tipo de análisis y son null cuando ese análisis no se ha ejecutado para la llamada. Su estructura interna sigue el formato de resultados del análisis y conviene inspeccionarla sobre una llamada real.

Errores: 404 cuando la llamada no existe o pertenece a un proyecto que no puedes ver.


Progreso del análisis automático de los proyectos seleccionados, pensado para consultarlo periódicamente mientras se procesan las subidas.

Respuesta (200 OK):

{
"analysis_status": {
"calls_analysis_copc": { "completed": 54, "queued": 3 },
"calls_analysis_no_protocol": { "completed": 57 }
},
"analyzed_calls": 57,
"duplicate_uploads": 2,
"in_progress": true,
"reclustering": false,
"last_analyzed_at": "2026-07-29T02:50:11.127124+00:00"
}
CampoSignificado
analysis_statusPor tipo de análisis, el número de llamadas en cada estado (queued, processing, completed, failed)
analyzed_callsLlamadas con resultados, sin aplicar filtro de fechas
duplicate_uploadsArchivos subidos con un nombre que el proyecto ya tenía. Son la misma llamada, así que un registro sustituye al anterior — por eso el número de archivos puede superar al de llamadas
in_progresstrue mientras haya análisis en cola o en curso — consulta hasta que sea false y vuelve a pedir el informe
reclusteringtrue mientras se reagrupan los motivos de contacto
last_analyzed_atMarca de tiempo del resultado más reciente, o null
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")
[ "$(echo "$resp" | jq -r .in_progress)" = "false" ] && break
sleep 30
done

Consulta Subir Llamadas para Análisis para el recorrido completo de subida y sondeo.


Respuestas por llamada a las preguntas personalizadas del proyecto, reunidas de todos los lotes.

Respuesta (200 OK):

{
"questions": ["¿Se ofreció una devolución de llamada?", "¿Se mencionó el descuento?"],
"calls": [
{
"call_analysis_id": 904,
"file": "call_027.mp3",
"call_datetime": "2026-07-28T09:15:00Z",
"agent": "Luis Gomez",
"answers": {
"¿Se ofreció una devolución de llamada?": { "answer": "Sí — el agente ofreció llamar el martes.", "quotes": 2 }
}
}
],
"count": 12
}

questions es la unión de las preguntas encontradas en las llamadas devueltas, en orden de aparición: úsala como lista de columnas. Una llamada analizada con un conjunto de preguntas anterior simplemente no tiene entrada para las nuevas. quotes cuenta las citas de la transcripción que respaldan la respuesta.

Los proyectos sin preguntas personalizadas devuelven arrays vacíos y count: 0.


Reagrupa bajo demanda los motivos de contacto abiertos, la misma acción que Actualizar motivos de contacto en el informe.

La reagrupación se encola para todos los proyectos abiertos accesibles; los proyectos con códigos predefinidos congelados clasifican cada llamada al llegar y se omiten, por lo que nunca aparecen en la respuesta. El trabajo se ejecuta en segundo plano: consulta reclustering en analysis-status para saber cuándo termina.

Respuesta (202 Accepted):

{ "reclustering": [312, 318], "count": 2 }

reclustering lista los ids de proyecto encolados. Las peticiones solapadas se descartan, así que llamar a este endpoint mientras ya hay una reagrupación en curso es inofensivo.

Ejemplo:

Ventana de terminal
curl -X POST -H "Authorization: Api-Key $USPEECH_KEY" \
"https://app.uspeech.io/calls/api/recluster/?project_id=312"

El mismo PDF listo para el cliente que genera el botón Exportar PDF del informe, con el resumen ejecutivo escrito por IA, para los filtros actuales.

Respuesta (200 OK): application/pdf como descarga de archivo. La generación es síncrona e incluye una llamada al modelo para las secciones narrativas, así que tarda bastante más que el endpoint JSON; si la narrativa falla, el PDF se devuelve igualmente con sus tablas y un aviso.

El documento se redacta en inglés por defecto. Envía Accept-Language: es para obtenerlo en español: una petición autenticada con clave API no tiene sesión de navegador, por lo que el idioma del perfil del usuario no se aplica aquí.

Ejemplo:

Ventana de terminal
curl -H "Authorization: Api-Key $USPEECH_KEY" \
-o informe_llamadas.pdf \
"https://app.uspeech.io/calls/api/report/pdf/?project_id=312&date_range=last_month"

EstadoCuándo
401 / 403Clave API ausente, mal formada, revocada o de un usuario inactivo
404En los endpoints de informe y PDF, cuando project_id apunta a un proyecto que no existe o que no puedes ver; en el de detalle, lo mismo con la llamada

Ojo con la asimetría: un project_id inalcanzable da 404 en el informe y en el PDF, pero en los endpoints de lista, estado, preguntas personalizadas y reagrupación simplemente no coincide con nada y obtienes un resultado vacío y a cero. Un resultado vacío nunca es un error en sí mismo: un proyecto que puedes ver sin llamadas analizadas se ve igual. Consulta Códigos de estado y errores para la estructura general de los errores.