> ## 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.

# API para desarrolladores

> Qué cubre la API pública de muveya, su URL base, las convenciones que siguen todas las respuestas y cómo está organizada esta referencia.

La API pública de muveya es una interfaz REST bajo `/v1` pensada para integraciones del lado del servidor: un ERP o sistema de compras, una herramienta de BI, una hoja de cálculo automatizada, un tablero interno. Se autentica con una **clave de API** que pertenece a una sola clínica dental y lee los mismos datos con los que tu equipo trabaja en la consola.

La API es **de solo lectura**, con una excepción: `POST /v1/analytics/exports`, que pide a muveya generar un archivo CSV del resumen gerencial. Nada de lo que llames en `/v1` crea, cambia ni elimina un pedido, una caja, un movimiento de existencias, un miembro o un insumo del catálogo.

## URL base

```text theme={null}
https://api.muveya.com
```

Todas las rutas públicas empiezan con `/v1`, así que tu primera llamada es `https://api.muveya.com/v1/me`.

## Autenticación en una línea

```bash theme={null}
curl https://api.muveya.com/v1/me \
  -H "Authorization: Bearer $MUVEYA_API_KEY"
```

La clave se envía como token bearer en cada solicitud. El servidor la asocia a una clínica dental: ninguna ruta, parámetro ni encabezado nombra una clínica dental, así que una clave solo puede leer la suya. Consulta [Autenticación](/docs/es/api-reference/authentication) para saber cómo obtener una clave y protegerla.

## Palabras de la consola y palabras de la API

La consola y la API describen lo mismo con palabras distintas. Tenlas presentes al relacionar los datos de la API con lo que las personas ven en pantalla.

| En la consola | En la API |
| - | - |
| **Clínica dental** (tu espacio de trabajo) | El espacio de trabajo al que pertenece la clave. `GET /v1/me` lo devuelve como `workspaceId`. Nunca aparece en una ruta. |
| **Sedes** | `clinics`: `GET /v1/clinics`, `clinicId` |
| **Bodegas** | `warehouses`: `GET /v1/warehouses`, `warehouseId`. Una bodega `central` atiende a toda la clínica dental; una bodega `express` pertenece a una sede. |
| **Catálogo** | Insumos y categorías del catálogo: `itemId`, `catalogItemId`, `categoryId` |
| **Inventario** | Cajas de existencias, sus saldos y sus movimientos en el registro: `boxId`, `movementId` |
| **Pedidos** y **Aprobación de pedidos** | Pedidos, sus líneas y su plan de aprobación: `orderId`, `lineId` |
| **Entregas** | `fulfillments` (registros de entrega) e historial de custodia, identificados por `orderId` |
| **Reportes** | `analytics` (analítica): métricas, excepciones, consumo, resumen gerencial |

## Qué cubre `/v1`

