Files
OmniRoute/docs/i18n/es/docs/reference/API_REFERENCE.md
Diego Rodrigues de Sa e Souza b637350680 fix(docs): re-sync the 65 documentation mirror sets; section-level docs pipeline; drift gate blocking (#13940)
1,104 mirrors rewritten over five passes of run-translation on the 22-source core set: the 14 sources edited since their translation, the 322 mirrors that were still English copies, and the frontmatter the old extractor leaked into the newer locales' bodies. The pipeline now caches per-`## `-section hashes and retranslates only changed sections, never reuses a section that is still English, rebuilds English-copy / leaked mirrors even when the source is unchanged, merges the state on save (parallel runs), and the drift gate (scoped to the core set) is blocking. Final audit: 0 stale, 0 English copies, 0 leaked frontmatter across 1,430 core mirrors.

⚠️ base-red inherited: #12732
2026-09-17 02:55:31 -03:00

1735 lines
130 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API Reference (Español)
🌐 **Languages:** 🇺🇸 [English](../../../../reference/API_REFERENCE.md) · 🇪🇹 [am](../../../am/docs/reference/API_REFERENCE.md) · 🇸🇦 [ar](../../../ar/docs/reference/API_REFERENCE.md) · 🇦🇿 [az](../../../az/docs/reference/API_REFERENCE.md) · 🇧🇬 [bg](../../../bg/docs/reference/API_REFERENCE.md) · 🇧🇩 [bn](../../../bn/docs/reference/API_REFERENCE.md) · 🇨🇿 [cs](../../../cs/docs/reference/API_REFERENCE.md) · 🇩🇰 [da](../../../da/docs/reference/API_REFERENCE.md) · 🇩🇪 [de](../../../de/docs/reference/API_REFERENCE.md) · 🇬🇷 [el](../../../el/docs/reference/API_REFERENCE.md) · 🇪🇪 [et](../../../et/docs/reference/API_REFERENCE.md) · 🇮🇷 [fa](../../../fa/docs/reference/API_REFERENCE.md) · 🇫🇮 [fi](../../../fi/docs/reference/API_REFERENCE.md) · 🇫🇷 [fr](../../../fr/docs/reference/API_REFERENCE.md) · 🇮🇪 [ga](../../../ga/docs/reference/API_REFERENCE.md) · 🇮🇳 [gu](../../../gu/docs/reference/API_REFERENCE.md) · 🇳🇬 [ha](../../../ha/docs/reference/API_REFERENCE.md) · 🇮🇱 [he](../../../he/docs/reference/API_REFERENCE.md) · 🇮🇳 [hi](../../../hi/docs/reference/API_REFERENCE.md) · 🇭🇷 [hr](../../../hr/docs/reference/API_REFERENCE.md) · 🇭🇺 [hu](../../../hu/docs/reference/API_REFERENCE.md) · 🇦🇲 [hy](../../../hy/docs/reference/API_REFERENCE.md) · 🇮🇩 [id](../../../id/docs/reference/API_REFERENCE.md) · 🇳🇬 [ig](../../../ig/docs/reference/API_REFERENCE.md) · 🇮🇹 [it](../../../it/docs/reference/API_REFERENCE.md) · 🇯🇵 [ja](../../../ja/docs/reference/API_REFERENCE.md) · 🇬🇪 [ka](../../../ka/docs/reference/API_REFERENCE.md) · 🇰🇭 [km](../../../km/docs/reference/API_REFERENCE.md) · 🇮🇳 [kn](../../../kn/docs/reference/API_REFERENCE.md) · 🇰🇷 [ko](../../../ko/docs/reference/API_REFERENCE.md) · 🇱🇹 [lt](../../../lt/docs/reference/API_REFERENCE.md) · 🇱🇻 [lv](../../../lv/docs/reference/API_REFERENCE.md) · 🇮🇳 [ml](../../../ml/docs/reference/API_REFERENCE.md) · 🇮🇳 [mr](../../../mr/docs/reference/API_REFERENCE.md) · 🇲🇾 [ms](../../../ms/docs/reference/API_REFERENCE.md) · 🇲🇹 [mt](../../../mt/docs/reference/API_REFERENCE.md) · 🇲🇲 [my](../../../my/docs/reference/API_REFERENCE.md) · 🇳🇵 [ne](../../../ne/docs/reference/API_REFERENCE.md) · 🇳🇱 [nl](../../../nl/docs/reference/API_REFERENCE.md) · 🇳🇴 [no](../../../no/docs/reference/API_REFERENCE.md) · 🇮🇳 [or](../../../or/docs/reference/API_REFERENCE.md) · 🇮🇳 [pa](../../../pa/docs/reference/API_REFERENCE.md) · 🇵🇭 [phi](../../../phi/docs/reference/API_REFERENCE.md) · 🇵🇱 [pl](../../../pl/docs/reference/API_REFERENCE.md) · 🇵🇹 [pt](../../../pt/docs/reference/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/reference/API_REFERENCE.md) · 🇷🇴 [ro](../../../ro/docs/reference/API_REFERENCE.md) · 🇷🇺 [ru](../../../ru/docs/reference/API_REFERENCE.md) · 🇱🇰 [si](../../../si/docs/reference/API_REFERENCE.md) · 🇸🇰 [sk](../../../sk/docs/reference/API_REFERENCE.md) · 🇸🇮 [sl](../../../sl/docs/reference/API_REFERENCE.md) · 🇷🇸 [sr](../../../sr/docs/reference/API_REFERENCE.md) · 🇸🇪 [sv](../../../sv/docs/reference/API_REFERENCE.md) · 🇰🇪 [sw](../../../sw/docs/reference/API_REFERENCE.md) · 🇮🇳 [ta](../../../ta/docs/reference/API_REFERENCE.md) · 🇮🇳 [te](../../../te/docs/reference/API_REFERENCE.md) · 🇹🇭 [th](../../../th/docs/reference/API_REFERENCE.md) · 🇹🇷 [tr](../../../tr/docs/reference/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/reference/API_REFERENCE.md) · 🇵🇰 [ur](../../../ur/docs/reference/API_REFERENCE.md) · 🇺🇿 [uz](../../../uz/docs/reference/API_REFERENCE.md) · 🇻🇳 [vi](../../../vi/docs/reference/API_REFERENCE.md) · 🇳🇬 [yo](../../../yo/docs/reference/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/reference/API_REFERENCE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/reference/API_REFERENCE.md)
---
🌐 **Idiomas:** 🇺🇸 [English](./API_REFERENCE.md) | 🇪🇹 [አማርኛ](../i18n/am/docs/reference/API_REFERENCE.md) | 🇸🇦 [العربية](../i18n/ar/docs/reference/API_REFERENCE.md) | 🇦🇿 [Azərbaycan dili](../i18n/az/docs/reference/API_REFERENCE.md) | 🇧🇬 [Български](../i18n/bg/docs/reference/API_REFERENCE.md) | 🇧🇩 [বাংলা](../i18n/bn/docs/reference/API_REFERENCE.md) | 🇨🇿 [Čeština](../i18n/cs/docs/reference/API_REFERENCE.md) | 🇩🇰 [Dansk](../i18n/da/docs/reference/API_REFERENCE.md) | 🇩🇪 [Deutsch](../i18n/de/docs/reference/API_REFERENCE.md) | 🇬🇷 [Ελληνικά](../i18n/el/docs/reference/API_REFERENCE.md) | 🇪🇸 [Español](../i18n/es/docs/reference/API_REFERENCE.md) | 🇪🇪 [Eesti](../i18n/et/docs/reference/API_REFERENCE.md) | 🇮🇷 [فارسی](../i18n/fa/docs/reference/API_REFERENCE.md) | 🇫🇮 [Suomi](../i18n/fi/docs/reference/API_REFERENCE.md) | 🇫🇷 [Français](../i18n/fr/docs/reference/API_REFERENCE.md) | 🇮🇪 [Gaeilge](../i18n/ga/docs/reference/API_REFERENCE.md) | 🇮🇳 [ગુજરાતી](../i18n/gu/docs/reference/API_REFERENCE.md) | 🇳🇬 [Hausa](../i18n/ha/docs/reference/API_REFERENCE.md) | 🇮🇱 [עברית](../i18n/he/docs/reference/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../i18n/hi/docs/reference/API_REFERENCE.md) | 🇭🇷 [Hrvatski](../i18n/hr/docs/reference/API_REFERENCE.md) | 🇭🇺 [Magyar](../i18n/hu/docs/reference/API_REFERENCE.md) | 🇦🇲 [Հայերեն](../i18n/hy/docs/reference/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../i18n/id/docs/reference/API_REFERENCE.md) | 🇳🇬 [Igbo](../i18n/ig/docs/reference/API_REFERENCE.md) | 🇮🇹 [Italiano](../i18n/it/docs/reference/API_REFERENCE.md) | 🇯🇵 [日本語](../i18n/ja/docs/reference/API_REFERENCE.md) | 🇬🇪 [ქართული](../i18n/ka/docs/reference/API_REFERENCE.md) | 🇰🇭 [ខ្មែរ](../i18n/km/docs/reference/API_REFERENCE.md) | 🇮🇳 [ಕನ್ನಡ](../i18n/kn/docs/reference/API_REFERENCE.md) | 🇰🇷 [한국어](../i18n/ko/docs/reference/API_REFERENCE.md) | 🇱🇹 [Lietuvių](../i18n/lt/docs/reference/API_REFERENCE.md) | 🇱🇻 [Latviešu](../i18n/lv/docs/reference/API_REFERENCE.md) | 🇮🇳 [മലയാളം](../i18n/ml/docs/reference/API_REFERENCE.md) | 🇮🇳 [मराठी](../i18n/mr/docs/reference/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../i18n/ms/docs/reference/API_REFERENCE.md) | 🇲🇹 [Malti](../i18n/mt/docs/reference/API_REFERENCE.md) | 🇲🇲 [မြန်မာ](../i18n/my/docs/reference/API_REFERENCE.md) | 🇳🇵 [नेपाली](../i18n/ne/docs/reference/API_REFERENCE.md) | 🇳🇱 [Nederlands](../i18n/nl/docs/reference/API_REFERENCE.md) | 🇳🇴 [Norsk](../i18n/no/docs/reference/API_REFERENCE.md) | 🇮🇳 [ଓଡ଼ିଆ](../i18n/or/docs/reference/API_REFERENCE.md) | 🇮🇳 [ਪੰਜਾਬੀ](../i18n/pa/docs/reference/API_REFERENCE.md) | 🇵🇭 [Filipino](../i18n/phi/docs/reference/API_REFERENCE.md) | 🇵🇱 [Polski](../i18n/pl/docs/reference/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../i18n/pt/docs/reference/API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../i18n/pt-BR/docs/reference/API_REFERENCE.md) | 🇷🇴 [Română](../i18n/ro/docs/reference/API_REFERENCE.md) | 🇷🇺 [Русский](../i18n/ru/docs/reference/API_REFERENCE.md) | 🇱🇰 [සිංහල](../i18n/si/docs/reference/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../i18n/sk/docs/reference/API_REFERENCE.md) | 🇸🇮 [Slovenščina](../i18n/sl/docs/reference/API_REFERENCE.md) | 🇷🇸 [Српски](../i18n/sr/docs/reference/API_REFERENCE.md) | 🇸🇪 [Svenska](../i18n/sv/docs/reference/API_REFERENCE.md) | 🇰🇪 [Kiswahili](../i18n/sw/docs/reference/API_REFERENCE.md) | 🇮🇳 [தமிழ்](../i18n/ta/docs/reference/API_REFERENCE.md) | 🇮🇳 [తెలుగు](../i18n/te/docs/reference/API_REFERENCE.md) | 🇹🇭 [ไทย](../i18n/th/docs/reference/API_REFERENCE.md) | 🇹🇷 [Türkçe](../i18n/tr/docs/reference/API_REFERENCE.md) | 🇺🇦 [Українська](../i18n/uk-UA/docs/reference/API_REFERENCE.md) | 🇵🇰 [اردو](../i18n/ur/docs/reference/API_REFERENCE.md) | 🇺🇿 [Oʻzbekcha](../i18n/uz/docs/reference/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../i18n/vi/docs/reference/API_REFERENCE.md) | 🇳🇬 [Yorùbá](../i18n/yo/docs/reference/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../i18n/zh-CN/docs/reference/API_REFERENCE.md) | 🇹🇼 [中文 (繁體)](../i18n/zh-TW/docs/reference/API_REFERENCE.md)
Referencia principal de la API de OmniRoute. Abarca la superficie pública `/v1` y los endpoints de administración más utilizados; el archivo legible por máquina [`docs/openapi.yaml`](../openapi.yaml) y el árbol de rutas ubicado en `src/app/api/` son las fuentes exhaustivas.
---
## Tabla de contenidos
- [Completado de chat](#chat-completions)
- [Arrendamientos exclusivos de sesiones administradas](#exclusive-managed-session-leases)
- [Embeddings](#embeddings)
- [Generación de imágenes](#image-generation)
- [OCR de documentos](#document-ocr)
- [Lista de modelos](#list-models)
- [Manifiesto de plugins de proveedores](#provider-plugin-manifest)
- [Endpoints de compatibilidad](#compatibility-endpoints)
- [API de archivos](#files-api)
- [API de lotes](#batches-api)
- [API de búsqueda](#search-api)
- [Streaming mediante WebSocket](#websocket-streaming)
- [Informes de cuotas e incidencias](#quotas--issues-reporting)
- [Caché semántica](#semantic-cache)
- [Panel y administración](#dashboard--management)
- [Administración de combos](#combo-management)
- [Webhooks](#webhooks)
- [Claves registradas (administración automática)](#registered-keys-auto-management)
- [Protocolo de agentes](#agents-protocol)
- [Proxies de administración](#management-proxies)
- [Resiliencia (ampliada)](#resilience-extended)
- [Habilidades](#skills)
- [Memoria](#memory)
- [Servidor MCP](#mcp-server)
- [Servidor A2A](#a2a-server)
- [Nube, evaluaciones y valoración](#cloud-evals--assess)
- [Procesamiento de solicitudes](#request-processing)
- [Autenticación](#authentication)
---
## Completado de chat
```bash
POST /v1/chat/completions
Authorization: Bearer your-api-key
Content-Type: application/json
{
"model": "cc/claude-opus-4-6",
"messages": [
{"role": "user", "content": "Escribe una función para..."}
],
"stream": true
}
```
### Encabezados personalizados
| Encabezado | Dirección | Descripción |
| ------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `X-OmniRoute-No-Cache` | Solicitud | Establézcalo en `true` para omitir la caché |
| `x-omniroute-no-memory` | Solicitud | Establézcalo en `true` para omitir la inyección de memoria y habilidades en esta solicitud (equivale a no usar la caché; evita la sobrecarga de tokens/coste por llamada) |
| `X-OmniRoute-Progress` | Solicitud | Establézcalo en `true` para recibir eventos de progreso |
| `X-Session-Id` | Solicitud | Clave de sesión persistente para la afinidad de sesiones externas |
| `x_session_id` | Solicitud | También se acepta la variante con guion bajo (HTTP directo) |
| `X-OmniRoute-Session-Id` | Solicitud | Etiqueta de sesión/conversación proporcionada por el llamador (también alimenta la memoria). Cuando está presente, se conserva textualmente en `call_logs.session_tag` para atribuir costes por sesión (#8249); nunca se sintetiza cuando está ausente |
| `Idempotency-Key` | Solicitud | Clave de desduplicación (ventana de 5 s) |
| `X-Request-Id` | Solicitud | Clave de desduplicación alternativa |
| `X-OmniRoute-Cache` | Respuesta | `HIT` o `MISS` (sin streaming) |
| `X-OmniRoute-Idempotent` | Respuesta | `true` si se ha desduplicado |
| `X-OmniRoute-Progress` | Respuesta | `enabled` si el seguimiento del progreso está activado |
| `X-OmniRoute-Session-Id` | Respuesta | ID de sesión efectivo utilizado por OmniRoute |
| `X-OmniRoute-Request-Id` | Respuesta | ID de correlación de la solicitud (cuando se conoce) |
| `X-OmniRoute-Version` | Respuesta | Versión de compilación de OmniRoute (siempre presente) |
| `X-OmniRoute-Cost-Saved` | Respuesta | Importe en USD que la caché permitió ahorrar en un `HIT` (solo aciertos de caché) |
| `X-OmniRoute-Decision` | Respuesta | Traza de enrutamiento: `strategy=<name>; provider=<alias>; latency_ms=<n>` (`<name>` es la estrategia del combo, o `single` para una solicitud que no usa un combo); siempre está presente en las respuestas de finalización |
> Nota sobre Nginx: si depende de encabezados con guiones bajos (por ejemplo, `x_session_id`), habilite `underscores_in_headers on;`.
> **Encabezados de telemetría de costes:** las respuestas correctas sin streaming también incluyen el conjunto de telemetría de costes `X-OmniRoute-*`: `X-OmniRoute-Response-Cost` (USD, con 10 decimales fijos; `0.0000000000` para servicios gratuitos o sin precio), `X-OmniRoute-Tokens-In` / `X-OmniRoute-Tokens-Out`, `X-OmniRoute-Model`, `X-OmniRoute-Provider`, `X-OmniRoute-Latency-Ms`, `X-OmniRoute-Cache-Hit` y `X-OmniRoute-Fallback-Attempts` (solo cuando > 0), además de `X-OmniRoute-Request-Id` y `X-OmniRoute-Version`. Estos encabezados se emiten para las finalizaciones de chat, `/v1/responses`, `/v1/messages` **y los endpoints multimedia**: `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/speech`, `/v1/audio/transcriptions`, `/v1/rerank`, `/v1/videos/generations`, `/v1/music/generations` y `/v1/moderations` (siempre con un coste de `0`). El coste multimedia se calcula por modalidad (por imagen, por segundo, por carácter o por unidad de búsqueda) cuando hay precios disponibles; de lo contrario, es `0` (fail-open).
> **Semántica del coste de los aciertos de caché:** cuando se produce un acierto en la caché semántica (`X-OmniRoute-Cache-Hit: true`), no se realiza ninguna llamada al proveedor ascendente, por lo que `X-OmniRoute-Response-Cost` es `0.0000000000` (el coste **incremental** de servir el acierto). El coste original o que se habría producido se indica por separado en `X-OmniRoute-Cost-Saved`. Los consumidores de datos de facturación deben sumar `X-OmniRoute-Response-Cost` (los aciertos no tienen coste); los sistemas de análisis de caché pueden agregar `X-OmniRoute-Cost-Saved`.
## Arrendamientos exclusivos de sesiones gestionadas
El arrendamiento exclusivo de sesiones gestionadas es un contrato de enrutamiento opcional e independiente del cliente: un propietario activo mantiene una conexión apta de OmniRoute. No arrienda un modelo, no requiere OAuth, no identifica a un cliente concreto ni exige un proveedor específico.
La clave de API utilizada para la autenticación debe tener el ámbito `lease:exclusive` y una lista explícita no vacía de `allowedConnections`. El límite de mutación de la base de datos exige ambos campos conjuntamente durante la creación de claves y las actualizaciones parciales.
```http
POST /api/v1/session-leases
Authorization: Bearer <managed-api-key>
Content-Type: application/json
X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters>
{"action":"acquire","model":"glm/glm-4.6"}
```
Las respuestas correctas de adquisición, renovación y liberación exponen marcas de tiempo, `state` y el valor positivo exacto de `generation`, pero nunca la conexión seleccionada ni las credenciales. La renovación y la liberación proporcionan la generación en el cuerpo JSON:
```json
{ "action": "renew", "generation": 1 }
```
```json
{ "action": "release", "generation": 1, "reason": "OWNER_EXIT" }
```
El propietario de un arrendamiento activo puede solicitar explícitamente metadatos de visualización que protejan la privacidad para su vinculación actual:
```json
{ "action": "status", "generation": 1 }
```
```json
{
"state": "ACTIVE",
"generation": 1,
"acquiredAt": "2026-08-28T12:00:00.000Z",
"renewedAt": "2026-08-28T12:00:30.000Z",
"expiresAt": "2026-08-28T12:02:30.000Z",
"connection": {
"displayName": "Primary Codex",
"provider": "codex"
}
}
```
Esta acción de estado opcional queda delimitada por el propietario opaco, la clave de API gestionada autenticada y la generación activa exacta dentro de una única transacción de base de datos. `displayName` es únicamente el nombre de conexión configurado sin espacios en blanco al principio ni al final; es `null` cuando no existe un nombre configurado seguro. OmniRoute nunca lo sustituye por un correo electrónico ni por una identidad de cuenta generada. El valor del proveedor es una etiqueta de visualización no confidencial y nunca un identificador generado de un proveedor compatible. Se excluyen las credenciales, los tokens, las cookies, los identificadores sin procesar de conexiones o claves de API, los hashes de propietarios, los secretos de delimitación y los datos internos de enrutamiento.
Las consultas con una clave incorrecta, un propietario incorrecto, una generación obsoleta, datos ausentes, un arrendamiento vencido, liberado o invalidado devuelven todas el mismo error `409 LEASE_FENCE_STALE` sin metadatos de conexión. Un cliente que haya recibido la respuesta de espera de capacidad no tiene ninguna vinculación activa que inspeccionar. Cuando el enrutamiento cambia un arrendamiento activo, la misma generación sigue siendo válida y el estado devuelve atómicamente la nueva vinculación, nunca la anterior. Los clientes existentes no sufren cambios porque las respuestas de adquisición, renovación, liberación y espera conservan sus formatos anteriores.
Este contrato del servidor no modifica `/status` de OpenAI Codex estándar. Actualmente, Codex estándar informa sobre su proveedor de modelos y el estado integrado de autenticación/cuenta, pero no representa metadatos de cuenta arbitrarios de proveedores personalizados; una futura integración de cliente deberá llamar a esta acción y decidir cómo mostrar `connection.displayName`.
A partir de entonces, cada solicitud de inferencia gestionada proporciona ambas cabeceras de control:
```http
X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters>
X-OmniRoute-Lease-Generation: 1
```
El propietario exacto, la generación, la conexión activa y la clave de API autenticada se delimitan inmediatamente antes de cada intento ascendente compatible. Reutilizar el propietario y la generación con otra clave falla incluso cuando esa clave permite la misma conexión. Los propietarios sin procesar no se conservan, registran ni retienen en la instantánea de la solicitud, ni se reenvían al sistema ascendente.
La contención temporal devuelve HTTP `429` con `Retry-After` y:
```json
{
"state": "WAITING_FOR_CAPACITY",
"error": { "type": "lease_error", "code": "LEASE_CAPACITY_UNAVAILABLE" },
"reason": "NO_FREE_ELIGIBLE_CONNECTION",
"retryAfter": 30
}
```
Esta respuesta solo significa que el conjunto apto ordinario no estaba vacío y que todos los candidatos libres estaban retenidos por un arrendamiento activo ajeno. Los modelos/proveedores no compatibles, las discrepancias de políticas, los períodos de enfriamiento, las cuotas, el estado de salud y otros fallos ordinarios de idoneidad conservan sus respuestas existentes de OmniRoute.
### `x-omniroute-compression`
Anulación por solicitud del plan de compresión. Tiene la máxima precedencia: prevalece sobre la anulación de la combinación de enrutamiento, el perfil activo, la activación automática y el valor predeterminado del panel. Valores:
| Valor | Efecto |
| ------------- | ------------------------------------------------------------------------------------------------------------------- |
| `off` | Sin compresión para esta solicitud. |
| `default` | El perfil predeterminado derivado del panel (ignora el perfil activo). |
| `engine:<id>` | Un único motor cuando está habilitado, p. ej., `engine:rtk`. |
| `<combo>` | Una combinación con nombre, comparada primero por nombre (sin distinguir mayúsculas y minúsculas) y después por id. |
Notas:
- Los valores desconocidos se ignoran (la solicitud nunca se rechaza); la resolución continúa según la precedencia normal de operadores.
- Si varias combinaciones comparten un nombre, proporcione el **id** de la combinación para obtener una coincidencia determinista.
- Una combinación cuyo nombre sea `off` o `default` no puede seleccionarse por nombre (esas palabras clave se interpretan primero); haga referencia a dicha combinación mediante su id.
- El interruptor principal de compresión actúa como una barrera estricta: cuando la compresión está deshabilitada globalmente, esta cabecera no puede habilitarla.
El plan aplicado se devuelve en la cabecera de respuesta:
```
X-OmniRoute-Compression: <mode>; source=<source>
```
donde `<source>` es uno de `request-header`, `routing-override`, `active-profile`, `auto-trigger`, `default` u `off`.
---
## Embeddings
```bash
POST /v1/embeddings
Authorization: Bearer your-api-key
Content-Type: application/json
{
"model": "nebius/Qwen/Qwen3-Embedding-8B",
"input": "The food was delicious"
}
```
Proveedores disponibles: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, Jina AI.
Los identificadores del catálogo tienen el formato `provider/model` (ejemplo: `jina-ai/jina-embeddings-v5-omni-small`). Los identificadores simples de modelos de Jina que aparecen en el registro (por ejemplo, `jina-embeddings-v5-text-small`, `jina-reranker-v3.5`) también se resuelven. Las operaciones de embeddings, reclasificación, clasificación y segmentación de Jina utilizan primero las credenciales `jina-ai` del panel; `JINA_AI_API_KEY` solo se usa como alternativa cuando no existe ninguna clave en el panel. La tarjeta `jina-reader` es únicamente para Reader / `r.jina.ai` (`POST /v1/web/fetch`) y nunca proporciona embeddings ni reclasificación.
Los modelos del registro que anuncian compatibilidad multimodal también aceptan hasta 32 elementos estructurados independientes del proveedor. Los tipos de elementos multimedia son `text`, `image`, `audio`, `video` y `document`. Su `source` multimedia es `{"type":"url","url":"https://..."}` o `{"type":"base64","data":"...","media_type":"..."}`.
Jina v5 Omni (`jina-ai/jina-embeddings-v5-omni-small`, `jina-ai/jina-embeddings-v5-omni-nano` y el alias de familia `jina-ai/jina-embeddings-v5-omni` → omni-small) también acepta documentos EmbeddingsV5Request nativos de Jina y **los reenvía intactos** a `https://api.jina.ai/v1/embeddings`:
```json
{
"model": "jina-ai/jina-embeddings-v5-omni-small",
"task": "retrieval.query",
"normalized": true,
"input": [
{ "text": "a red bicycle" },
{ "image": "https://example.com/bike.png" },
{
"content": [{ "text": "caption" }, { "image": "data:image/png;base64,..." }]
}
]
}
```
Los valores nativos `{ image | audio | video | pdf }` pueden ser una URL HTTPS pública, un URI `data:` o base64 sin procesar. OmniRoute no convierte esos objetos en cadenas ni obtiene las URL de imágenes nativas: Jina recupera directamente el contenido multimedia público. Los campos adicionales de Jina (`task`, `normalized`, `truncate`, `embedding_type`) se reenvían. Los SKU de Jina que solo admiten texto siguen rechazando documentos que no sean de texto.
Límites de seguridad y transporte:
- Las URL remotas de contenido multimedia deben ser HTTPS públicas. Los elementos canónicos `{type,source:url}` se obtienen en el servidor (revalidación de redirecciones, tiempo de espera, límites de tamaño, DNS público y fijación de conexión) y se insertan antes de la llamada al proveedor. Los elementos nativos de Jina `{image:"https://..."}` se reenvían tal cual después de realizar la misma comprobación de HTTPS público; Jina obtiene la URL.
- El contenido multimedia base64 en línea está limitado a 8 MiB decodificados por elemento y 16 MiB decodificados en toda la solicitud.
Traducción para el proveedor (los elementos canónicos nunca se reenvían sin cambios):
- Modelos multimodales de Jina: cada elemento de nivel superior se convierte en un objeto con clave de modalidad (`text` / `image` / `audio` / `video` / `pdf`) que utiliza URI de datos para el contenido multimedia en línea; un vector por cada elemento de nivel superior.
- Familia Gemini Embedding 2: una matriz de nivel superior se convierte en una única solicitud nativa `models/{model}:embedContent` con `content.parts` (`text` o `inline_data`).
- Los modelos desconocidos o dinámicos sin metadatos explícitos de modalidad rechazan las entradas estructuradas con HTTP 400.
```json
{
"model": "jina-ai/jina-embeddings-v5-omni-small",
"input": [
{ "type": "text", "text": "A red bicycle" },
{
"type": "image",
"source": { "type": "url", "url": "https://example.com/bicycle.png" }
}
],
"dimensions": 512,
"encoding_format": "float"
}
```
Las combinaciones de modelo y modalidad no compatibles devuelven HTTP 400 en lugar de convertir el elemento. Los campos de extensión que no sean de entrada en solicitudes heredadas de cadenas o tokens continúan transmitiéndose sin cambios.
```bash
# Enumerar todos los modelos de embeddings
GET /v1/embeddings
```
---
## Generación de imágenes
```bash
POST /v1/images/generations
Authorization: Bearer your-api-key
Content-Type: application/json
{
"model": "openai/gpt-image-2",
"prompt": "Un hermoso atardecer sobre las montañas",
"size": "1024x1024"
}
```
Proveedores disponibles: OpenAI (GPT Image 2), xAI (Grok Image), Together AI (FLUX), Fireworks AI, Nebius (FLUX), Hyperbolic, NanoBanana, **OpenRouter**, SD WebUI (local), ComfyUI (local).
```bash
# Enumerar todos los modelos de imágenes
GET /v1/images/generations
```
---
## OCR de documentos
```bash
POST /v1/ocr
Authorization: Bearer your-api-key
Content-Type: application/json
{
"model": "mistral/mistral-ocr-latest",
"document": {
"type": "document_url",
"document_url": "https://example.com/invoice.pdf"
}
}
```
`model` selecciona el proveedor de OCR mediante un prefijo `provider/model`; un id de modelo sin prefijo (p. ej.,
`mistral-ocr-latest`) se resuelve con su proveedor registrado, y si se omite `model`, se utiliza de forma predeterminada
Mistral (`mistral-ocr-latest`). Proveedores registrados (`open-sse/config/ocrRegistry.ts`):
| Id del proveedor | Id del modelo | Valor de `model` | Notas |
| ----------------------------- | -------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `mistral` | `mistral-ocr-latest` | `mistral/mistral-ocr-latest` (o `mistral-ocr-latest` solo) | Síncrono: la respuesta se devuelve directamente desde la única llamada al servicio externo. |
| `azure-document-intelligence` | `prebuilt-read` | `azure-document-intelligence/prebuilt-read` | Servicio externo asíncrono (`analyze` + sondeo): consulte la información a continuación. |
| `vertex-deepseek-ocr` | `deepseek-ocr-maas` | `vertex-deepseek-ocr/deepseek-ocr-maas` | Síncrono, mediante el endpoint asociado `openapi/chat/completions` de Vertex AI; consulte más abajo la autenticación/URL. |
Los tres proveedores responden con el mismo cuerpo con formato de Mistral:
```json
{
"pages": [{ "index": 0, "markdown": "# Texto extraído..." }],
"model": "mistral-ocr-latest",
"usage_info": { "pages_processed": 1 }
}
```
### Flujo de sondeo de Azure Document Intelligence
La API `analyze` de Azure Document Intelligence es asíncrona: la solicitud inicial devuelve un
encabezado `Operation-Location` en lugar de un cuerpo, y se debe sondear el resultado. El controlador
(`open-sse/handlers/ocr.ts`) sondea esa URL cada segundo durante un máximo de 30 intentos, produce un error de inmediato (sin
seguir sondeando) ante una respuesta de sondeo que no sea `ok` o un estado `"failed"`, y devuelve `504` si la
operación continúa ejecutándose después de agotar el límite de intentos. La respuesta final de Azure se
normaliza con la misma estructura `pages`/`markdown` utilizada por Mistral antes de devolverse al
cliente, por lo que el código del cliente no necesita tratar al proveedor como un caso especial.
### Autenticación y resolución del endpoint de OCR de Vertex AI DeepSeek
`vertex-deepseek-ocr` reutiliza la misma autenticación de Vertex AI que OmniRoute ya admite para el
tráfico de chat/imágenes (`open-sse/executors/vertex.ts`): la clave de API de la conexión es una
credencial JSON de cuenta de servicio (intercambiada por un token de acceso OAuth de corta duración mediante el flujo JWT Bearer)
o un token de acceso OAuth ya emitido que se utiliza tal cual. La URL del endpoint del servicio externo es el endpoint
asociado genérico `openapi/chat/completions` de Vertex, creado a partir del proyecto y la
región de la conexión: un valor explícito de `providerSpecificData.project`/`providerSpecificData.region` siempre tiene prioridad;
de lo contrario, el proyecto se obtiene del `project_id` del JSON de la cuenta de servicio y la región
tiene como valor predeterminado `us-central1`. Ambas resoluciones se realizan en `open-sse/handlers/ocr.ts`
(`resolveVertexOcrAccessToken`, `resolveVertexOcrBaseUrl`) y son utilizadas por
`src/app/api/v1/ocr/route.ts` antes de delegar la solicitud a `handleOcr`.
---
## Listar modelos
```bash
GET /v1/models
Authorization: Bearer your-api-key
→ Devuelve todos los modelos de chat, embeddings e imágenes, además de las combinaciones, en formato OpenAI
```
### Prefijos de id de modelo (`?prefix=`)
La mayoría de los modelos se anuncian con un **prefijo de proveedor**. El prefijo que se obtiene está controlado por la marca de funcionalidad `MODELS_CATALOG_PREFIX_MODE` y puede sobrescribirse **para cada solicitud** mediante un parámetro de consulta, lo que resulta útil para clientes que desean una lista limpia sin cambiar la configuración global del servidor para todos los demás:
```bash
GET /v1/models?prefix=alias # un id por modelo: el prefijo de alias corto
GET /v1/models?prefix=dual # ambas formas (valor predeterminado del servidor)
GET /v1/models?prefix=canonical # solo el prefijo completo del id del proveedor
```
| Modo | Emite | Notas |
| ----------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `dual` | `cc/claude-sonnet-4-6` **y** `claude/claude-sonnet-4-6` | **Predeterminado.** Ambos ids se enrutan al mismo modelo; se mantienen para que sigan funcionando las configuraciones de clientes que hayan codificado de forma fija cualquiera de las dos variantes. Aproximadamente duplica el catálogo. |
| `alias` | `cc/claude-sonnet-4-6` | Una entrada por modelo. Los proveedores sin un alias distinto siguen emitiendo su entrada, por lo que no se pierde nada. |
| `canonical` | `claude/claude-sonnet-4-6` | Una entrada por modelo con el prefijo completo del id del proveedor. Los proveedores sin un alias distinto (p. ej., `antigravity/…`, `agy/…`) también emiten aquí su único id, por lo que no se pierde nada. |
Un reflejo en modo `dual` también puede reconocerse sin el parámetro de consulta: incluye un campo `parent` que apunta al id principal.
Los clientes que muestran un selector de modelos deben solicitar `?prefix=alias`; esto es lo que hace la [extensión OmniCopilot para VS Code](../guides/VSCODE-COPILOT.md).
### Variantes de modelos sin razonamiento
Para los modelos Claude con capacidad de razonamiento, `/v1/models` también anuncia una variante **sin razonamiento** cuyo id lleva el prefijo `claude-3-omniroute-no-thinking/`:
```
claude-3-omniroute-no-thinking/<provider>/<model>
```
Al seleccionar este id (p. ej., en una configuración de Claude Code que siempre adjunta un bloque `thinking`), se vuelve a resolver al `<provider>/<model>` real con el razonamiento suprimido: `thinking:{type:"disabled"}` en la ruta `/v1/messages`, o se omiten los campos `reasoning`/`reasoning_effort` en la ruta `/v1/chat/completions`. La variante solo aparece para los modelos de la familia Claude que admiten razonamiento **y** respetan `disabled` (por lo que, p. ej., se excluyen los modelos exclusivamente adaptativos que rechazan `disabled`). Los operadores pueden forzar la activación o desactivación de la variante para cada modelo mediante `ModelSpec.noThinkingAlias`.
---
## Manifiesto de plugins de proveedores
```bash
GET /api/v1/provider-plugin-manifest
```
Devuelve el manifiesto JSON seguro de plugins de proveedores utilizado por Bifrost, CLIProxyAPI y
futuros enrutadores sidecar. La respuesta se genera a partir del registro de proveedores de
TypeScript y excluye intencionadamente los secretos de clientes OAuth, la resolución del entorno
de ejecución, las funciones ejecutoras, los encabezados de solicitud y los datos de las cuentas.
Utilice este endpoint cuando un sidecar se ejecute fuera de proceso y no pueda importar
`open-sse/config/providerPluginManifestRegistry.ts` directamente.
---
## Endpoints de compatibilidad
| Método | Ruta | Formato |
| ------ | ----------------------------------------- | --------------------------------------- |
| POST | `/v1/chat/completions` | OpenAI |
| POST | `/v1/messages` | Anthropic |
| POST | `/v1/responses` | OpenAI Responses |
| POST | `/v1/embeddings` | OpenAI |
| POST | `/v1/images/generations` | OpenAI Images |
| POST | `/v1/images/edits` | OpenAI Images (edición/inpainting) |
| POST | `/v1/videos/generations` | Generación de vídeo estilo OpenAI |
| POST | `/v1/music/generations` | Generación de música estilo OpenAI |
| POST | `/v1/audio/transcriptions` | OpenAI Audio (STT) |
| POST | `/v1/audio/speech` | OpenAI TTS (devuelve audio) |
| POST | `/v1/rerank` | Reordenamiento estilo Cohere/Voyage |
| POST | `/v1/classify` | Clasificación de Jina (`api.jina.ai`) |
| POST | `/v1/segment` | Segmentador de Jina (`segment.jina.ai`) |
| POST | `/v1/moderations` | OpenAI Moderations |
| GET | `/v1/models` | OpenAI |
| POST | `/v1/messages/count_tokens` | Anthropic |
| GET | `/v1beta/models` | Gemini |
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
| POST | `/v1/api/chat` | Ollama |
| GET | `/api/v1/vscode/{token}/` | Alias del catálogo de OpenAI |
| GET | `/api/v1/vscode/{token}/models` | Alias de modelos de OpenAI |
| POST | `/api/v1/vscode/{token}/chat/completions` | Alias con token de OpenAI |
| POST | `/api/v1/vscode/{token}/responses` | Alias con token de OpenAI Responses |
| POST | `/api/v1/vscode/{token}/api/chat` | Alias con token de Ollama |
| GET | `/api/v1/vscode/{token}/api/tags` | Alias con token de etiquetas de Ollama |
Todas las rutas POST siguen la misma estructura: `Bearer your-api-key` + cuerpo JSON validado por Zod (`v1RerankSchema`, `v1ModerationSchema`, `v1AudioSpeechSchema`, etc.; consulte `src/shared/validation/schemas.ts`). Se devuelve un error 4xx cuando falla la validación del esquema.
Para los clientes que no puedan adjuntar `Authorization: Bearer ...`, OmniRoute también acepta claves de API en la URL mediante parámetros de consulta compatibles (`?token=...`, `?apiKey=...`, `?api_key=...`, `?key=...`) o los endpoints específicos `/api/v1/vscode/{token}/...` documentados a continuación.
```bash
# Reordenamiento
POST /v1/rerank { "model": "jina-ai/jina-reranker-v3.5", "query": "...", "documents": ["..."] }
# Clasificación de Jina (credenciales de Foundation API)
POST /v1/classify { "model": "jina-embeddings-v5-text-small", "input": ["..."], "labels": ["a", "b"] }
# Segmentador de Jina
POST /v1/segment { "content": "...", "return_chunks": true }
# Búsqueda de Jina (s.jina.ai; alias de proveedores: jina-search, jina-ai, jina)
POST /v1/search { "query": "...", "provider": "jina-search" }
# Moderaciones
POST /v1/moderations { "model": "omni-moderation-latest", "input": "..." }
# TTS — devuelve un cuerpo audio/mpeg (o en el formato solicitado)
POST /v1/audio/speech { "model": "openai/tts-1", "input": "Hello", "voice": "alloy" }
# Edición de imágenes (multipart)
POST /v1/images/edits -F image=@input.png -F prompt="..." -F mask=@mask.png
# Generación de vídeo/música (identificador de modelo con prefijo de proveedor)
POST /v1/videos/generations { "model": "runway/gen-3", "prompt": "..." }
POST /v1/music/generations { "model": "suno/v3.5", "prompt": "..." }
```
### Rutas específicas de proveedores
```bash
POST /v1/providers/{provider}/chat/completions
POST /v1/providers/{provider}/embeddings
POST /v1/providers/{provider}/images/generations
```
El prefijo del proveedor se añade automáticamente si falta. Los modelos que no coincidan devuelven `400`.
---
## API de archivos
Endpoint de archivos compatible con OpenAI para entrada/salida por lotes y cargas de archivos con propósito.
| Método | Ruta | Descripción |
| ------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| POST | `/v1/files` | Cargar un archivo (multipart: `file`, `purpose`, `expires_after[anchor]`, `expires_after[seconds]`) — máximo de 512 MiB |
| GET | `/v1/files` | Listar los archivos de la clave de API autenticada |
| GET | `/v1/files/[id]` | Obtener los metadatos de un archivo |
| DELETE | `/v1/files/[id]` | Eliminar un archivo |
| GET | `/v1/files/[id]/content` | Transmitir el contenido sin procesar del archivo |
**Autenticación:** Clave de API Bearer — los archivos se limitan por clave de API mediante `getApiKeyRequestScope`. Una clave
solo puede ver, descargar y eliminar sus propios archivos; una sesión del panel sin clave puede leer toda la
instancia; el acceso a un archivo sin propietario (carga anónima o realizada desde una sesión del panel) se deniega a cualquier
cliente sin sesión. `GET /v1/files` rechaza a un cliente anónimo —y a una clave proporcionada que no
se pueda resolver— con `401`, incluso cuando `REQUIRE_API_KEY=false`, en lugar de listar los archivos de
todos los tenants (GHSA-m3hp-hq9g-fpmv, GHSA-2jm2-mpx8-6523).
---
## API de lotes
Procesamiento por lotes compatible con OpenAI.
| Método | Ruta | Descripción |
| ------ | ------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| POST | `/v1/batches` | Crear un lote — cuerpo validado mediante `v1BatchCreateSchema` (`input_file_id`, `endpoint`, `completion_window`) |
| GET | `/v1/batches` | Listar lotes |
| GET | `/v1/batches/[id]` | Obtener el estado del lote + `request_counts` |
| DELETE | `/v1/batches/[id]` | Eliminar un lote finalizado/fallido |
| POST | `/v1/batches/[id]/cancel` | Cancelar un lote en curso |
**Autenticación:** Clave de API Bearer. Los lotes se limitan por clave de API conforme a la misma regla de tres casos que
los archivos: solo la clave propietaria, la sesión del panel para toda la instancia y los registros sin propietario denegados a cualquier
cliente sin sesión (obtención, eliminación, cancelación y comprobación de `input_file_id` al crear).
`GET /v1/batches` rechaza a un cliente anónimo con `401`, incluso cuando `REQUIRE_API_KEY=false`.
---
## API de búsqueda
Abstracción de proveedores web/de búsqueda (Tavily, Brave, Exa, Serper, etc.).
| Método | Ruta | Descripción |
| ------ | ---------------------- | ------------------------------------------------------------------------------------------------- |
| GET | `/v1/search` | Enumera los proveedores de búsqueda configurados y sus capacidades |
| POST | `/v1/search` | Ejecuta una consulta de búsqueda; cuerpo validado por `v1SearchSchema`, admite caché/coalescencia |
| GET | `/v1/search/analytics` | Estadísticas de aciertos/latencia/caché por proveedor |
**Autenticación:** clave de API Bearer (`extractApiKey` + `isValidApiKey`). La política de búsqueda se aplica mediante `enforceApiKeyPolicy`.
---
## API de obtención web
Extrae contenido de una URL mediante un proveedor de obtención web configurado (Firecrawl, Jina
Reader, Tavily Extract, TinyFish Fetch, Nimble Extract).
| Método | Ruta | Descripción |
| ------ | --------------- | -------------------------------------------------------------- |
| POST | `/v1/web/fetch` | Obtiene/extrae una URL; cuerpo validado por `v1WebFetchSchema` |
**Autenticación:** clave de API Bearer (`extractApiKey` + `isValidApiKey`). La política se aplica mediante `enforceApiKeyPolicy`.
**Alternativa consciente de cuotas (#8297):** cuando no se proporciona un `provider` explícito, se recorre el grupo
(`firecrawl``jina-reader``tavily-search``tinyfish``nimble-search`) en un orden de
prioridad fijo (llenado prioritario): un proveedor configurado pero limitado por tasa se omite
en lugar de interrumpir la solicitud, y un fallo reintentable/de cuota del servicio ascendente
(HTTP 429 siempre; 402/403 para niveles gratuitos con límites de cuota de Firecrawl/Tavily/TinyFish,
no para Jina Reader, y nunca para una solicitud incorrecta 400 convencional) pasa al
siguiente proveedor con credenciales que aún no se haya probado en el momento de la solicitud. Cuando todos los proveedores del
grupo se han agotado, el endpoint devuelve un único `429` (con un encabezado `Retry-After`)
en lugar del anterior `400` genérico. Cuando se solicita un `provider` explícito,
**no** hay una alternativa silenciosa: un proveedor explícito limitado por tasa o con fallos
expone su propio error (`429` si está limitado por tasa; de lo contrario, el estado del servicio
ascendente).
---
## Streaming mediante WebSocket
```bash
GET /v1/ws?handshake=1
```
Valida un protocolo de enlace de actualización a WebSocket y devuelve los mensajes de ejemplo del protocolo de comunicación (`request`, `cancel`). Los frames de WS reales los gestiona el servidor WS incluido fuera de la tabla de rutas de Next.js.
**Autenticación:** clave de API Bearer durante el protocolo de enlace.
### API Responses mediante WebSocket (solo codex)
```bash
# Mismo host:puerto que la API HTTP (20128 de forma predeterminada); actualice la conexión:
wscat -c "ws://localhost:20128/v1/responses?api_key=<OMNIROUTE_API_KEY>"
# (o bien: -H "Authorization: Bearer <OMNIROUTE_API_KEY>")
# El primer frame DEBE ser response.create:
{ "type": "response.create", "model": "gpt-5.5", "input": [ { "role": "user", "content": "hi" } ] }
```
Un proxy de la API Responses mediante WebSocket está conectado **exclusivamente a `codex`** (backend de ChatGPT). Escucha en el mismo puerto que la API/el panel en las rutas `/v1/responses`,
`/responses` y `/api/v1/responses`. En el primer frame `response.create`,
autentica y prepara mediante el puente interno `codex-responses-ws`, selecciona una
conexión OAuth de codex y crea un túnel hacia `wss://chatgpt.com/backend-api/codex/responses`
mediante el transporte `wreq-js`. **Los modelos que no son codex se rechazan** (`codex_ws_provider_required`).
Para el enrutamiento por cuota compartida, use `model: "qtSd/<group>/codex/<model>"`. Implementado en
`app/server-ws.mjs` + `scripts/dev/responses-ws-proxy.mjs` + `src/app/api/internal/codex-responses-ws/route.ts`.
**Autenticación:** clave de API Bearer durante el protocolo de enlace. El servidor HTTP incluido (`server-ws.mjs`)
debe ser el punto de entrada activo (lo es de forma predeterminada cuando existe `app/server-ws.mjs`).
#### ID del modelo: use el ID de ChatGPT sin prefijo (sin el prefijo `codex/`)
La **CLI de Codex** de OpenAI valida el nombre del modelo en el cliente cuando
`supports_websockets = true` y **rechaza los ID con prefijo de proveedor**, como
`codex/gpt-5.5` (`The 'codex/gpt-5.5' model is not supported when using Codex with
a ChatGPT account`). Envíe el ID **sin prefijo** (por ejemplo, `gpt-5.5`). El puente de OmniRoute es
exclusivo para codex, por lo que vuelve a resolver un ID sin prefijo como un modelo de codex
(`resolveCodexWsModelInfo`) antes de crear el túnel ascendente, aunque un
`gpt-5.5` sin prefijo se enrutaría de otro modo a otro proveedor mediante HTTP.
#### Configuración de la CLI de Codex de OpenAI
Dirija la CLI de Codex hacia OmniRoute añadiendo un proveedor personalizado con compatibilidad con WebSocket
a `~/.codex/config.toml` (use un `CODEX_HOME` independiente para evitar modificar
una configuración existente):
```toml
model = "gpt-5.5" # ID sin prefijo; NO "codex/gpt-5.5"
model_provider = "omniroute"
[model_providers.omniroute]
name = "OmniRoute (WS)"
base_url = "http://localhost:20128/v1" # sin barra diagonal final; la URL de WS se deriva (use https/wss en producción)
wire_api = "responses" # único valor compatible desde febrero de 2026
supports_websockets = true # habilita el transporte de Responses mediante WS
env_key = "OMNIROUTE_API_KEY" # contiene la clave de API de OmniRoute (Bearer)
```
```bash
export OMNIROUTE_API_KEY=sk-... # una clave de API de OmniRoute (cualquier clave si REQUIRE_API_KEY=false)
codex exec "Responda apenas: PONG"
```
La CLI actualiza `base_url + /responses` a un WebSocket y OmniRoute crea un túnel
hacia la conexión OAuth de codex seleccionada. Validado de extremo a extremo con el servidor
local: ChatGPT devuelve `codex.rate_limits` + `response.created` y transmite la
finalización.
---
## Cuotas e informes de incidencias
| Método | Ruta | Descripción |
| ------ | ------------------- | ----------------------------------------------------------------------------------------------- |
| GET | `/v1/quotas/check` | Valida previamente la cuota de un `provider` + `accountId` antes de emitir una clave registrada |
| POST | `/v1/issues/report` | Informa a GitHub de un fallo de cuota/emisión de clave (requiere `GITHUB_ISSUES_REPO` + token) |
**Autenticación:** clave de API Bearer (`isAuthenticated`).
---
## Uso de autoservicio (`/api/usage/om-usage`)
Cualquier clave de API puede consultar **su propio** uso y sus cuotas, sin autenticación de administración. Este es el endpoint que un
cliente (CLI, el panel de OmniCopilot) utiliza para mostrar sus gastos al titular de una clave.
```bash
# Formato de texto (el contrato histórico: texto sin formato para un terminal)
curl -H "Authorization: Bearer <your-api-key>" \
http://localhost:20128/api/usage/om-usage
# Formato estructurado: el que consume una interfaz de usuario
curl -H "Authorization: Bearer <your-api-key>" \
"http://localhost:20128/api/usage/om-usage?format=json"
```
La clave debe tener **`allowUsageCommand`** habilitado (está deshabilitado de forma predeterminada; el administrador de claves de API
del panel lo activa o desactiva para cada clave). Sin esta opción, el endpoint responde con `403`.
`?format=json` devuelve una estructura discriminada para que quien realiza la llamada nunca lea un campo de datos de una
denegación. En caso de éxito:
```jsonc
{
"allowed": true,
// solo está presente cuando la clave ha habilitado límites de uso por clave (USD diarios/semanales):
"personal": {
"dailySpentUsd": 1.25,
"dailyLimitUsd": 5,
"dailyResetAtIso": "…",
"weeklySpentUsd": 8,
"weeklyLimitUsd": 20,
"weeklyResetAtIso": "…" /* */,
},
// la instantánea de cuota del proveedor seleccionado, o null cuando aún no hay nada almacenado en caché:
"provider": {
"connectionId": "…",
"provider": "claude",
"plan": "…",
"quotas": {/* */},
},
// la instantánea de cada conexión, para que una interfaz pueda mostrar varios proveedores en paralelo:
"providers": [
{ "connectionId": "…", "provider": "claude" /* */ },
{ "provider": "codex" /* */ },
],
}
```
En caso de denegación (`401` por clave incorrecta / `403` por falta de permiso), la misma ruta devuelve
`{ "allowed": false, "error": { "message": "…" } }`: un campo `personal`/`provider` presente pero vacío
(clave permitida, todavía no se ha obtenido información) representa un estado distinto de una denegación, y solo el formato JSON
permite distinguirlos.
**Autenticación:** la propia clave de API Bearer de quien realiza la llamada, validada con `isValidApiKey`; esta _no_ es la
interfaz de administración (`/api/keys/…`), que continúa protegida por `requireManagementAuth`.
---
## Caché semántica
```bash
# Obtener estadísticas de la caché
GET /api/cache/stats
# Borrar todas las cachés
DELETE /api/cache/stats
```
Ejemplo de respuesta:
```json
{
"semanticCache": {
"memorySize": 42,
"memoryMaxSize": 500,
"dbSize": 128,
"hitRate": 0.65
},
"idempotency": {
"activeKeys": 3,
"windowMs": 5000
}
}
```
### Impacto en la latencia
Un acierto de la caché semántica sirve la respuesta desde la caché **sin realizar una llamada
al proveedor**, por lo que el valor informado en `X-OmniRoute-Response-Latency` es cercano a cero
(independientemente de la latencia original del proveedor). Los clientes sensibles a la latencia
(pruebas de rendimiento, supervisión de p50/p99) deben comprobar el encabezado de respuesta
`X-OmniRoute-Cache-Latency`:
| Valor | Significado |
| ----------- | ----------------------------------------------------------------------------- |
| `synthetic` | Respuesta servida desde la caché; la latencia no es tiempo real del proveedor |
| _(ausente)_ | Respuesta procedente de una llamada real al proveedor |
### Omisión de la caché por clave
Las claves de API pueden excluirse de las lecturas de la caché semántica mediante `cacheDefaultMode`:
| Valor | Comportamiento |
| -------- | ---------------------------------------------------------------------- |
| `legacy` | Comportamiento normal de la caché (predeterminado) |
| `bypass` | Omite por completo la consulta de la caché; siempre llama al proveedor |
Se configura al crear la clave (`POST /api/keys`) o al actualizarla (`PATCH /api/keys/[id]`):
```json
{ "cacheDefaultMode": "bypass" }
```
### Omisión por solicitud
Cualquier solicitud puede omitir la caché independientemente de la configuración de la clave:
```
X-OmniRoute-No-Cache: true
```
---
## Panel de control y gestión
Las rutas de gestión (`/api/*`, excepto las públicas de autenticación/inicio de sesión) **no** autorizan el acceso mediante claves API de inferencia convencionales. Familias de credenciales, ámbitos y ejemplos con curl:
[Autenticación de gestión](../guides/MANAGEMENT-AUTH.md).
### Autenticación
| Endpoint | Método | Descripción |
| ----------------------------- | ------- | ---------------------------------------------------- |
| `/api/auth/login` | POST | Iniciar sesión |
| `/api/auth/logout` | POST | Cerrar sesión |
| `/api/settings/require-login` | GET/PUT | Activar o desactivar el inicio de sesión obligatorio |
### Gestión de proveedores
| Endpoint | Método | Descripción |
| ---------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `/api/providers` | GET/POST | Listar/crear proveedores |
| `/api/providers/[id]` | GET/PUT/DELETE | Gestionar un proveedor |
| `/api/providers/[id]/test` | POST | Probar la conexión del proveedor |
| `/api/providers/[id]/models` | GET | Listar los modelos del proveedor |
| `/api/providers/validate` | POST | Validar la configuración del proveedor |
| `/api/providers/bulk` | POST | Añadir en bloque claves API para UN proveedor |
| `/api/providers/import` | POST | Importar una LISTA heterogénea de proveedores desde un archivo CSV/JSON analizado (#6836); resultados de fallos parciales por fila |
| `/api/provider-nodes*` | Varios | Gestión de nodos de proveedores |
| `/api/provider-models` | GET/POST/PATCH/DELETE | Modelos personalizados (añadir, actualizar, ocultar/mostrar, eliminar) |
### Flujos de OAuth
| Endpoint | Método | Descripción |
| -------------------------------- | ------ | ------------------------------ |
| `/api/oauth/[provider]/[action]` | Varios | OAuth específico del proveedor |
### Enrutamiento y configuración
| Endpoint | Método | Descripción |
| --------------------- | -------- | -------------------------------------- |
| `/api/models/alias` | GET/POST | Alias de modelos |
| `/api/models/catalog` | GET | Todos los modelos por proveedor + tipo |
| `/api/combos*` | Varios | Gestión de combinaciones |
| `/api/keys*` | Varios | Gestión de claves API |
| `/api/pricing` | GET | Precios de los modelos |
### Uso y análisis
| Endpoint | Método | Descripción |
| -------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/api/usage/history` | GET | Historial de uso |
| `/api/usage/logs` | GET | Registros de uso |
| `/api/usage/request-logs` | GET | Registros a nivel de solicitud |
| `/api/usage/[connectionId]` | GET | Uso por conexión |
| `/api/usage/token-limits` | GET/POST/DELETE | Presupuestos de límite de tokens por clave de API |
| `/api/usage/model-latency-stats` | GET | Agregado móvil de latencia por proveedor/modelo (promedio/p50/p95/p99, tasa de éxito); filtros: `windowHours`/`minSamples`/`maxRows`/`provider`/`model` (#6873) |
| `/api/usage/cache-health` | GET | Resumen del estado de la caché de prompts en `call_logs`: proporción de escritura/lectura, distribución p50/p90/p99 del tamaño de escritura, concentración de escrituras intensivas, desglose por modelo y veredicto `healthy`/`degraded`/`thrash`/`no-data`; parámetros de consulta `range` (`1h`\|`24h`\|`7d`\|`30d`, valor predeterminado `24h`) y `model` opcional (#8827) |
### Configuración
| Endpoint | Método | Descripción |
| ------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/api/settings` | GET/PUT/PATCH | Configuración general |
| `/api/settings/proxy` | GET/PUT | Configuración del proxy de red |
| `/api/settings/proxy/test` | POST | Probar la conexión del proxy |
| `/api/settings/ip-filter` | GET/PUT | Lista de direcciones IP permitidas/bloqueadas |
| `/api/settings/thinking-budget` | GET/PUT | Modo de reescritura de **solicitudes** para pensamiento/razonamiento (transferencia directa / eliminación automática / personalizado / adaptativo). Independiente de la compresión. Consulta [THINKING_BUDGET.md](../guides/THINKING_BUDGET.md). |
| `/api/settings/system-prompt` | GET/PUT | Prompt global del sistema |
| `/api/settings/compression` | GET/PUT | Configuración global de compresión |
| `/api/settings/purge-request-history` | POST | Borrar las filas del registro de solicitudes y los artefactos locales del registro de llamadas |
### Contexto y compresión
| Endpoint | Método | Descripción |
| -------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------- |
| `/api/compression/preview` | POST | Vista previa de la compresión off/lite/standard/aggressive/ultra/RTK/stacked |
| `/api/compression/language-packs` | GET | Lista de paquetes de idioma de Caveman disponibles |
| `/api/compression/rules` | GET | Lista de metadatos de reglas de Caveman |
| `/api/context/caveman/config` | GET/PUT | Alias de configuración específica de Caveman |
| `/api/context/rtk/config` | GET/PUT | Configuración específica de RTK, incluidos filtros personalizados y conservación de la salida sin procesar |
| `/api/context/rtk/filters` | GET | Catálogo de filtros de RTK y diagnósticos de filtros personalizados |
| `/api/context/rtk/test` | POST | Ejecuta una vista previa/prueba de RTK con una carga útil de texto |
| `/api/context/rtk/raw-output/[id]` | GET | Lee la salida sin procesar y censurada conservada mediante el id del puntero |
| `/api/context/combos` | GET/POST | Lista/creación de combinaciones de compresión |
| `/api/context/combos/[id]` | GET/PUT/DELETE | Detalle/actualización/eliminación de una combinación de compresión |
| `/api/context/combos/[id]/assignments` | GET/PUT | Asigna combinaciones de compresión a combinaciones de enrutamiento |
| `/api/context/analytics` | GET | Alias de análisis de compresión |
### Monitorización
| Endpoint | Método | Descripción |
| ------------------------------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/api/sessions` | GET | Seguimiento de sesiones activas |
| `/api/rate-limits` | GET | Límites de tasa por cuenta |
| `/api/monitoring/health` | GET | Comprobación de estado + resumen de proveedores (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`). La vista de gestión incluye `credentialHealth`: valores escalares de la caché de sondeos, `failedConnections` cuando `failed>0` y `staleDbNonOkCount` (`test_status` persistente de SQLite, no el indicador). Consulte [MONITORING_GUIDE.md](../ops/MONITORING_GUIDE.md#credentialhealth-probe-cache-vs-sqlite-test_status). |
| `/api/cache/stats` | GET/DELETE | Estadísticas de caché / vaciado |
| `/api/modality-bridge/stats` | GET | `attempts` en memoria, éxitos/`bridged`, fallos, aciertos de caché, `totalLatencyMs`, `latencySamples`, `averageLatencyMs` calculada sobre las muestras y hora del último uso (se restablece al reiniciar; autenticación de gestión) |
| `/api/modality-bridge/video/runtime` | GET | Comprobación estricta de bucle invertido de confianza antes de la autenticación/sondeo de gestión; disponibilidad y versiones saneadas de FFmpeg/ffprobe (no-store) |
| `/api/modality-bridge/video/extract` | POST | Intermediario interno autenticado de bytes mediante bucle invertido de confianza; entrada de 50 MiB, cola limitada/salida de 32 MiB, capacidad `503`, desconexión `499`, plazo agotado `504`; no es una API pública de carga de archivos |
### Copia de seguridad y exportación/importación
| Endpoint | Método | Descripción |
| --------------------------- | ------ | ------------------------------------------------------------- |
| `/api/db-backups` | GET | Enumerar las copias de seguridad disponibles |
| `/api/db-backups` | PUT | Crear una copia de seguridad manual |
| `/api/db-backups` | POST | Restaurar desde una copia de seguridad específica |
| `/api/db-backups/export` | GET | Descargar la base de datos como archivo .sqlite |
| `/api/db-backups/import` | POST | Cargar un archivo .sqlite para reemplazar la base de datos |
| `/api/db-backups/exportAll` | GET | Descargar la copia de seguridad completa como archivo .tar.gz |
### Sincronización en la nube
| Endpoint | Método | Descripción |
| ---------------------- | ------ | ---------------------------------------- |
| `/api/sync/cloud` | Varios | Operaciones de sincronización en la nube |
| `/api/sync/initialize` | POST | Inicializar la sincronización |
| `/api/cloud/*` | Varios | Gestión de la nube |
### Túneles
| Endpoint | Método | Descripción |
| -------------------------- | ------ | -------------------------------------------------------------------------------- |
| `/api/tunnels/cloudflared` | GET | Leer el estado de instalación/ejecución de Cloudflare Quick Tunnel para el panel |
| `/api/tunnels/cloudflared` | POST | Habilitar o deshabilitar Cloudflare Quick Tunnel (`action=enable/disable`) |
| `/api/tunnels/ngrok` | GET | Leer el estado de ejecución de ngrok Tunnel para el panel |
| `/api/tunnels/ngrok` | POST | Habilitar o deshabilitar ngrok Tunnel (`action=enable/disable`) |
### Herramientas de CLI
| Endpoint | Método | Descripción |
| ---------------------------------- | ------ | ------------------------------------ |
| `/api/cli-tools/claude-settings` | GET | Estado de Claude CLI |
| `/api/cli-tools/codex-settings` | GET | Estado de Codex CLI |
| `/api/cli-tools/droid-settings` | GET | Estado de Droid CLI |
| `/api/cli-tools/openclaw-settings` | GET | Estado de OpenClaw CLI |
| `/api/cli-tools/runtime/[toolId]` | GET | Entorno de ejecución genérico de CLI |
Las respuestas de CLI incluyen: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
### Agentes ACP
| Endpoint | Método | Descripción |
| ----------------- | ------ | --------------------------------------------------------------------------------- |
| `/api/acp/agents` | GET | Enumerar todos los agentes detectados (integrados + personalizados) con su estado |
| `/api/acp/agents` | POST | Añadir un agente personalizado o actualizar la caché de detección |
| `/api/acp/agents` | DELETE | Eliminar un agente personalizado mediante el parámetro de consulta `id` |
La respuesta GET incluye `agents[]` (id, name, binary, version, installed, protocol, isCustom) y `summary` (total, installed, notFound, builtIn, custom).
### Resiliencia y límites de tasa
| Endpoint | Método | Descripción |
| --------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `/api/resilience` | GET/PATCH | Obtener/actualizar la cola de solicitudes, el periodo de espera de las conexiones, el disyuntor del proveedor y la configuración de espera |
| `/api/resilience/reset` | POST | Restablecer los disyuntores de los proveedores |
| `/api/resilience/model-cooldowns` | GET | Enumerar los bloqueos activos por (proveedor, conexión, modelo), ordenados por tiempo restante |
| `/api/resilience/model-cooldowns` | DELETE | Eliminar un bloqueo de modelo — cuerpo `{provider, model}` o `{all: true}` para borrarlos todos |
| `/api/rate-limits` | GET | Estado del límite de tasa por cuenta |
| `/api/rate-limit` | GET | Configuración global del límite de tasa |
> Las cuatro rutas `/api/resilience/*` requieren **autenticación de administración** (`requireManagementAuth`). Consulta [Resiliencia (ampliada)](#resilience-extended) para obtener un desglose completo del disyuntor del proveedor, el periodo de espera de la conexión y el bloqueo del modelo.
### Evaluaciones
| Endpoint | Método | Descripción |
| ------------ | -------- | ---------------------------------------------------------- |
| `/api/evals` | GET/POST | Enumerar conjuntos de evaluación / ejecutar una evaluación |
### Políticas
| Endpoint | Método | Descripción |
| --------------- | --------------- | ----------------------------------- |
| `/api/policies` | GET/POST/DELETE | Gestionar políticas de enrutamiento |
### Cumplimiento
| Endpoint | Método | Descripción |
| --------------------------- | ------ | ------------------------------------------------- |
| `/api/compliance/audit-log` | GET | Registro de auditoría de cumplimiento (últimos N) |
### v1beta (compatible con Gemini)
| Endpoint | Método | Descripción |
| -------------------------- | ------ | ------------------------------------ |
| `/v1beta/models` | GET | Enumerar modelos en formato Gemini |
| `/v1beta/models/{...path}` | POST | Endpoint `generateContent` de Gemini |
Estos endpoints reproducen el formato de la API de Gemini para los clientes que esperan compatibilidad nativa con el SDK de Gemini.
### API internas / del sistema
| Endpoint | Método | Descripción |
| ------------------------ | ------ | --------------------------------------------------------------------------- |
| `/api/init` | GET | Comprobación de inicialización de la aplicación (usada en el primer inicio) |
| `/api/tags` | GET | Etiquetas de modelos compatibles con Ollama (para clientes Ollama) |
| `/api/restart` | POST | Inicia un reinicio controlado del servidor |
| `/api/shutdown` | POST | Inicia un apagado controlado del servidor |
| `/api/system/env/repair` | POST | Repara las variables de entorno del proveedor OAuth |
> **Nota:** Estos endpoints se utilizan internamente por el sistema o para garantizar la compatibilidad con clientes Ollama. Por lo general, los usuarios finales no los invocan.
### Reparación del entorno OAuth _(v3.6.1+)_
```bash
POST /api/system/env/repair
Content-Type: application/json
{
"provider": "claude-code"
}
```
Repara las variables de entorno OAuth ausentes o dañadas de un proveedor específico. Devuelve:
```json
{
"success": true,
"repaired": ["CLAUDE_CODE_OAUTH_CLIENT_ID", "CLAUDE_CODE_OAUTH_CLIENT_SECRET"],
"backupPath": "/home/user/.omniroute/backups/env-repair-2026-04-11.bak"
}
```
---
## Transcripción de audio
```bash
POST /v1/audio/transcriptions
Authorization: Bearer your-api-key
Content-Type: multipart/form-data
```
Transcribe archivos de audio mediante cualquier proveedor de STT configurado. El primer segmento de la ruta selecciona el proveedor nativo (`openai/…`, `deepgram/…`). Las puertas de enlace que vuelven a exponer el modelo de otro proveedor utilizan un identificador cualificado (`openrouter/deepgram/nova-3`).
**Solicitud:**
```bash
curl -X POST http://localhost:20128/v1/audio/transcriptions \
-H "Authorization: Bearer your-api-key" \
-F "file=@recording.mp3" \
-F "model=openai/whisper-1"
```
**Respuesta:**
```json
{
"text": "Hello, this is the transcribed audio content.",
"task": "transcribe",
"language": "en",
"duration": 12.5
}
```
**Ejemplos de identificadores de modelos:** `openai/whisper-1` (requiere una clave de OpenAI), `openrouter/deepgram/nova-3` (requiere una clave de OpenRouter), `deepgram/nova-3` (requiere una clave nativa de Deepgram). Una solicitud simple a `deepgram/nova-3` **no** utiliza OpenRouter.
**Formatos compatibles:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
---
## Compatibilidad con Ollama
Para clientes que utilizan el formato de API de Ollama:
```bash
# Endpoint de chat (formato de Ollama)
POST /v1/api/chat
# Listado de modelos (formato de Ollama)
GET /api/tags
```
Las solicitudes se traducen automáticamente entre los formatos de Ollama y los formatos internos.
## Alias tokenizados de VS Code / sin encabezados
Utilice estos alias cuando una integración no pueda inyectar un encabezado `Authorization` y necesite que la clave de API esté integrada en la URL base.
```bash
# Alias del catálogo al estilo OpenAI
GET /api/v1/vscode/{token}/
GET /api/v1/vscode/{token}/models
# Alias de chat al estilo OpenAI
POST /api/v1/vscode/{token}/chat/completions
POST /api/v1/vscode/{token}/responses
# Alias al estilo Ollama
POST /api/v1/vscode/{token}/api/chat
GET /api/v1/vscode/{token}/api/tags
```
Ejemplo:
```bash
curl https://your-host.example/api/v1/vscode/YOUR_API_KEY/models
curl -X POST https://your-host.example/api/v1/vscode/YOUR_API_KEY/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"auto","messages":[{"role":"user","content":"hello"}]}'
```
Notas:
- Los alias tokenizados reutilizan los mismos controladores que `/v1/*` y `/api/tags`; las estructuras de las respuestas permanecen idénticas.
- Utilice preferentemente `Authorization: Bearer ...` siempre que el cliente admita encabezados personalizados.
- Los tokens incluidos en las URL pueden aparecer en los registros del proxy inverso, el historial del navegador y la telemetría externa a OmniRoute. Trátelos como una opción de compatibilidad, no como el modo de autenticación predeterminado.
---
## Telemetría
```bash
# Obtener el resumen de telemetría de latencia (p50/p95/p99 por proveedor)
GET /api/telemetry/summary
```
**Respuesta:**
```json
{
"providers": {
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
}
}
```
---
## Presupuesto
```bash
# Obtener el estado del presupuesto de todas las claves de API
GET /api/usage/budget
# Establecer o actualizar un presupuesto
POST /api/usage/budget
Content-Type: application/json
{
"apiKeyId": "key-123",
"dailyLimitUsd": 5.00,
"weeklyLimitUsd": 30.00,
"monthlyLimitUsd": 100.00,
"warningThreshold": 0.8,
"resetInterval": "monthly"
}
```
> **Notas sobre el esquema** (`setBudgetSchema`): `apiKeyId` es obligatorio; al menos uno de `dailyLimitUsd`, `weeklyLimitUsd` o `monthlyLimitUsd` debe ser mayor que cero. Campos opcionales: `warningThreshold` (01), `resetInterval` (`daily` | `weekly` | `monthly`), `resetTime` (`HH:MM`). El formato heredado `{keyId, limit, period}` devuelve `400 Bad Request`.
## Límites de tokens
Presupuestos de **tokens** por clave de API (distintos del Presupuesto basado en USD indicado anteriormente). Se aplican directamente en la ruta de la solicitud: cuando el uso de una clave durante la ventana actual alcanza su límite, las solicitudes se rechazan con `429 Too Many Requests`. Los límites pueden restringirse a un `model` específico, a un `provider` o aplicarse de forma `global` a toda la clave; cuando varios límites coinciden con una solicitud, prevalece el más restrictivo.
```bash
# Enumerar los límites de tokens de una clave (incluye el uso actual de la ventana)
GET /api/usage/token-limits?apiKeyId=key-123
# Crear o actualizar un límite de tokens
POST /api/usage/token-limits
Content-Type: application/json
{
"apiKeyId": "key-123",
"scopeType": "model",
"scopeValue": "openai/gpt-4o",
"tokenLimit": 1000000,
"resetInterval": "monthly",
"enabled": true
}
# Eliminar un límite de tokens por id
DELETE /api/usage/token-limits?id=tl-abc
```
> **Notas del esquema** (`setTokenLimitSchema`): `apiKeyId` y `scopeType` (`model` | `provider` | `global`) son obligatorios. `scopeValue` es obligatorio, salvo que `scopeType` sea `global` (por ejemplo, un id de modelo para el ámbito `model` o un id de proveedor para el ámbito `provider`). `tokenLimit` debe ser un entero positivo (convertido desde una cadena). Opcionales: `id` (omítalo para crear, inclúyalo para actualizar), `resetInterval` (`daily` | `weekly` | `monthly`, valor predeterminado `monthly`), `resetTime` (`HH:MM`), `enabled` (valor predeterminado `true`). Las respuestas de `GET` enriquecen cada límite con `tokensUsed`, `remaining`, `windowStart`, `periodStartAt` y `nextResetAt`. Este es un endpoint de administración (la autenticación se aplica de forma centralizada mediante la canalización de autorización).
## Procesamiento de solicitudes
1. El cliente envía una solicitud a `/v1/*`
2. El controlador de rutas llama a `handleChat`, `handleEmbedding`, `handleAudioTranscription` o `handleImageGeneration`
3. Se resuelve el modelo (proveedor/modelo directo o alias/combo)
4. Se seleccionan las credenciales de la base de datos local aplicando el filtrado por disponibilidad de la cuenta
5. Para el chat: `handleChatCore` comprueba la caché semántica/de firmas y resuelve la configuración de compresión del combo
6. La compresión proactiva se ejecuta antes de la traducción al formato del proveedor cuando está habilitada (`lite`, Caveman, RTK o apilada)
7. El ejecutor del proveedor envía la solicitud al servicio ascendente
8. La respuesta se vuelve a traducir al formato del cliente (chat) o se devuelve tal cual (embeddings/imágenes/audio)
9. Se registran el uso, los análisis de compresión y los registros de solicitudes
10. En caso de error, se aplica la alternativa de respaldo según las reglas del combo
Referencia completa de la arquitectura: [`ARCHITECTURE.md`](../architecture/ARCHITECTURE.md)
---
## Administración de combos
Los combos de enrutamiento de nivel superior (ya resumidos en `/api/combos*`) también pueden asignarse individualmente a partir de un patrón de id de modelo, lo que permite redirigir de forma transparente un id de modelo con estilo de OpenAI a un combo.
| Método | Ruta | Descripción |
| ------ | -------------------------------- | -------------------------------------------------------------------------------------- |
| GET | `/api/model-combo-mappings` | Enumerar todas las asignaciones modelo→combo |
| POST | `/api/model-combo-mappings` | Crear una asignación — cuerpo: `{pattern, comboId, priority?, enabled?, description?}` |
| GET | `/api/model-combo-mappings/[id]` | Recuperar una asignación individual |
| PUT | `/api/model-combo-mappings/[id]` | Actualizar los campos de una asignación existente |
| DELETE | `/api/model-combo-mappings/[id]` | Eliminar una asignación |
**Autenticación:** sesión/clave de API de administración (`requireManagementAuth`).
---
## Webhooks
Suscripciones a webhooks salientes para eventos de OmniRoute (finalización de solicitudes, agotamiento de cuotas, rotación de claves, etc.).
| Método | Ruta | Descripción |
| ------ | ------------------------- | -------------------------------------------------------------------------------------- |
| GET | `/api/webhooks` | Enumera los webhooks (los secretos se ocultan como `<prefix>...`) |
| POST | `/api/webhooks` | Crea un webhook — cuerpo: `{url, events?: ["*"], secret?, description?}` |
| GET | `/api/webhooks/[id]` | Recupera un webhook |
| PUT | `/api/webhooks/[id]` | Actualiza url/events/secret/description |
| DELETE | `/api/webhooks/[id]` | Elimina un webhook |
| POST | `/api/webhooks/[id]/test` | Envía una carga útil de prueba a la URL del webhook y devuelve el estado de la entrega |
**Autenticación:** sesión de administración/clave de API (`requireManagementAuth`).
---
## Claves registradas (administración automática)
Utilizadas por el subsistema de administración automática de claves para emitir y rotar claves de API mediante un proveedor o una cuenta subyacente, con cuotas diarias y por hora.
| Método | Ruta | Descripción |
| ------ | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/v1/registered-keys` | Enumera las claves registradas (solo el prefijo oculto) |
| POST | `/api/v1/registered-keys` | Emite una nueva clave registrada — cuerpo: `{name, provider?, accountId?, idempotencyKey?, expiresAt?, dailyBudget?, hourlyBudget?}`. Devuelve la clave sin enmascarar **una sola vez**. Devuelve `429` si se rechaza por cuota. |
| GET | `/api/v1/registered-keys/[id]` | Recupera los metadatos de una clave registrada (sin el material de la clave) |
| DELETE | `/api/v1/registered-keys/[id]` | Revoca una clave registrada |
| POST | `/api/v1/registered-keys/[id]/revoke` | Endpoint de revocación explícita (mismo efecto que DELETE) |
**Autenticación:** clave de API Bearer (`isAuthenticated`). Consulta también `/v1/quotas/check` y `/v1/issues/report`.
---
## Protocolo de agentes
Tareas de agentes en la nube (Claude Code, Codex Cloud, OpenHands, etc.) ejecutadas de forma remota en nombre de los usuarios de OmniRoute.
| Método | Ruta | Descripción |
| ------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/v1/agents/tasks` | Enumera las tareas — admite opcionalmente `?provider=`, `?status=`, `?limit=` (1500, valor predeterminado: 50) |
| POST | `/api/v1/agents/tasks` | Crea una tarea — cuerpo validado mediante `CreateCloudAgentTaskSchema` (`providerId`, `prompt`, `source`, `options?`). Devuelve `201` con el contenedor de la tarea |
| DELETE | `/api/v1/agents/tasks?id=...` | Elimina una tarea |
| GET | `/api/v1/agents/tasks/[id]` | Lee una tarea — actualiza de forma síncrona el estado desde el agente en la nube de origen cuando se ha establecido un `external_id` |
| POST | `/api/v1/agents/tasks/[id]` | Acción discriminada: `{action: "approve"}`, `{action: "message", message}` o `{action: "cancel"}` |
| DELETE | `/api/v1/agents/tasks/[id]` | Elimina una tarea específica por id |
> **Autenticación:** se requiere autenticación de gestión en todos los métodos (`requireCloudAgentManagementAuth`). Antes de v3.8.0, estos no requerían autenticación; consulte el commit `588a0333` para conocer el cambio incompatible.
```bash
# Crear una tarea de Claude Code en la nube
curl -X POST http://localhost:20128/api/v1/agents/tasks \
-H "Authorization: Bearer your-management-key" \
-H "Content-Type: application/json" \
-d '{"providerId":"claude-code-cloud","prompt":"Fix the failing test","source":{"repo":"...","branch":"..."}}'
```
---
## Proxies de gestión
Proxies HTTP(S)/SOCKS salientes que se pueden asignar a proveedores, cuentas o globalmente.
| Método | Ruta | Descripción |
| ------ | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/v1/management/proxies` | Enumera los proxies (con `?id=` devuelve uno; con `?id=&where_used=1` devuelve el grafo de asignaciones) |
| POST | `/api/v1/management/proxies` | Crea un proxy — cuerpo validado mediante `createProxyRegistrySchema` |
| PATCH | `/api/v1/management/proxies` | Actualiza un proxy — cuerpo validado mediante `updateProxyRegistrySchema` (requiere `id`) |
| DELETE | `/api/v1/management/proxies?id=...&force=1` | Elimina un proxy (use `force=1` para desvincular las asignaciones) |
| GET | `/api/v1/management/proxies/assignments` | Enumera las asignaciones — se puede filtrar por `proxy_id`, `scope`, `scope_id`; pase `resolve_connection_id=<id>` para resolver el proxy activo de una conexión |
| PUT | `/api/v1/management/proxies/assignments` | Asigna — cuerpo validado mediante `proxyAssignmentSchema` (`{scope, scopeId?, proxyId?}`). Limpia la caché del despachador |
| PUT | `/api/v1/management/proxies/bulk-assign` | Asigna en bloque — cuerpo validado mediante `bulkProxyAssignmentSchema` (`{scope, scopeIds[], proxyId?}`) |
| GET | `/api/v1/management/proxies/health?hours=24` | Agrega el estado de los proxies (recuentos de éxitos/fallos y latencia) durante un intervalo |
**Autenticación:** sesión de gestión/clave de API en cada ruta (`requireManagementAuth`).
> Los endpoints `POST /api/v1/management/proxies/[id]/assignments` y `POST /api/v1/management/proxies/[id]/health` de la descripción de la tarea se atienden mediante las rutas planas `/assignments` y `/health` que se muestran arriba; no hay subrutas por id en el código base.
---
## Resiliencia (ampliada)
OmniRoute ofrece tres mecanismos independientes para fallos temporales; los siguientes endpoints de administración permiten a los operadores consultarlos y sobrescribirlos:
| Ámbito | Almacenamiento del estado | Consulta | Restablecimiento / limpieza |
| ---------------------- | ------------------------------------------------ | ----------------------------------------- | --------------------------------------------------------------------- |
| Disyuntor de proveedor | `domain_circuit_breakers` + memoria interna | `/api/monitoring/health` | `POST /api/resilience/reset` |
| Pausa de conexión | `rateLimitedUntil` en conexiones de proveedor | `/api/rate-limits`, `/api/providers/[id]` | (se reactiva de forma diferida; se limpia mediante PUT del proveedor) |
| Bloqueo de modelo | Registro de disponibilidad de modelos en memoria | `GET /api/resilience/model-cooldowns` | `DELETE /api/resilience/model-cooldowns` |
`PATCH /api/resilience` acepta sobrescrituras del disyuntor de proveedor en `providerBreaker.oauth` y `providerBreaker.apikey`. Cada perfil admite `degradationThreshold`, `failureThreshold` y `resetTimeoutMs`; los mismos campos están disponibles en Panel de control → Configuración → Resiliencia.
```bash
# Limpiar el bloqueo de un único modelo
curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \
-H "Cookie: auth_token=..." \
-H "Content-Type: application/json" \
-d '{"provider":"openai","model":"gpt-4o-mini"}'
# Eliminar todos los bloqueos
curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \
-H "Cookie: auth_token=..." \
-d '{"all":true}'
```
Referencia conceptual completa y valores predeterminados del disyuntor: consulte [`CLAUDE.md`](../../CLAUDE.md) → "Estado de ejecución de la resiliencia".
---
## Habilidades
Marco de habilidades para ampliar OmniRoute con controladores ejecutables personalizados, además de integraciones con marketplaces.
| Método | Ruta | Descripción |
| ------ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/skills` | Enumera las habilidades instaladas; admite filtros mediante `?q=`, `?mode=on\|off\|auto`, `?source=skillsmp\|skillssh\|local` y paginación |
| GET | `/api/skills/[id]` | Recupera una habilidad |
| PUT | `/api/skills/[id]` | Actualiza una habilidad (nombre, descripción, modo, esquema, controlador, etiquetas) |
| DELETE | `/api/skills/[id]` | Desinstala una habilidad |
| POST | `/api/skills/install` | Instala una habilidad desde un manifiesto sin procesar — cuerpo: `{name, version, description, schema:{input, output}, handlerCode, apiKeyId?}` |
| GET | `/api/skills/executions` | Enumera las ejecuciones recientes de habilidades (registro de auditoría con entradas, salidas y duración) |
| GET | `/api/skills/marketplace?q=...` | Busca u obtiene la lista de elementos populares del marketplace SkillsMP (requiere la configuración `skillsmpApiKey`) |
| POST | `/api/skills/marketplace/install` | Instala una habilidad por id desde SkillsMP |
| GET | `/api/skills/skillssh?q=&limit=` | Busca en el registro skills.sh |
| POST | `/api/skills/skillssh/install` | Instala una habilidad por id desde skills.sh |
**Autenticación:** sesión de administración/clave de API. Las rutas de búsqueda del marketplace aceptan autenticación de administración o una clave de API Bearer (`isAuthenticated`).
---
## Memoria
Almacén persistente de memoria conversacional/factual, limitado por clave de API / sesión.
| Método | Ruta | Descripción |
| ------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/memory` | Enumera memorias — `?apiKeyId=`, `?type=`, `?sessionId=`, `?q=`, con paginación mediante `offset/limit` o `page/limit` |
| POST | `/api/memory` | Crea una memoria — cuerpo validado por Zod: `{content, key, type?, sessionId?, apiKeyId?, metadata?, expiresAt?}` |
| GET | `/api/memory/[id]` | Recupera una memoria |
| DELETE | `/api/memory/[id]` | Elimina una memoria |
| GET | `/api/memory/health` | Estado del subsistema de memoria (conectividad de la BD, backend de embeddings, estado del índice vectorial) |
**Autenticación:** sesión de administración/clave de API (`requireManagementAuth`). Enumeración `type`: `FACTUAL`, `EPISODIC`, `SEMANTIC`, `PROCEDURAL` (consulta `MemoryType` en `src/lib/memory/types.ts`).
---
## Servidor MCP
OmniRoute incluye un servidor Model Context Protocol integrado con 3 transportes (stdio, SSE, streamable-http) y herramientas con ámbitos definidos. Los endpoints del panel que aparecen a continuación leen datos de estado/auditoría y actúan como proxy de los transportes HTTP.
| Método | Ruta | Descripción |
| ------ | ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------- |
| GET | `/api/mcp/status` | Señal de actividad, transporte, estado en línea, última llamada, herramientas principales, tasa de éxito de las últimas 24 h |
| GET | `/api/mcp/tools` | Lista de herramientas MCP con `name`, `description`, `scopes`, `phase`, `auditLevel`, `sourceEndpoints` |
| GET | `/api/mcp/sse` | Abre un flujo SSE para el transporte SSE (devuelve `503` si MCP está deshabilitado o el transporte no coincide) |
| POST | `/api/mcp/sse` | Envía una trama JSON-RPC mediante el transporte SSE |
| GET | `/api/mcp/stream` | Abre el lado SSE del transporte HTTP transmitible (mensajes iniciados por el servidor) |
| POST | `/api/mcp/stream` | Envía una trama JSON-RPC mediante el transporte HTTP transmitible |
| DELETE | `/api/mcp/stream` | Finaliza una sesión HTTP transmitible |
| GET | `/api/mcp/audit` | Consulta el registro de auditoría — `?limit=`, `?offset=`, `?tool=`, `?success=true | false`, `?apiKeyId=` |
| GET | `/api/mcp/audit/stats` | Estadísticas de auditoría agregadas (totales, tasa de éxito, duración media, herramientas principales) |
**Autenticación:** los transportes `sse`/`stream` respetan la superficie de autenticación específica de MCP (clave de API Bearer con el ámbito `mcp`); las rutas `status`/`tools`/`audit*` pueden consultarse desde el panel (no se requiere autenticación adicional aparte de poder acceder al host del panel).
> Ambos transportes HTTP están controlados por `settings.mcpEnabled` y `settings.mcpTransport`: si el transporte no coincide, se devuelve `400`; si MCP está deshabilitado, se devuelve `503`.
---
## Servidor A2A
OmniRoute expone un endpoint A2A (agente a agente) JSON-RPC 2.0, además de un contenedor REST para su uso en inspección/paneles.
### JSON-RPC
```bash
POST /a2a
Authorization: Bearer your-api-key # opcional, salvo que OMNIROUTE_API_KEY esté configurada
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "message/send",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Route this coding task"}]
}
}
```
Métodos compatibles (todos condicionados por `settings.a2aEnabled`):
| Método | Descripción |
| ---------------- | ------------------------------------------------------------------------- |
| `message/send` | Ejecución síncrona de habilidades; devuelve `{task, artifacts, metadata}` |
| `message/stream` | Ejecución SSE en streaming del mismo conjunto de habilidades |
| `tasks/get` | Obtiene una tarea por `taskId` |
| `tasks/cancel` | Cancela una tarea por `taskId` |
Habilidades integradas: `smart-routing`, `quota-management`, `provider-discovery`, `cost-analysis`, `health-report`.
### Tarjeta del agente
```bash
GET /.well-known/agent.json
```
Devuelve la tarjeta pública del agente A2A (nombre, descripción, capacidades, catálogo de habilidades y esquema de autenticación), almacenada públicamente en caché durante 1 h. No requiere autenticación.
### Utilidades REST
| Método | Ruta | Descripción |
| ------ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/a2a/status` | Estado de activación de A2A + estadísticas de tareas + resumen almacenado en caché de la tarjeta del agente |
| GET | `/api/a2a/tasks` | Enumera las tareas — `?state=submitted\|working\|completed\|failed\|cancelled`, `?skill=`, `?limit=` (≤200), `?offset=` |
| POST | `/api/a2a/tasks` | (No implementado como utilidad REST; créela mediante JSON-RPC `message/send`) |
| GET | `/api/a2a/tasks/[id]` | Recupera una tarea |
| POST | `/api/a2a/tasks/[id]/cancel` | Cancela una tarea |
**Autenticación:** las utilidades REST se ejecutan sin autenticación de administración (pueden leerse desde el panel); la ruta JSON-RPC `/a2a` utiliza Bearer `OMNIROUTE_API_KEY` si está configurada.
---
## Nube, evaluaciones y valoración
| Método | Ruta | Descripción |
| ------ | ------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------- | ----------------------------------- |
| POST | `/api/cloud/auth` | Verifica una clave Bearer y devuelve conexiones de proveedores enmascaradas + alias de modelos para clientes de sincronización con la nube |
| POST | `/api/cloud/credentials/update` | Actualiza las credenciales cifradas de un proveedor sincronizado con la nube |
| POST | `/api/cloud/model/resolve` | Resuelve un id de modelo lógico a un proveedor/modelo concreto mediante la tabla de enrutamiento local |
| GET | `/api/cloud/models/alias` | Enumera los alias de modelos tal como se exponen a la sincronización con la nube |
| GET | `/api/assess` | Lee las categorizaciones de la evaluación más reciente (por proveedor/modelo) |
| POST | `/api/assess` | Ejecuta una evaluación — cuerpo: `{scope: {type:"all"} | {type:"provider", providerId} | {type:"model", modelId}, trigger?}` |
| GET | `/api/evals` | Enumera los conjuntos de evaluaciones integrados + las ejecuciones más recientes |
| POST | `/api/evals` | Inicia una ejecución de evaluación |
| POST | `/api/evals/suites` | Crea un conjunto de evaluaciones personalizado — cuerpo validado mediante `evalSuiteSaveSchema` |
| GET | `/api/evals/suites/[id]` | Recupera un conjunto de evaluaciones personalizado |
**Autenticación:** `/api/cloud/auth` valida directamente una clave Bearer; las demás rutas `/api/cloud/*`, `/api/evals/*` y `/api/assess` requieren una sesión/clave de API de administración. El POST de `/api/assess` utiliza `validateBody` con un esquema de ámbito de unión discriminada.
---
## Gestión de ACP (Agent Client Protocol)
como procesos secundarios. Estos endpoints gestionan la detección de agentes ACP y el registro de agentes
personalizados.
| Método | Ruta | Descripción |
| ------ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/acp/agents` | Enumera todos los agentes de CLI conocidos (integrados y personalizados) con su estado de instalación, versión y binario |
| POST | `/api/acp/agents` | Registra un agente ACP personalizado o actualiza la caché — cuerpo: `{id, name, binary, versionCommand, providerAlias, spawnArgs, protocol}` o `{action: "refresh"}` |
| DELETE | `/api/acp/agents` | Elimina un agente ACP personalizado — parámetro de consulta: `?id=<agentId>` |
**Ejemplo de respuesta** (`GET /api/acp/agents`):
```json
{
"agents": [
{
"id": "claude",
"name": "Claude Code CLI",
"binary": "claude",
"version": "1.0.45",
"installed": true,
"protocol": "stdio",
"providerAlias": "claude",
"isCustom": false
},
{
"id": "my-custom-cli",
"name": "My Custom CLI",
"installed": false,
"protocol": "stdio",
"providerAlias": "my-provider",
"isCustom": true
}
],
"cacheTtlMs": 60000,
"cacheAge": 1234
}
```
**Autenticación:** Requiere una sesión de administración (cookie `auth_token` del panel) o una
clave de API con ámbito de administración.
Consulta [Framework ACP](../frameworks/ACP.md) para obtener todos los detalles.
---
## Analítica y observabilidad
Endpoints de analítica en tiempo real para supervisar el enrutamiento, la compresión y la diversidad
de proveedores. Estos endpoints alimentan las páginas de `/dashboard/analytics/*`.
### Analítica de enrutamiento automático
| Método | Ruta | Descripción |
| ------ | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/analytics/auto-routing` | Estadísticas agregadas de enrutamiento automático: llamadas totales, distribución de estrategias, distribución de niveles y principales proveedores |
| GET | `/api/analytics/auto-routing?days=7` | Estadísticas para un intervalo temporal (24 h de forma predeterminada) |
**Ejemplo de respuesta**:
```json
{
"window": "24h",
"totalCalls": 1234,
"strategyBreakdown": {
"rules": 800,
"cost": 200,
"latency": 150,
"sla-aware": 50,
"lkgp": 34
},
"tierBreakdown": {
"ultra": 100,
"pro": 500,
"standard": 400,
"free": 234
},
"topProviders": [
{ "provider": "openai", "calls": 500, "avgLatencyMs": 850 },
{ "provider": "anthropic", "calls": 300, "avgLatencyMs": 1200 }
]
}
```
### Analítica de compresión
| Método | Ruta | Descripción |
| ------ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/analytics/compression` | Estadísticas agregadas de compresión: tokens ahorrados, porcentaje de ahorro, distribución de modos y uso de motores |
**Ejemplo de respuesta**:
```json
{
"window": "24h",
"totalOriginalTokens": 5000000,
"totalCompressedTokens": 3500000,
"totalSavings": 1500000,
"savingsPct": 30.0,
"modeBreakdown": {
"lite": 400,
"standard": 600,
"aggressive": 100,
"ultra": 50,
"rtk": 84
},
"engineBreakdown": {
"caveman": 800,
"rtk": 434
}
}
```
### Seguimiento de la diversidad de proveedores
| Método | Ruta | Descripción |
| ------ | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/analytics/diversity` | Seguimiento de la diversidad basado en la entropía de Shannon: evita puntos únicos de fallo midiendo la distribución entre proveedores |
**Ejemplo de respuesta**:
```json
{
"window": "24h",
"shannonEntropy": 2.45,
"maxEntropy": 3.17,
"diversityRatio": 0.77,
"providerUsage": {
"openai": 0.4,
"anthropic": 0.25,
"google": 0.2,
"kiro": 0.15
},
"warnings": ["OpenAI accounts for 40% of traffic — consider diversifying"]
}
```
**Autenticación:** Requiere una sesión de administración o una clave de API con ámbito de administración.
---
## Operaciones de administración
Endpoints exclusivos para administradores destinados a la gestión operativa.
| Método | Ruta | Descripción |
| ------ | ------------------------ | --------------------------------------------------------------------------------------------------------- |
| GET | `/api/admin/concurrency` | Consulta los límites de concurrencia actuales (globales y por proveedor) |
| POST | `/api/admin/concurrency` | Actualiza los límites de concurrencia — cuerpo: `{global?: number, perProvider?: Record<string, number>}` |
**Autenticación:** Requiere una sesión de gestión con alcance de administrador.
---
## Gestión de herramientas CLI
Gestiona las herramientas CLI que se integran con OmniRoute (antigravity, chipotle, commandCode,
devin-cli, etc.). Consulta la [Referencia de proveedores](./PROVIDER_REFERENCE.md) para ver la lista completa.
| Método | Ruta | Descripción |
| ------ | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/cli-tools/all-statuses` | Estado de todas las herramientas CLI (instalación, versión y última detección) |
| GET | `/api/cli-tools/status` | Detalles del estado de una herramienta CLI (consulta `?tool=`) |
| POST | `/api/cli-tools/apply` | Escribe la configuración generada de una herramienta (`dryRun` muestra una vista previa; `422` + `containerEphemeralTarget` si está en un contenedor; `migration` indica un YAML heredado de Codex) |
| GET | `/api/cli-tools/backups` | Enumera las copias de seguridad de configuración de las herramientas CLI |
| POST | `/api/cli-tools/backups` | Crea una copia de seguridad de todas las configuraciones de las herramientas CLI |
| POST | `/api/cli-tools/backups` | Restaura: el mismo endpoint con `{tool, backupId}` en el cuerpo restaura esa copia de seguridad |
| GET | `/api/cli-tools/antigravity-mitm` | Estado del proxy MITM de Antigravity (la herramienta CLI "antigravity-mitm") |
| POST | `/api/cli-tools/antigravity-mitm/alias` | Configura los alias de antigravity-mitm |
**Autenticación:** Requiere una sesión de gestión.
---
## Habilidades de agentes
Gestiona las habilidades de los agentes de IA (similares a los GPT personalizados de OpenAI, pero para agentes).
| Método | Ruta | Descripción |
| ------ | ---------------------------- | -------------------------------------------------------------------------------------------------------- |
| GET | `/api/agent-skills` | Enumera todas las habilidades de agentes (integradas y personalizadas) |
| GET | `/api/agent-skills/[id]` | Obtiene una habilidad de agente específica |
| POST | `/api/agent-skills` | Crea una habilidad de agente personalizada — cuerpo: `{name, description, prompt, model?, temperature?}` |
| PUT | `/api/agent-skills/[id]` | Actualiza una habilidad de agente personalizada |
| DELETE | `/api/agent-skills/[id]` | Elimina una habilidad de agente personalizada |
| GET | `/api/agent-skills/[id]/raw` | Obtiene el prompt sin procesar y los metadatos (sin ejecución) |
| POST | `/api/agent-skills/generate` | Genera mediante IA una nueva habilidad a partir de una descripción en lenguaje natural |
**Autenticación:** Requiere una sesión de gestión o una clave de API con alcance de gestión.
---
## Gestión de caché
Gestiona la caché semántica y la caché de razonamiento.
| Método | Ruta | Descripción |
| ------ | ---------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/cache` | Resumen de la caché: entradas totales, tasa de aciertos, tamaño en disco |
| GET | `/api/cache/entries` | Lista las entradas almacenadas en caché (con paginación) |
| DELETE | `/api/cache/entries` | Elimina entradas de la caché (filtradas por parámetros de consulta) |
| GET | `/api/cache/stats` | Estadísticas detalladas de la caché (por proveedor y por modelo) |
| GET | `/api/cache/reasoning` | Estado de la caché de razonamiento (para la reproducción del razonamiento) |
| DELETE | `/api/cache/reasoning` | Vacía la caché de razonamiento — parámetros de consulta: `?toolCallId=<id>` (uno), `?provider=<p>` o sin parámetros (todos) |
**Autenticación:** Requiere una sesión de administración.
---
## Sistema de memoria
Gestiona la memoria persistente (FTS5 + incrustaciones vectoriales).
| Método | Ruta | Descripción |
| ------ | ------------------ | ------------------------------------------------------------------------------------------ |
| GET | `/api/memory` | Lista las entradas de memoria (filtradas por ámbito, tipo o consulta de búsqueda) |
| POST | `/api/memory` | Crea una nueva entrada de memoria — cuerpo: `{scope, type, content, metadata?}` |
| GET | `/api/memory/[id]` | Obtiene una entrada de memoria específica |
| PUT | `/api/memory/[id]` | Actualiza una entrada de memoria |
| DELETE | `/api/memory/[id]` | Elimina una entrada de memoria |
| GET | `/api/memory?q=` | Busca en la memoria (FTS5 + vectores) — las estadísticas se incluyen en la misma respuesta |
**Autenticación:** Requiere una sesión de administración o una clave de API con ámbito de administración.
---
## Webhooks
Gestiona las suscripciones de webhooks para eventos.
| Método | Ruta | Descripción |
| ------ | ------------------------------- | ----------------------------------------------------------------------------- |
| GET | `/api/webhooks` | Lista todas las suscripciones de webhooks |
| POST | `/api/webhooks` | Crea una suscripción de webhook — cuerpo: `{url, events[], secret?, active?}` |
| GET | `/api/webhooks/[id]` | Obtiene una suscripción de webhook específica |
| PUT | `/api/webhooks/[id]` | Actualiza una suscripción de webhook |
| DELETE | `/api/webhooks/[id]` | Elimina una suscripción de webhook |
| GET | `/api/webhooks/[id]/deliveries` | Lista el historial de entregas de un webhook (registro de éxitos y errores) |
| POST | `/api/webhooks/[id]/test` | Envía un evento de prueba a un webhook |
**Autenticación:** Requiere una sesión de administración.
Consulta [Marco de webhooks](../frameworks/WEBHOOKS.md) para conocer todos los tipos de eventos.
---
## Framework de Skills
Gestiona Skills (el framework de extensiones agénticas).
| Método | Ruta | Descripción |
| ------ | ------------------------ | ------------------------------------------------------------------------------------------------ |
| GET | `/api/skills` | Enumera todas las skills instaladas (integradas + personalizadas) |
| POST | `/api/skills/install` | Instala una skill desde una ruta local o URL |
| DELETE | `/api/skills/[id]` | Desinstala una skill |
| PUT | `/api/skills/[id]` | Habilita o deshabilita una skill — cuerpo: `{enabled?: boolean, mode?: "on" \| "off" \| "auto"}` |
| POST | `/api/skills/executions` | Ejecuta una skill — cuerpo: `{skillName, apiKeyId, input?, sessionId?}` |
| GET | `/api/skills/executions` | Enumera el historial de ejecuciones de todas las skills (filtra mediante `?apiKeyId=`) |
**Autenticación:** Requiere una sesión de administración o una clave de API con ámbito de administración.
Consulta [Framework de Skills](../frameworks/SKILLS.md) para obtener todos los detalles.
---
## Plugins
Gestiona los plugins de OmniRoute (extensiones de terceros).
| Método | Ruta | Descripción |
| ------ | ---------------------------------- | -------------------------------------- |
| GET | `/api/plugins` | Enumera los plugins instalados |
| POST | `/api/plugins/marketplace/install` | Instala un plugin desde el marketplace |
| DELETE | `/api/plugins/[name]` | Desinstala un plugin |
| POST | `/api/plugins/[name]/activate` | Activa un plugin |
| POST | `/api/plugins/[name]/deactivate` | Desactiva un plugin |
| GET | `/api/plugins/[name]/config` | Obtiene la configuración del plugin |
| PUT | `/api/plugins/[name]/config` | Actualiza la configuración del plugin |
**Autenticación:** Requiere una sesión de administración.
Consulta [Framework de Plugins](../frameworks/PLUGIN_SDK.md) para obtener todos los detalles.
---
## Enrutamiento en sombra
La comparación en sombra / A-B de proveedores **no es una superficie REST independiente**; se configura mediante el enrutamiento combinado (consulta [Auto-Combo](../routing/AUTO-COMBO.md)). Las métricas de comparación por combinación se proporcionan mediante `GET /api/combos/metrics`.
---
## Barreras de protección
Inspecciona las barreras de protección en tiempo de ejecución (detección de PII, detección de inyección de prompts, puente de visión). Las barreras de protección se ejecutan en cada solicitud; la exclusión voluntaria por llamada se realiza mediante el encabezado de solicitud `x-omniroute-disabled-guardrails`; no existe una interfaz persistente para habilitarlas o deshabilitarlas.
| Método | Ruta | Descripción |
| ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/guardrails` | Enumera las barreras de protección registradas y su estado (nombre / habilitada / prioridad) |
| POST | `/api/guardrails/test` | Ejecuta en modo de prueba el pipeline previo a la llamada sobre una entrada de ejemplo — cuerpo: `{input, disabledGuardrails?}` |
**Autenticación:** Requiere una sesión de administración.
Consulta [Seguridad > Barreras de protección](../security/GUARDRAILS.md) para obtener todos los detalles.
---
---
## Autenticación
Consulta [Autenticación de administración](../guides/MANAGEMENT-AUTH.md) para conocer las cuatro
familias de credenciales (sesión del panel, token de CLI local, token de acceso
`oma_live_…`, clave de API con ámbito de administración) y en qué se diferencian de las claves de inferencia.
- Las rutas del panel (`/dashboard/*`) usan la cookie `auth_token`
- El inicio de sesión usa el hash de contraseña guardado; como alternativa, usa `INITIAL_PASSWORD`
- `requireLogin` se puede activar o desactivar mediante `/api/settings/require-login`
- Las rutas `/v1/*` pueden requerir opcionalmente una clave de API Bearer cuando `REQUIRE_API_KEY=true`
- En esta referencia, «token de administración» / «clave de API con ámbito de administración» significa una de las familias descritas en esa guía, no un tipo de secreto adicional sin definir
> **Cambio incompatible (v3.8.0)** — `/api/v1/agents/tasks/*` y los endpoints de administración del período de espera ahora requieren **autenticación de administración** (cookie `auth_token` del panel o una clave de API con ámbito de administración). Los clientes que anteriormente llamaban a estas rutas sin autenticación recibirán `401 Unauthorized`. Consulta el commit `588a0333` (`fix(auth): require management auth for agent and cooldown APIs`).