> ## Documentation Index
> Fetch the complete documentation index at: https://muveya.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Analítica de gestión

> Cada métrica de gestión que calcula muveya, qué significa y dónde leerla: consola, API pública, MCP o exportación CSV.

muveya calcula un conjunto cerrado de métricas de gestión a partir de tus registros operativos: alertas de existencias, entregas, pedidos, aprobaciones, custodia y consumo. Esta página define cada una en palabras simples e indica dónde puedes leerla.

Todas comparten las mismas reglas:

* **Solo lectura y en vivo.** Una métrica se calcula cuando la pides, con los registros actuales. No se guarda ni se almacena en caché, salvo el archivo CSV de una exportación.
* **Deterministas.** Los mismos registros dan la misma cifra. Ninguna IA calcula ni reescribe una cifra.
* **Solo conteos, cantidades y duraciones.** Ninguna métrica incluye costos, valores de pedidos ni referencias de pacientes.
* **La misma cifra en todas partes.** La consola, la API pública y MCP ejecutan el mismo cálculo, así que la misma pregunta obtiene el mismo número en cada superficie.
* **UTC.** Toda fecha, ventana y agrupación está en UTC.

## Dónde vive cada capacidad

Hoy, la consola tiene una sola pantalla de analítica: [Reporte de consumo](/docs/es/reports/consumption). Todo lo demás se lee mediante la API pública con una clave de API o mediante MCP con OAuth. No hay pantalla en la consola para las demás métricas, para las exportaciones ni para crear claves de API; para obtener una clave, escribe a [team@muveya.com](mailto:team@muveya.com).

| Capacidad | Consola | API pública | Herramienta MCP |
| - | - | - | - |
| Métricas operativas (8 ids) | No | `GET /v1/analytics/metrics/{metric}` | No como herramienta. Los cinco conteos instantáneos están dentro de `management.briefing`. |
| Excepciones operativas | No | `GET /v1/analytics/exceptions` | Dentro de `management.briefing` |
| Comparación de sedes | No | `GET /v1/analytics/clinics/comparison` | `management.compare_clinics` |
| Tendencia de consumo | **Reportes** | `GET /v1/analytics/consumption-trend` | `analytics.consumption` |
| Pendientes de aprobación | No | `GET /v1/analytics/approval-backlog` | No como herramienta. Sus tramos están dentro de `management.briefing`. |
| Tiempo de ciclo del pedido | No | `GET /v1/analytics/cycle-time` | No como herramienta. Sus etapas están dentro de `management.briefing`. |
| Resumen gerencial | No | `GET /v1/analytics/briefing` | `management.briefing` |
| Exportación CSV del resumen | No | `POST /v1/analytics/exports`, `GET /v1/analytics/exports/{exportId}` | No |

Para los detalles técnicos de cada superficie, consulta [Exportaciones](/docs/es/api-reference/exports) y [Herramientas MCP](/docs/es/mcp/tools).

## Quién puede leerlas

| Superficie | Qué necesitas |
| - | - |
| Consola | El permiso de miembro `reports.read` (**Ver reportes**). Ningún rol lo incluye; se otorga en **Equipo**. |
| API pública | Una clave de API con el scope `analytics:read`. muveya lo traduce a `reports.read`. Consulta [Scopes](/docs/es/api-reference/scopes). |
| MCP | Una conexión OAuth con `analytics:read`, sujeta al permiso `reports.read` del miembro. Consulta [Conectar un cliente](/docs/es/mcp/connect). |

`reports.read` es suficiente: una métrica lee los pedidos, entregas y existencias subyacentes en tu nombre solo para contarlos, y nunca devuelve un campo que no podrías leer de otra forma. Una clave de API cubre todas las sedes y bodegas de su cuenta de clínica dental. Un miembro de la consola limitado a algunas bodegas ve el consumo solo de esas bodegas.

## Campos que comparten los resultados