| Operación | Scope | Qué obtienes |
| - | - | - |
| `GET /v1/me` | Cualquier clave válida | La clínica dental (`workspaceId`), el `environment` de la clave y sus `scopes` |
| `GET /v1/clinics` | `clinics:read` | Todas las sedes con su nombre y estado |
| `GET /v1/warehouses` | `clinics:read` | Todas las bodegas con su tipo (`central` o `express`) y estado |
| `GET /v1/catalog/items` | `catalog:read` | Todos los insumos del catálogo, sin importar su estado |
| `GET /v1/catalog/items/{itemId}` | `catalog:read` | Un insumo del catálogo |
| `GET /v1/catalog/categories` | `catalog:read` | Todas las categorías |
| `GET /v1/inventory/balances` | `inventory:read` | Cantidades en mano (`onHand`), reservadas (`reserved`) y disponibles (`available`) por caja, paginadas y filtrables por `catalogItemId` y `warehouseId` |
| `GET /v1/inventory/boxes/{boxId}` | `inventory:read` | Una caja: código, insumo, bodega, estado, lote, números de serie, vencimiento, origen |
| `GET /v1/inventory/boxes/{boxId}/balance` | `inventory:read` | Las cantidades de una caja |
| `GET /v1/inventory/boxes/{boxId}/movements` | `inventory:read` | Los movimientos de una caja en el registro, del más antiguo al más reciente |
| `GET /v1/orders` | `orders:read` | Pedidos, paginados y filtrables por `status` |
| `GET /v1/orders/{orderId}` | `orders:read` | Un pedido con sus líneas y su plan de aprobación |
| `GET /v1/fulfillments` | `fulfillment:read` | Registros de entrega, paginados y filtrables por `status` |
| `GET /v1/fulfillments/{orderId}` | `fulfillment:read` | El historial de custodia de un pedido: movimientos, entrega, recepción y cierre |
| `GET /v1/analytics/metrics/{metric}` | `analytics:read` | Una métrica operativa con su evidencia |
| `GET /v1/analytics/exceptions` | `analytics:read` | Excepciones operativas, de mayor a menor prioridad |
| `GET /v1/analytics/clinics/comparison` | `analytics:read` | Sedes comparadas por volumen de pedidos |
| `GET /v1/analytics/consumption-trend` | `analytics:read` | Consumo por insumo en su propia unidad a lo largo del tiempo |
| `GET /v1/analytics/approval-backlog` | `analytics:read` | Aprobaciones pendientes agrupadas por antigüedad |
| `GET /v1/analytics/cycle-time` | `analytics:read` | Duración promedio de cada etapa del pedido |
| `GET /v1/analytics/briefing` | `analytics:read` | El resumen gerencial diario o semanal |
| `POST /v1/analytics/exports` | `analytics:read` | Pide una exportación CSV del resumen gerencial (la única escritura) |
| `GET /v1/analytics/exports/{exportId}` | `analytics:read` | El estado de una exportación y, cuando está lista, su enlace de descarga |

Cada scope se explica en [Scopes](/docs/es/api-reference/scopes). La solicitud y la respuesta de cada operación están documentadas en el grupo **Endpoints** de esta pestaña.

## Qué no hace `/v1`

