Datos para agentes
KPIs
Los KPIs son las mismas cifras que ve una persona en los paneles de Olympus, calculadas con los mismos
permisos, en una API con contrato propio. Solo para claves de agente: una clave de integración recibe
403 agent_required.
El catálogo: GET /kpis
Sección titulada «El catálogo: GET /kpis»Antes de pedir cifras, un agente debería saber qué significa cada una. GET /kpis devuelve, solo para los
KPIs que este agente puede leer, el endpoint, su módulo, sus parámetros y la definición de cada cifra con su
unidad (importe, porcentaje, días, meses, unidades). No devuelve datos del negocio.
curl https://olympus.atharix.com/api/v1/kpis -H "X-API-Key: $OLYMPUS_AGENT_KEY"El ejemplo completo está en Crear un agente.
Los endpoints
Sección titulada «Los endpoints»| Endpoint | Qué trae | Módulo | Periodo |
|---|---|---|---|
GET /kpis/summary | Resumen ejecutivo: ventas del mes y su variación, productos que más venden, dinero por cobrar, proyección a 30 días, notas de crédito, retenciones y serie de 6 meses | inicio.resumen | Siempre el mes en curso |
GET /kpis/sales | Top 10 productos, proyección a 30 días, ticket medio, crecimiento, concentración en los 5 mejores clientes y resumen frente al periodo anterior | inicio.resumen | desde · hasta |
GET /kpis/receivables | Volumen de comprobantes, ratio de notas de crédito, tasa de autorización, DSO, antigüedad de la cartera, facturas del periodo y vencidas | analisis.finanzas | desde · hasta |
GET /kpis/withholdings | Retenciones emitidas y recibidas, por tipo de impuesto y por semana. Pensado para Ecuador | analisis.finanzas | desde · hasta |
GET /kpis/purchases | Compras, concentración en proveedores, antigüedad de lo que se debe, DPO, gastos, órdenes de compra abiertas y próximos pagos | compras.facturas | desde · hasta |
GET /kpis/finance | Caja por cuenta, flujo de caja diario, cobros frente a pagos, runway y conciliación bancaria | analisis.finanzas | desde · hasta |
GET /kpis/inventory | Valor del inventario por bodega, alertas de stock, rotación, productos de más valor, movimientos y stock sin salida | inventario.stock | desde · hasta |
GET /kpis/daily | Por día: ventas, compras, costo de ventas y beneficio, con totales | inicio.resumen | desde · hasta |
GET /kpis/recurring | MRR, ARR, ARPA, NRR, churn, movimientos, cohortes, cobro, renovaciones y suscripciones en riesgo | ventas.suscripciones | mes |
Parámetros
Sección titulada «Parámetros»| Parámetro | Formato | Qué hace |
|---|---|---|
desde | AAAA-MM-DD | Inicio del periodo. Por defecto, el día 1 del mes en curso |
hasta | AAAA-MM-DD | Fin del periodo. Por defecto, hoy |
sucursal | UUID | Acota a una sucursal: el id que devuelve GET /establishments. Un agente limitado a sus sucursales solo puede pedir las suyas |
mes | AAAA-MM | Solo en /kpis/recurring. Por defecto, el mes en curso |
- Periodo efectivo. Sin fechas, del día 1 del mes en curso a hoy; solo con
hasta, del día 1 de ese mes ahasta; solo condesde, dedesdea hoy. Es el que se calcula y el que devuelvemeta.periodo. - Rango máximo: 366 días de periodo efectivo. Si pasa:
422range_too_large. Para periodos largos, pide un año cada vez. desdeposterior ahasta, o una fecha mal escrita:400validation_error.sucursales elid(UUID) del establecimiento, no su código del SRI (001). Los dos vienen enGET /establishments.
La respuesta
Sección titulada «La respuesta»Todas las respuestas de datos tienen la misma forma: meta con el contexto y datos con las cifras.
curl "https://olympus.atharix.com/api/v1/kpis/sales?desde=2026-09-01&hasta=2026-09-30" \ -H "X-API-Key: $OLYMPUS_AGENT_KEY"ventas = olympus.get("/kpis/sales", params={"desde": "2026-09-01", "hasta": "2026-09-30"}).json()resumen = ventas["datos"]["period_summary"]print(f"{resumen['total']:.2f} {ventas['meta']['moneda']} en {resumen['invoice_count']} facturas")const url = "https://olympus.atharix.com/api/v1/kpis/sales?desde=2026-09-01&hasta=2026-09-30";const ventas = await (await fetch(url, { headers: { "X-API-Key": process.env.OLYMPUS_AGENT_KEY } })).json();const resumen = ventas.datos.period_summary;console.log(`${resumen.total.toFixed(2)} ${ventas.meta.moneda} en ${resumen.invoice_count} facturas`);Respuesta (recortada a tres bloques):
{ "meta": { "moneda": "USD", "sucursal": null, "generado_en": "2026-10-12T15:31:07.418204+00:00", "definiciones": "/api/v1/kpis", "periodo": { "desde": "2026-09-01", "hasta": "2026-09-30" }, "datos_personales": "enmascarados" }, "datos": { "top_products": [ { "id": "4b8e1c2a-7d3f-4a9b-8e6c-1f2a3b4c5d6e", "name": "Servicio de soporte mensual", "total_quantity": 96.0, "total_revenue": 9600.0 }, { "id": "9c2d4e6f-1a3b-4c5d-8e7f-0a1b2c3d4e5f", "name": "Mantenimiento preventivo", "total_quantity": 40.0, "total_revenue": 7200.0 }, { "id": "2e4f6a8b-3c5d-4e7f-9a1b-2c3d4e5f6a7b", "name": "Instalación de red", "total_quantity": 12.0, "total_revenue": 5400.0 } ], "average_ticket": 225.0, "period_summary": { "total": 48150.0, "invoice_count": 214, "average_ticket": 225.0, "customer_count": 87, "previous_total": 43065.0, "previous_invoice_count": 198, "previous_average_ticket": 217.5, "growth_pct": 11.81, "invoice_count_growth_pct": 8.08, "average_ticket_growth_pct": 3.45 } }}Las ventas de producto (total_revenue) van sin impuestos; los totales de factura (total), con impuestos. El
periodo anterior es uno de la misma duración justo antes: aquí, 30 días, del 2 al 31 de agosto.
| Campo | Qué es |
|---|---|
moneda | Moneda del negocio. Todos los importes están convertidos a ella |
sucursal | La sucursal pedida, o null |
generado_en | Cuándo se calcularon las cifras, en UTC. Si vienen de la caché, hasta 60 segundos antes de la respuesta |
definiciones | Dónde leer qué significa cada cifra: /api/v1/kpis |
periodo | desde y hasta con los que se calcularon las cifras, también cuando no enviaste fechas. No aparece en summary ni en recurring; en los listados es null |
datos_personales | "visibles" o "enmascarados", según el agente tenga datos.personales |
Claves en snake_case
Sección titulada «Claves en snake_case»Las claves de datos van en snake_case, convertidas de forma mecánica desde los nombres internos. Las que
llevan números quedan así, y son estables:
| Bloque | Claves |
|---|---|
Antigüedad de la cartera (aging_receivables) | current, 1_to30_days, 31_to60_days, 61_to90_days, over90_days, total_outstanding |
Proyección (projected_revenue30d) | total, from_subscriptions, from_open_orders |
Concentración en clientes (customer_concentration) | total_revenue, top_customers, top_ncombined_percentage |
Por ejemplo, la cartera de /kpis/receivables:
{ "aging_receivables": { "current": 12480.0, "1_to30_days": 6215.5, "31_to60_days": 2940.0, "61_to90_days": 1120.0, "over90_days": 865.25, "total_outstanding": 23620.75 }, "overdue": { "count": 37, "amount": 11140.75, "oldest_due_date": "2026-05-18" }, "dso": { "average_days": 38.4, "paid_invoices_in_period": 162 }}overdue.amount es la cartera vencida: el total menos lo que está al día (23.620,75 − 12.480,00 = 11.140,75).
Bloques ocultos y de todo el negocio
Sección titulada «Bloques ocultos y de todo el negocio»Un KPI nunca devuelve una cifra que el agente no debería ver, y nunca la de todo el negocio sin avisar:
| Lo verás | Qué significa |
|---|---|
"scope": "business" | La cifra es de todo el negocio aunque pidas una sucursal: caja, flujo, conciliación, runway, gastos, ingresos recurrentes |
"scope": "assigned" | Acotada a las sucursales del agente, más estrecha que el resto del panel (órdenes de compra) |
"hidden": true y "hidden_reason": "no_access" | El bloque es de un módulo que el agente no tiene. Llega con la forma de siempre, las cifras a null y las listas vacías |
"hidden": true y "hidden_reason": "branch_scope" | El agente solo ve sus sucursales y ese dato no se puede acotar a ellas |
Campos a null en summary | Sin analisis.finanzas: dinero por cobrar, ratio de notas de crédito y retenciones. Sin compras.facturas: las compras de la serie mensual |
Campos que no están en daily | Sin compras.facturas no llega purchases; sin costos.ver, ni cogs ni profit |
null en el valor del inventario | Sin costos.ver: valor, costo de ventas, rotación y días de stock |
scope aparece en /kpis/purchases, /kpis/finance y /kpis/recurring; hidden, en los bloques de gastos
(expenses_summary) y órdenes de compra (purchase_orders_pipeline) de /kpis/purchases.
Caché y consumo
Sección titulada «Caché y consumo»- Cada respuesta se guarda 60 segundos por agente, permisos y parámetros. Pedir lo mismo cada segundo
no recalcula nada: devuelve la misma cifra. Si cambian los permisos del agente, la caché no se reutiliza.
meta.generado_endice cuándo se calcularon, así que sabes de cuándo son. - Los elementos de las listas de la respuesta cuentan como registros leídos para el tope diario del agente
(
max_daily_rows_read, 20 000 por defecto). Una respuesta grande puede pasar el tope; la siguiente lectura se rechaza. Ver Autonomía y límites.
Lo siguiente
Sección titulada «Lo siguiente»- Listados: gastos, compras, contactos, productos y cotizaciones, fila a fila.
- Reportes contables: balance, resultados, mayor y diario.