La mayoría de los resultados incluye estos campos. La forma exacta de cada operación está en la referencia de la API.

| Campo | Significado |
| - | - |
| `metric` | El id de la métrica, por ejemplo `LOW_STOCK` u `ORDER_CYCLE_TIME`. |
| `definition` | La definición en palabras, siempre en inglés. Está en todos los reportes excepto la lista de excepciones, y en las tres métricas piloto. |
| `unit` | `count`, `percent`, `hours`, `orders` o una unidad de medida en el consumo. |
| `asOf` | Cuándo se calculó la cifra. |
| `freshness` | Siempre `live`. |
| `timezone` | Siempre `UTC`. |
| `evidenceId` | Una descripción estable de la métrica y sus filtros, por ejemplo `CONSUMPTION_TREND:catalogItemId=...,granularity=week`. La misma solicitud siempre cita el mismo `evidenceId`, así que puedes reproducir y citar una cifra. Nunca contiene la hora en que se calculó la cifra (`asOf`), pero sí incluye el `from` o `to` que envíes. |
| `truncated` | `true` cuando una lectura llegó a su límite. La cifra es entonces un mínimo, nunca un resultado completo silencioso. |
| `filters` | Los filtros aplicados. |

Un `value` igual a `null` significa que no hubo muestra para calcular un porcentaje, una mediana o un promedio. Nunca se reemplaza por cero.

### Límites de lectura

| Qué se lee | Límite | Al llegar al límite |
| - | - | - |
| Alertas de existencias abiertas | 500 alertas | `truncated: true` |
| Pedidos y entregas | 10.000 registros (200 por página, 50 páginas), del más antiguo al más reciente | `truncated: true`; quedan fuera los registros más recientes |
| Pedidos pendientes para los tramos de aprobación | 1000 pedidos, del más antiguo al más reciente | `truncated: true`; quedan fuera los pendientes más recientes |
| Movimientos de consumo | 5000 movimientos, del más reciente al más antiguo | `truncated: true` y `coverage.coveredFrom` |

## Métricas operativas

`GET /v1/analytics/metrics/{metric}` devuelve una cifra única. `{metric}` debe ser uno de estos ocho ids; cualquier otro valor se rechaza con `400` y `common.invalid_request`.

### Conteos instantáneos

Describen la situación actual. `catalogItemId` limita los dos conteos de existencias a un insumo.

| Id | Definición | Unidad |
| - | - | - |
| `LOW_STOCK` | Cantidad de alertas de existencias bajas abiertas en este momento (un insumo bajo su mínimo). | `count` |
| `EXPIRING_STOCK` | Cantidad de alertas de vencimiento abiertas en este momento (cajas cerca de su fecha de vencimiento). | `count` |
| `DELIVERY_EXCEPTIONS` | Cantidad de entregas en estado `exception` (una entrega confirmada como fallida). | `count` |
| `RECEIPT_DISCREPANCIES` | Cantidad de entregas en estado `partially_fulfilled` (al menos una caja se disputó en la recepción y la entrega aún no está cerrada). | `count` |
| `PENDING_ORDERS` | Cantidad de pedidos en estado `pending_approval`. | `count` |

### Señales piloto

Estas tres agregan `numerator`, `denominator` y `sampleCount` cuando aplican, una `definition` y advertencias legibles por máquina en `caveats`.