* No crea ni cambia nada de tu operación: pedidos, aprobaciones, preparación, despacho, entrega, recepción, ingresos de existencias, consumos, traslados, correcciones, conteos, cambios de catálogo y cambios del equipo se hacen en la consola (consulta [Introducción](/docs/es/introduction)), y algunas tareas de existencias desde WhatsApp (consulta [Canal de WhatsApp](/docs/es/whatsapp/overview)).
* No crea ni revoca claves de API. Consulta [Autenticación](/docs/es/api-reference/authentication).
* No envía eventos a tus sistemas. Todavía no hay webhooks; consulta [Webhooks](/docs/es/api-reference/webhooks) para saber cómo consultar periódicamente.
* Nunca devuelve totales de pedidos ni referencias de pacientes (consulta [Datos que se omiten](#datos-que-se-omiten)).

## Convenciones

**JSON en todo.** Las respuestas exitosas son `application/json`. Los errores son documentos `application/problem+json` con un `code` estable (consulta [Errores](/docs/es/api-reference/errors)). Los nombres de campos están en inglés con formato camelCase y los valores de enumeraciones son palabras en inglés en minúsculas, como `pending_approval`; las claves de métricas van en mayúsculas, como `LOW_STOCK`. Ninguno cambia con el idioma.

**Ids opacos.** Todos los ids son cadenas de texto. Compáralos como texto y nunca los interpretes ni los construyas. Un id que pertenece a otra clínica dental se comporta exactamente igual que un id inexistente: la respuesta es `404`.

**Ausente, no null.** Un campo opcional sin valor, o que tu clave no puede ver, se omite de la respuesta. No se envía como `null` ni como `0`. Las excepciones son tres campos de analítica: `value` (de una métrica o de una cifra del resumen) y `averageHours` (de una etapa del tiempo de ciclo) son `null` cuando no hubo muestra para medir, y `maxAgeHours` es `null` en el tramo abierto de los pendientes de aprobación.

**Fechas en UTC.** Las fechas y horas son cadenas ISO 8601 en UTC con el sufijo `Z`, por ejemplo `2026-09-15T13:45:00.000Z`. Los reportes de analítica indican `"timezone": "UTC"`. Las ventanas de tiempo que envías (`from`, `to`) también van en ISO 8601.

**Dinero en unidades menores.** Un importe es un entero en la unidad menor de su moneda (centavos para USD) y siempre viaja con `currency`, un código ISO 4217: `"cost": 1250, "currency": "USD"` significa 12,50 USD. El dinero solo aparece en los campos de costo del catálogo y en el `unitCost` de las líneas de pedido, y solo para una clave con `catalog.cost:read`.

**Cantidades en la unidad del insumo.** Cantidades como `onHand`, `requestedQty` o `quantityDelta` son enteros contados en la `unitOfMeasure` del insumo (`unit`, `box`, `milliliter`, etc.). La API nunca suma cantidades de insumos o unidades distintas.

**Idioma.** Envía `Accept-Language` con `en`, `es` o `pt` (el inglés es el valor por defecto). Solo cambia el texto pensado para personas: el `title` y el `detail` de un error, la `label` de cada cifra del resumen gerencial y las etiquetas dentro de una exportación CSV. Claves, códigos, valores de enumeraciones, números e ids son iguales en todos los idiomas.

**Ids de solicitud.** Toda respuesta incluye el encabezado `x-request-id`. Si envías tu propio `X-Request-Id` con un UUID, muveya lo reutiliza; si no, genera uno. Los cuerpos de error lo repiten como `requestId`. Regístralo en tu sistema e inclúyelo cuando escribas a [team@muveya.com](mailto:team@muveya.com).

**Listas.** Toda lista responde `{ "data": [...], "hasMore": false }`, más `nextCursor` cuando hay otra página. Consulta [Paginación](/docs/es/api-reference/pagination).

**Límites de uso.** Cada clave tiene su propio presupuesto de solicitudes y cada respuesta lo informa en encabezados. Consulta [Límites de uso](/docs/es/api-reference/rate-limits).

**Estabilidad.** Dentro de `/v1` los cambios son aditivos. Consulta [Versionado y estabilidad](/docs/es/api-reference/versioning) y [Novedades](/docs/es/changelog).

## Datos que se omiten

El servidor quita los datos que tu clave no puede ver antes de construir la respuesta. Los campos se omiten, nunca se enmascaran.

| Dato | Cuándo lo devuelve `/v1` |
| - | - |
| `cost`, `currency`, `costStatus`, `costMeasurement` del catálogo | Solo con `catalog.cost:read` |
| `unitCost` y `currency` de las líneas de pedido | Solo con `catalog.cost:read` |
| `value`, `currency` y `approvalPlan.evaluatedValue` del pedido | Nunca. Ningún scope de la API da acceso a valores de pedidos. |
| `patientRef` de un pedido clínico | Nunca. Ningún scope de la API da acceso a referencias de pacientes. |
| Analítica y exportaciones del resumen gerencial | Solo conteos, cantidades y duraciones. Nunca costos, valores ni referencias de pacientes. |

Una clave de API no es un miembro del equipo y no está limitada por el acceso a sedes: lee **todas las sedes y bodegas** de su clínica dental dentro de sus scopes. Da a cada clave solo los scopes que la integración necesita.

## Cómo está organizada esta referencia

* **Resumen** (estas páginas): autenticación, guía rápida, scopes, paginación, límites de uso, errores, versionado, exportaciones y webhooks.
* **Endpoints**: una página por operación, generada a partir del contrato OpenAPI de muveya, en tu idioma. Cada página muestra los parámetros, el esquema de respuesta, los errores posibles y ejemplos de solicitud en cURL, JavaScript y Python. El constructor de solicitudes de esas páginas solo prepara una solicitud para que la copies: nunca la envía y nunca guarda tu clave.

<Note>
  El servidor MCP en `https://api.muveya.com/mcp` usa ingreso y autorización con OAuth para asistentes de IA. Consulta [Servidor MCP](/docs/es/mcp/introduction).
</Note>

<CardGroup cols={2}>
  <Card title="Autenticación" icon="key" href="/docs/es/api-reference/authentication">
    Obtén una clave, envíala y mantenla en tu servidor.
  </Card>

  <Card title="Guía rápida" icon="rocket" href="/docs/es/api-reference/quickstart">
    Tus primeras llamadas con cURL, JavaScript y Python.
  </Card>

  <Card title="Scopes" icon="shield-halved" href="/docs/es/api-reference/scopes">
    Qué permite leer cada scope.
  </Card>

  <Card title="Errores" icon="triangle-exclamation" href="/docs/es/api-reference/errors">
    El documento de problema y todos los códigos de error.
  </Card>
</CardGroup>


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