| Id | Definición | Unidad | Ventana | Advertencias |
| - | - | - | - | - |
| `BOX_TRACEABILITY` | La proporción de cajas activas cuya ubicación es identificable: una bodega conocida, un estado y un último movimiento en el registro de movimientos. `numerator` son las cajas trazables y `denominator` las cajas activas. | `percent` | Ninguna. Es una foto del momento; las semanas pasadas no se reconstruyen. `catalogItemId` se ignora. | `snapshot_of_now_not_reconstructed_for_past_windows` |
| `APPROVAL_DECISION_MEDIAN_HOURS` | La mediana del tiempo entre la solicitud de un pedido y su primera decisión de aprobación, sobre los pedidos solicitados en la ventana que recibieron una decisión humana. Los pedidos que siguen esperando y los aprobados automáticamente no entran en la muestra. | `hours` | `from` (incluido) y `to` (excluido), ambos opcionales, en ISO 8601 | `wall_clock_hours_no_business_calendar`, `orders_without_a_human_decision_excluded` |
| `DISTINCT_CUSTODY_ACTORS` | La proporción de traspasos recibidos en la ventana cuya entrega y recepción las confirmaron dos personas distintas. Una entrega sin ambas confirmaciones no entra en la muestra. | `percent` | `from` y `to`, igual que arriba, aplicados a la hora de recepción | `handoffs_without_both_confirmations_excluded` |

<Note>
  `wall_clock_hours_no_business_calendar` significa que las noches, los fines de semana y los feriados cuentan como horas. muveya todavía no aplica un calendario de horario hábil.
</Note>

Una ventana cuyo `from` no es anterior a `to`, o una fecha que no se puede leer, se rechaza con `400`. El resultado incluye `period` solo cuando envías `from` y `to`.

## Excepciones operativas

`GET /v1/analytics/exceptions` lista los problemas sobre los que un gerente debe actuar, del más urgente al menos urgente. `catalogItemId` limita las excepciones de existencias a un insumo.

| Prioridad | Categoría (`metric`) | Una entrada por | Detalle (`drillDownType`, `drillDownId`) | Campos de `reference` |
| - | - | - | - | - |
| 0 | `EXPIRING_STOCK` | alerta de vencimiento abierta | `movement` y el id del movimiento, o `item` y el id del insumo cuando ningún movimiento originó la alerta | `alertId`, `catalogItemId`, y `boxId`, `warehouseId` cuando se conocen |
| 1 | `DELIVERY_EXCEPTIONS` | entrega en `exception` | `order` y el id del pedido | `orderId` |
| 2 | `LOW_STOCK` | alerta de existencias bajas abierta | igual que `EXPIRING_STOCK` | igual que `EXPIRING_STOCK` |
| 3 | `RECEIPT_DISCREPANCIES` | entrega en `partially_fulfilled` | `order` y el id del pedido | `orderId` |
| 4 | `PENDING_ORDERS` | pedido en `pending_approval` | `order` y el id del pedido | `orderId`, `clinicId` |

Cada entrada tiene además `priority`, un `evidenceId` propio y, en las alertas de existencias, `detectedAt`. Las entradas se ordenan por prioridad y luego por id de detalle. El reporte agrega `total`.

Para seguir un detalle con la misma clave:

* `order`: `GET /v1/orders/{orderId}` y `GET /v1/fulfillments/{orderId}`.
* `movement`: el movimiento aparece en `GET /v1/inventory/boxes/{boxId}/movements`, con el `boxId` de `reference`.
* `item`: `GET /v1/catalog/items/{itemId}`.

Cada una de esas operaciones necesita su propio scope. Consulta [Scopes](/docs/es/api-reference/scopes).

## Comparación de sedes

`GET /v1/analytics/clinics/comparison` (métrica `ORDERS_BY_CLINIC`, unidad `orders`) ordena las sedes de tu cuenta por volumen de pedidos.

| Campo por sede | Significado |
| - | - |
| `clinicId`, `clinicName`, `clinicStatus` | La sede. Aparecen todas, incluso con cero pedidos. |
| `totalOrders` | Todos los pedidos de la sede, en cualquier estado, borradores incluidos. |
| `pendingApprovalOrders` | La parte de esos pedidos en `pending_approval`. |

Las sedes se ordenan por `totalOrders`, de mayor a menor, y luego por id. Nunca se incluyen valores de pedidos.

## Tendencia de consumo

`GET /v1/analytics/consumption-trend` (métrica `CONSUMPTION_TREND`) es el cálculo detrás del [Reporte de consumo](/docs/es/reports/consumption) de la consola.

| Parámetro | Valor por defecto | Regla |
| - | - | - |
| `from` | 30 días antes de `to` | ISO 8601, incluido |
| `to` | ahora | ISO 8601, excluido |
| `granularity` | `day` | `day` o `week` (las semanas empiezan el lunes) |
| `catalogItemId` | todos los insumos | un insumo |

La ventana debe tener `from` antes de `to` y abarcar como máximo 366 días; si no, `400`.

El resultado tiene una entrada en `series` por insumo y unidad (`seriesKey` es `catalogItemId:unitOfMeasure`), con `totalConsumed`, `usedQuantity` (uso observado), `issuedQuantity` (lo entregado a boxes o áreas que no cuentan sus existencias, un consumo estimado) y `movementCount`, además de `buckets` por día o semana. `usedQuantity + issuedQuantity = totalConsumed`. Nunca hay un total entre insumos o unidades.

`coverage` indica qué representan las cifras: `measuredMovementCount`, `unverifiedMovementCount` (registros anteriores a la unidad verificada, contados pero no cuantificados, listados por insumo en `unverifiedItems`), `warehouseScope` (`all` o `restricted`) y `coveredFrom` cuando la lectura se cortó. Se incluye una `narration` solo si pasa la verificación de que cada número coincide con la tabla.

## Pendientes de aprobación

`GET /v1/analytics/approval-backlog` (métrica `APPROVAL_BACKLOG`, unidad `orders`) cuenta los pedidos que esperan aprobación en toda la cuenta, agrupados por el tiempo que llevan esperando desde su solicitud.

| Tramo (`label`) | Tiempo de espera | `maxAgeHours` |
| - | - | - |
| `within_24h` | menos de 24 horas | `24` |
| `h24_to_72h` | de 24 horas a menos de 72 horas | `72` |
| `d3_to_7d` | de 72 horas a menos de 7 días | `168` |
| `over_7d` | 7 días o más | `null` |

También devuelve `total` y `oldestSubmittedAt`. Para la bandeja propia de quien aprueba, consulta [Aprobación de pedidos](/docs/es/orders/approvals).

## Tiempo de ciclo del pedido

`GET /v1/analytics/cycle-time` (métrica `ORDER_CYCLE_TIME`, unidad `hours`) da la duración promedio de cada etapa de la vida de un pedido, sobre los pedidos que llegaron a esa etapa.

| Etapa | Desde | Hasta |
| - | - | - |
| `submit_to_dispatch` | pedido solicitado | entrega despachada |
| `dispatch_to_deliver` | despachada | entrega confirmada |
| `deliver_to_receive` | entrega confirmada | recepción confirmada |
| `receive_to_close` | recepción confirmada | entrega cerrada |

Cada etapa tiene `averageHours` (dos decimales, `null` cuando ningún pedido llegó a ella) y `sampleCount`. `observedFulfillments` es la cantidad de entregas leídas. El promedio no se limita a una ventana. Consulta [Confirmar la entrega, recibir y cerrar](/docs/es/deliveries/delivery-and-receipt).

## Resumen gerencial

`GET /v1/analytics/briefing` (métrica `MANAGEMENT_BRIEFING`) es un resumen reproducible que reúne las métricas anteriores en una lista plana de cifras. `period` es `daily` (por defecto) o `weekly`; cualquier otro valor es `400`.

Cada cifra tiene `metric` (su origen), `dimension` (la subclave, ausente en una cifra única), `label`, `value`, `unit` y el `evidenceId` de su origen. Las cifras llegan en este orden:

| Cifras | `metric` | `dimension` | Etiqueta (español) | `unit` |
| - | - | - | - | - |
| Cinco conteos instantáneos | `LOW_STOCK`, `EXPIRING_STOCK`, `DELIVERY_EXCEPTIONS`, `RECEIPT_DISCREPANCIES`, `PENDING_ORDERS` | ninguna | Alertas bajo el mínimo, Alertas de cajas por vencer, Excepciones de entrega, Discrepancias de recepción, Aprobaciones pendientes | `count` |
| Cuatro tramos de espera | `APPROVAL_BACKLOG` | el tramo | Aprobaciones pendientes: menos de 24 horas, de 24 a 72 horas, de 3 a 7 días, más de 7 días | `orders` |
| Registros de consumo | `CONSUMPTION_TREND` | `movements` | Movimientos de consumo | `movements` |
| Registros sin unidad verificada | `CONSUMPTION_TREND` | `unverified_movements` | Movimientos de consumo sin unidad verificada | `movements` |
| Hasta cinco insumos, tres cifras cada uno | `CONSUMPTION_TREND` | `seriesKey`, `seriesKey:use`, `seriesKey:issue` | el nombre del insumo; `nombre: uso observado`; `nombre: entregado a salas (consumo estimado)` | la unidad del insumo (por ejemplo `box`) |
| Cuatro etapas del ciclo | `ORDER_CYCLE_TIME` | la etapa | Tiempo de ciclo: de solicitud a despacho, de despacho a entrega, de entrega a recepción, de recepción a cierre | `hours` |

Qué cambia con `period`:

* La parte de consumo siempre cubre la ventana por defecto de la métrica de consumo, los últimos 30 días. `daily` la agrupa por día y `weekly` por semana. Como el resumen lista totales, hoy las cifras de un resumen diario y de uno semanal son las mismas; solo cambia el `evidenceId` del consumo.
* Los conteos instantáneos, los tramos de espera y el tiempo de ciclo no se limitan a un día ni a una semana.

Las etiquetas siguen el idioma de quien lee: el encabezado `Accept-Language` en la API (`en`, `es` o `pt`; inglés en otro caso) y el encabezado `Accept-Language` en MCP, con inglés como alternativa. Los ids, dimensiones, unidades, valores y `evidenceId` nunca cambian con el idioma. Un insumo que el catálogo no puede nombrar se etiqueta `Insumo desconocido`.

El `evidenceId` propio del resumen es `MANAGEMENT_BRIEFING:period=daily` o `MANAGEMENT_BRIEFING:period=weekly`, y `truncated` es `true` si alguno de sus orígenes quedó truncado. En MCP, `management.briefing` devuelve este resumen junto con las excepciones operativas.

## Exportaciones CSV

El resumen se puede exportar como archivo CSV. Las exportaciones se solicitan y se recogen solo mediante la API pública. Las formas completas de solicitud y respuesta están en [Exportaciones](/docs/es/api-reference/exports).

<Steps>
  <Step title="Solicita la exportación">
    `POST /v1/analytics/exports` con un `period` opcional (`daily` por defecto, o `weekly`). El encabezado `Accept-Language` de esta solicitud fija el idioma de las etiquetas del CSV. La respuesta es `202` con un `exportId` y el `status` del trabajo.
  </Step>

  <Step title="Consulta hasta que esté listo">
    `GET /v1/analytics/exports/{exportId}` devuelve el estado actual. El archivo se genera en segundo plano, así que la primera respuesta suele ser `pending`, aunque puede llegar ya como `ready`.
  </Step>

  <Step title="Descarga">
    Cuando `status` es `ready`, la respuesta trae `downloadUrl` y `downloadExpiresAt`. El enlace funciona 5 minutos. Cada consulta crea un enlace nuevo, así que vuelve a consultar si venció. El archivo se llama `management-briefing-daily.csv` o `management-briefing-weekly.csv`.
  </Step>

  <Step title="Verifica">
    Compara el SHA-256 de los bytes descargados con `checksum`, y el tamaño con `byteSize`.
  </Step>
</Steps>

### Estados de la exportación

| `status` | Significado |
| - | - |
| `pending` | Aceptada, aún no generada. |
| `building` | El archivo se está componiendo. |
| `ready` | El archivo está guardado. Están presentes `byteSize`, `checksum`, `downloadUrl` y `downloadExpiresAt`. |
| `failed` | La generación falló. `error` contiene un código de motivo sin datos sensibles: `schedule_failed` (el trabajo no se pudo encolar; la propia solicitud falla entonces con `500`, así que solicita una nueva exportación), `processing_error` (una falla temporal; la generación se reintenta automáticamente). |

### Reglas

* **Vencimiento.** Un trabajo de exportación se conserva 7 días. Después, `GET /v1/analytics/exports/{exportId}` responde `404`. Un enlace de descarga dura 5 minutos y nunca es permanente.
* **Aislamiento.** Un `exportId` solo funciona con una clave de la misma cuenta de clínica dental. Cualquier otro id responde `404`, sin decir si existe en otra parte.
* **Omisión de datos.** El archivo contiene solo conteos, cantidades, duraciones, etiquetas e ids de evidencia. No puede contener costos, valores de pedidos ni referencias de pacientes.
* **Formato.** UTF-8 con marca de orden de bytes (para que las hojas de cálculo lean bien los acentos), fin de línea CRLF y las columnas `metric`, `dimension`, `label`, `value`, `unit`, `evidenceId`. Una cifra sin muestra tiene la celda `value` vacía, nunca `0`. Una celda que empieza con `=`, `+`, `-`, `@`, una tabulación o un retorno de carro lleva un apóstrofo delante, para que una hoja de cálculo nunca la ejecute como fórmula.
* **Auditoría.** Cada solicitud escribe el registro de auditoría `analytics.export`. Un archivo terminado escribe `analytics.export_built` con su checksum y tamaño, que perdura más allá de los 7 días del trabajo. Una clave sin `analytics:read` se rechaza con `403` antes de solicitar la exportación, y ese rechazo no escribe ningún registro de auditoría.

## Qué puede salir mal

| HTTP | `code` | Causa | Qué hacer |
| - | - | - | - |
| `400` | `common.invalid_request` | Id de métrica desconocido, ventana ilegible o invertida, ventana de consumo de más de 366 días, `granularity` o `period` desconocidos. | Corrige el parámetro. |
| `401` | `api_keys.invalid` | Clave de API ausente, inválida o revocada. | Consulta [Autenticación](/docs/es/api-reference/authentication). |
| `403` | `api_keys.scope_missing` | La clave no tiene `analytics:read`. | Pide a [team@muveya.com](mailto:team@muveya.com) una clave con ese scope. |
| `404` | `common.not_found` | `exportId` desconocido o vencido. | Solicita una nueva exportación. |
| `429` | `common.too_many_requests` | Demasiadas solicitudes con la clave. | Consulta [Límites de uso](/docs/es/api-reference/rate-limits). |

El formato completo de los errores está en [Errores](/docs/es/api-reference/errors).

## Páginas relacionadas

<CardGroup cols={2}>
  <Card title="Reporte de consumo" icon="chart-column" href="/docs/es/reports/consumption">
    La pantalla de la consola para el consumo por insumo.
  </Card>

  <Card title="Exportaciones" icon="file-csv" href="/docs/es/api-reference/exports">
    Solicita y consulta una exportación del resumen.
  </Card>

  <Card title="Herramientas MCP" icon="plug" href="/docs/es/mcp/tools">
    `analytics.consumption`, `management.briefing`, `management.compare_clinics`.
  </Card>

  <Card title="Reposición y alertas" icon="bell" href="/docs/es/inventory/replenishment-and-alerts">
    De dónde salen las alertas de existencias bajas y de vencimiento.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.