mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-23 15:42:12 +03:00
Validated on the combined batch board over tip 92ef3c71: static gates clean (changelog, file-size, complexity 2624<=2774, cognitive 1182<=1223, dead-code 411<=416), typecheck:core clean, focused tests green.
Combo without models is now refused at the schema boundary (API 400), the CLI flags it, and openapi.yaml matches the real contract (phantom props removed). combo-* suites + cli-combo-create-models green on the board. Closes #10954. Thank you @maxmad64bis!
8931 lines
261 KiB
YAML
8931 lines
261 KiB
YAML
openapi: 3.1.0
|
||
info:
|
||
title: OmniRoute API
|
||
version: 3.8.50
|
||
description: |
|
||
OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
|
||
endpoint that routes requests to multiple AI providers with load balancing,
|
||
failover, and usage tracking.
|
||
|
||
## Base URLs
|
||
- **Local**: `http://localhost:20128`
|
||
|
||
## Authentication
|
||
All proxy endpoints require a Bearer token (API key managed via the dashboard).
|
||
Management endpoints are protected when `requireLogin` is enabled.
|
||
contact:
|
||
name: OmniRoute
|
||
license:
|
||
name: MIT
|
||
|
||
servers:
|
||
- url: http://localhost:20128
|
||
description: Local development
|
||
|
||
tags:
|
||
- name: Playground
|
||
description: Playground Studio — preset management and prompt improvement
|
||
- name: Memory
|
||
description: Conversational memory management — CRUD, engine status, playground preview, summarization, reindex, and Qdrant settings (plan 21 — v3.8.6). All routes require management auth.
|
||
- name: Chat
|
||
description: OpenAI-compatible chat completions
|
||
- name: Messages
|
||
description: Anthropic-compatible messages
|
||
- name: Responses
|
||
description: OpenAI Responses API
|
||
- name: Embeddings
|
||
description: Text embedding generation
|
||
- name: Images
|
||
description: Image generation
|
||
- name: Audio
|
||
description: Audio speech and transcription
|
||
- name: Moderations
|
||
description: Content moderation
|
||
- name: Rerank
|
||
description: Document reranking
|
||
- name: Models
|
||
description: Available model listing
|
||
- name: Providers
|
||
description: Provider connection management
|
||
- name: Provider Nodes
|
||
description: Provider node configuration
|
||
- name: Proxy Subscriptions
|
||
description: >-
|
||
Operator-supplied proxy subscription links (Karing-style). Nodes are fetched,
|
||
parsed, and synced into the provider/account pool on create, refresh, or the
|
||
background scheduler tick.
|
||
- name: API Keys
|
||
description: API key management
|
||
- name: Session Leases
|
||
description: Client-neutral exclusive managed session connection leases
|
||
- name: Combos
|
||
description: Routing combo management
|
||
- name: Settings
|
||
description: Application settings
|
||
- name: Compression
|
||
description: Prompt compression, RTK filters, Caveman rules, and compression combos
|
||
- name: Usage
|
||
description: Usage analytics and logs
|
||
- name: Translator
|
||
description: Format translation debug & testing
|
||
- name: CLI Tools
|
||
description: CLI tool configuration management
|
||
- name: Embedded Services
|
||
description: >-
|
||
Install, start, stop, and monitor locally-running embedded services (9Router, CLIProxyAPI).
|
||
All routes are LOCAL_ONLY — accessible from loopback only (hard rule #17).
|
||
- name: OAuth
|
||
description: OAuth flows for provider authentication
|
||
- name: System
|
||
description: System management (restart, shutdown, backup)
|
||
- name: Pricing
|
||
description: Model pricing configuration
|
||
- name: Cloud
|
||
description: Cloud worker authentication and sync
|
||
- name: Fallback
|
||
description: Fallback chain management
|
||
- name: Telemetry
|
||
description: Telemetry and token health monitoring
|
||
- name: Agent Skills
|
||
description: >-
|
||
Agent Skills catalog — 42 SKILL.md files (22 REST API + 20 CLI) for external agents,
|
||
MCP clients, and A2A orchestrators to discover OmniRoute capabilities.
|
||
- name: AgentBridge
|
||
description: >-
|
||
MITM proxy manager for 9 IDE agents (Antigravity, Kiro, Copilot, Codex, Cursor, Zed,
|
||
Claude Code, Open Code, Trae). Controls server lifecycle, DNS/model mappings, bypass list,
|
||
and cert management. All routes are LOCAL_ONLY + SPAWN_CAPABLE (hard rules #15, #17).
|
||
See docs/frameworks/AGENTBRIDGE.md.
|
||
- name: Traffic Inspector
|
||
description: >-
|
||
LLM-aware HTTPS traffic debugger with 4 capture modes (AgentBridge, Custom Hosts,
|
||
HTTP_PROXY :8080, System-wide). Provides real-time WebSocket stream, session recording,
|
||
HAR export, SSE merge, and conversation normalization.
|
||
All routes are LOCAL_ONLY + SPAWN_CAPABLE (hard rules #15, #17).
|
||
See docs/frameworks/TRAFFIC_INSPECTOR.md.
|
||
|
||
paths:
|
||
/api/v1/session-leases:
|
||
post:
|
||
tags:
|
||
- Session Leases
|
||
summary: Acquire, renew, or release an exclusive managed connection lease
|
||
description: |
|
||
Requires an API key with `lease:exclusive` and an explicit non-empty
|
||
`allowedConnections` policy. The opaque owner is bound to the authenticated API key;
|
||
the lease owns an eligible connection, not a provider or model. Managed inference
|
||
requests present the owner and exact generation headers. Temporary foreign occupancy
|
||
returns 429 `WAITING_FOR_CAPACITY` with `Retry-After`.
|
||
security:
|
||
- BearerAuth: []
|
||
parameters:
|
||
- name: X-OmniRoute-Lease-Owner
|
||
in: header
|
||
required: true
|
||
schema:
|
||
type: string
|
||
pattern: ^vlo_[A-Za-z0-9_-]{43}$
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
oneOf:
|
||
- type: object
|
||
required: [action, model]
|
||
properties:
|
||
action: { type: string, const: acquire }
|
||
model: { type: string, minLength: 1, maxLength: 512 }
|
||
- type: object
|
||
required: [action, generation]
|
||
properties:
|
||
action: { type: string, const: renew }
|
||
generation: { type: integer, minimum: 1 }
|
||
- type: object
|
||
required: [action, generation]
|
||
properties:
|
||
action: { type: string, const: release }
|
||
generation: { type: integer, minimum: 1 }
|
||
reason:
|
||
type: string
|
||
enum: [OWNER_EXIT, CLIENT_CANCELLED]
|
||
responses:
|
||
"200":
|
||
description: Lease lifecycle state without connection or credential disclosure
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ExclusiveConnectionLeaseLifecycle"
|
||
"400":
|
||
description: Missing or invalid lease context/action
|
||
"401":
|
||
description: Missing or invalid API key
|
||
"403":
|
||
description: Managed lease scope or key configuration required
|
||
"409":
|
||
description: Stale generation, missing binding, or connection fence rejection
|
||
"415":
|
||
description: Lifecycle mutations require application/json
|
||
"429":
|
||
description: Eligible managed connections are held by foreign active leases
|
||
headers:
|
||
Retry-After:
|
||
schema: { type: integer, minimum: 1, maximum: 3600 }
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ExclusiveConnectionLeaseCapacity"
|
||
# --- Playground + Search Tools (plans 17+18) ---
|
||
/api/playground/improve-prompt:
|
||
post:
|
||
tags:
|
||
- Playground
|
||
summary: Improve prompt via LLM
|
||
description: |
|
||
Rewrites the supplied system prompt and/or user prompt using a meta-prompt
|
||
(inspired by Anthropic Console Prompt Improver). Internally calls
|
||
`/v1/chat/completions` with the model specified in the request body.
|
||
Quota is consumed from the caller's account.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- model
|
||
properties:
|
||
system:
|
||
type: string
|
||
maxLength: 50000
|
||
description: System prompt to improve (at least one of system/prompt required)
|
||
prompt:
|
||
type: string
|
||
maxLength: 50000
|
||
description: User prompt to improve
|
||
model:
|
||
type: string
|
||
description: Model to use for the improvement call (e.g. openai/gpt-4o)
|
||
tone:
|
||
type: string
|
||
enum:
|
||
- concise
|
||
- detailed
|
||
default: concise
|
||
responses:
|
||
"200":
|
||
description: Improved prompt(s)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
improvedSystem:
|
||
type: string
|
||
improvedPrompt:
|
||
type: string
|
||
tokensIn:
|
||
type: integer
|
||
tokensOut:
|
||
type: integer
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/playground/presets:
|
||
get:
|
||
tags:
|
||
- Playground
|
||
summary: List playground presets
|
||
description: Returns all saved playground presets ordered by creation date (newest first).
|
||
security:
|
||
- BearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: Preset list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
presets:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PlaygroundPreset"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
post:
|
||
tags:
|
||
- Playground
|
||
summary: Create playground preset
|
||
description: Saves the current playground configuration as a named preset in the database.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PlaygroundPresetCreate"
|
||
responses:
|
||
"201":
|
||
description: Created preset
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PlaygroundPreset"
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/playground/presets/{id}:
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
get:
|
||
tags:
|
||
- Playground
|
||
summary: Get playground preset
|
||
security:
|
||
- BearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: Preset found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PlaygroundPreset"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"404":
|
||
description: Preset not found
|
||
put:
|
||
tags:
|
||
- Playground
|
||
summary: Update playground preset
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PlaygroundPresetCreate"
|
||
responses:
|
||
"200":
|
||
description: Updated preset
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PlaygroundPreset"
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"404":
|
||
description: Preset not found
|
||
delete:
|
||
tags:
|
||
- Playground
|
||
summary: Delete playground preset
|
||
security:
|
||
- BearerAuth: []
|
||
responses:
|
||
"204":
|
||
description: Deleted
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"404":
|
||
description: Preset not found
|
||
# --- Memory Engine (plan 21) ---
|
||
/api/memory:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
summary: List memory entries
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- name: apiKeyId
|
||
in: query
|
||
schema:
|
||
type: string
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum:
|
||
- factual
|
||
- episodic
|
||
- procedural
|
||
- semantic
|
||
- name: sessionId
|
||
in: query
|
||
schema:
|
||
type: string
|
||
- name: q
|
||
in: query
|
||
schema:
|
||
type: string
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 200
|
||
default: 50
|
||
- name: page
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
default: 1
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 0
|
||
responses:
|
||
"200":
|
||
description: Paginated list of memories with stats
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/MemoryEntry"
|
||
total:
|
||
type: integer
|
||
totalPages:
|
||
type: integer
|
||
stats:
|
||
type: object
|
||
properties:
|
||
total:
|
||
type: integer
|
||
tokensUsed:
|
||
type: integer
|
||
hitRate:
|
||
type: number
|
||
cacheStats:
|
||
type: object
|
||
properties:
|
||
hits:
|
||
type: integer
|
||
misses:
|
||
type: integer
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
post:
|
||
tags:
|
||
- Memory
|
||
summary: Create a memory entry
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- content
|
||
- key
|
||
properties:
|
||
content:
|
||
type: string
|
||
minLength: 1
|
||
key:
|
||
type: string
|
||
minLength: 1
|
||
type:
|
||
type: string
|
||
enum:
|
||
- factual
|
||
- episodic
|
||
- procedural
|
||
- semantic
|
||
default: factual
|
||
sessionId:
|
||
type: string
|
||
nullable: true
|
||
apiKeyId:
|
||
type: string
|
||
metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
expiresAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
responses:
|
||
"201":
|
||
description: Created memory entry
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/MemoryEntry"
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/memory/{id}:
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Memory UUID
|
||
get:
|
||
tags:
|
||
- Memory
|
||
summary: Get a single memory entry
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Memory entry
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/MemoryEntry"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"404":
|
||
description: Memory not found
|
||
put:
|
||
tags:
|
||
- Memory
|
||
summary: Update a memory entry
|
||
description: Update `type`, `key`, `content`, and/or `metadata` of an existing memory. If an embedding source is available, the vector in `vec_memories` is also regenerated. Corresponds to `MemoryUpdatePutSchema`.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
type:
|
||
type: string
|
||
enum:
|
||
- factual
|
||
- episodic
|
||
- procedural
|
||
- semantic
|
||
key:
|
||
type: string
|
||
minLength: 1
|
||
content:
|
||
type: string
|
||
minLength: 1
|
||
metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
additionalProperties: false
|
||
responses:
|
||
"200":
|
||
description: Updated memory entry
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/MemoryEntry"
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"404":
|
||
description: Memory not found
|
||
delete:
|
||
tags:
|
||
- Memory
|
||
summary: Delete a memory entry
|
||
description: Deletes the SQLite row, removes the vector from `vec_memories`, and best-effort deletes the point from Qdrant.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Deleted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
success:
|
||
type: boolean
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"404":
|
||
description: Memory not found
|
||
/api/memory/health:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
summary: Memory store health check
|
||
description: Round-trip create→list→delete to verify the store is alive.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Health result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
working:
|
||
type: boolean
|
||
latencyMs:
|
||
type: number
|
||
error:
|
||
type: string
|
||
nullable: true
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/memory/retrieve-preview:
|
||
post:
|
||
tags:
|
||
- Memory
|
||
summary: Dry-run memory retrieval (Playground)
|
||
description: Simulates `retrieveMemories()` for a given query and returns the ranked results with score, tier, and token count. Does NOT modify any memory. Corresponds to `RetrievePreviewSchema`.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- query
|
||
properties:
|
||
query:
|
||
type: string
|
||
minLength: 1
|
||
strategy:
|
||
type: string
|
||
enum:
|
||
- exact
|
||
- semantic
|
||
- hybrid
|
||
default: hybrid
|
||
maxTokens:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 16000
|
||
default: 2000
|
||
apiKeyId:
|
||
type: string
|
||
description: Optional — tests global pool when omitted
|
||
limit:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 100
|
||
default: 20
|
||
additionalProperties: false
|
||
responses:
|
||
"200":
|
||
description: Preview results
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
memories:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
type:
|
||
type: string
|
||
enum:
|
||
- factual
|
||
- episodic
|
||
- procedural
|
||
- semantic
|
||
key:
|
||
type: string
|
||
content:
|
||
type: string
|
||
score:
|
||
type: number
|
||
tokens:
|
||
type: integer
|
||
tier:
|
||
type: string
|
||
enum:
|
||
- fts5
|
||
- vector
|
||
- hybrid-rrf
|
||
- qdrant
|
||
vecScore:
|
||
type: number
|
||
nullable: true
|
||
ftsScore:
|
||
type: number
|
||
nullable: true
|
||
resolution:
|
||
type: object
|
||
properties:
|
||
embeddingSource:
|
||
type: string
|
||
enum:
|
||
- remote
|
||
- static
|
||
- transformers
|
||
nullable: true
|
||
embeddingModel:
|
||
type: string
|
||
nullable: true
|
||
vectorStore:
|
||
type: string
|
||
enum:
|
||
- sqlite-vec
|
||
- qdrant
|
||
- none
|
||
strategyUsed:
|
||
type: string
|
||
enum:
|
||
- exact
|
||
- semantic
|
||
- hybrid
|
||
rerankApplied:
|
||
type: boolean
|
||
fallbackReason:
|
||
type: string
|
||
nullable: true
|
||
totalTokensUsed:
|
||
type: integer
|
||
budgetMaxTokens:
|
||
type: integer
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/memory/embedding-providers:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
summary: List embedding providers
|
||
description: Returns all providers that have embedding-capable models, indicating which have an active API key configured.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Provider list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
providers:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
provider:
|
||
type: string
|
||
hasKey:
|
||
type: boolean
|
||
models:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
description: "Format: provider/model"
|
||
name:
|
||
type: string
|
||
dimensions:
|
||
type: integer
|
||
nullable: true
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/memory/engine-status:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
summary: Memory engine status
|
||
description: Returns the full engine status including keyword tier availability, embedding resolution, vector store statistics (sqlite-vec), Qdrant health, and rerank configuration. Corresponds to `MemoryEngineStatusSchema`.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Engine status
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
keyword:
|
||
type: object
|
||
properties:
|
||
available:
|
||
type: boolean
|
||
backend:
|
||
type: string
|
||
enum:
|
||
- FTS5
|
||
embedding:
|
||
type: object
|
||
properties:
|
||
source:
|
||
type: string
|
||
enum:
|
||
- remote
|
||
- static
|
||
- transformers
|
||
nullable: true
|
||
model:
|
||
type: string
|
||
nullable: true
|
||
dimensions:
|
||
type: integer
|
||
nullable: true
|
||
available:
|
||
type: boolean
|
||
reason:
|
||
type: string
|
||
cacheStats:
|
||
type: object
|
||
properties:
|
||
hits:
|
||
type: integer
|
||
misses:
|
||
type: integer
|
||
size:
|
||
type: integer
|
||
vectorStore:
|
||
type: object
|
||
properties:
|
||
backend:
|
||
type: string
|
||
enum:
|
||
- sqlite-vec
|
||
- qdrant
|
||
- none
|
||
available:
|
||
type: boolean
|
||
rowCount:
|
||
type: integer
|
||
needsReindex:
|
||
type: integer
|
||
reason:
|
||
type: string
|
||
qdrant:
|
||
type: object
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
healthy:
|
||
type: boolean
|
||
nullable: true
|
||
latencyMs:
|
||
type: number
|
||
nullable: true
|
||
error:
|
||
type: string
|
||
nullable: true
|
||
rerank:
|
||
type: object
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
provider:
|
||
type: string
|
||
nullable: true
|
||
model:
|
||
type: string
|
||
nullable: true
|
||
available:
|
||
type: boolean
|
||
reason:
|
||
type: string
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/memory/summarize:
|
||
post:
|
||
tags:
|
||
- Memory
|
||
summary: Compact old memories
|
||
description: "Manually triggers memory compaction for memories older than `olderThanDays`. Use `dryRun: true` to preview candidates. Corresponds to `MemorySummarizeSchema`."
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
olderThanDays:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 365
|
||
default: 30
|
||
apiKeyId:
|
||
type: string
|
||
description: Optional — compacts all keys when omitted
|
||
dryRun:
|
||
type: boolean
|
||
default: false
|
||
additionalProperties: false
|
||
responses:
|
||
"200":
|
||
description: Summarization result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
candidates:
|
||
type: integer
|
||
tokensSaved:
|
||
type: integer
|
||
dryRun:
|
||
type: boolean
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/memory/reindex:
|
||
post:
|
||
tags:
|
||
- Memory
|
||
summary: Trigger vector reindex
|
||
description: "Starts background reindexing of memories with `needs_reindex = 1`. Use `force: true` to regenerate ALL vectors regardless of index status. Corresponds to `MemoryReindexSchema`."
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
force:
|
||
type: boolean
|
||
default: false
|
||
description: When true, marks all memories needs_reindex=1 before running.
|
||
additionalProperties: false
|
||
responses:
|
||
"200":
|
||
description: Reindex started
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
started:
|
||
type: boolean
|
||
pending:
|
||
type: integer
|
||
description: Memories still pending after this batch
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/settings/memory:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
- Settings
|
||
summary: Get memory settings
|
||
description: Returns the extended memory settings including 7 new fields added in plan 21 (embeddingSource, embeddingProviderModel, transformersEnabled, staticEnabled, rerankEnabled, rerankProviderModel, vectorStore).
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Extended memory settings
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/MemorySettingsExtended"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
put:
|
||
tags:
|
||
- Memory
|
||
- Settings
|
||
summary: Update memory settings
|
||
description: "Update any subset of the extended memory settings. All fields are optional; only provided fields are updated. Schema: `MemorySettingsExtendedSchema`."
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/MemorySettingsExtended"
|
||
responses:
|
||
"200":
|
||
description: Updated memory settings
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/MemorySettingsExtended"
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/settings/qdrant:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
- Settings
|
||
summary: Get Qdrant settings
|
||
description: Returns current Qdrant configuration. The `apiKey` field is never returned raw — use `hasApiKey` / `apiKeyMasked` instead.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Qdrant settings
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/QdrantSettings"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
put:
|
||
tags:
|
||
- Memory
|
||
- Settings
|
||
summary: Update Qdrant settings
|
||
description: 'Update Qdrant configuration. Pass `apiKey: ""` to remove the stored key. Schema: `QdrantSettingsUpdateSchema`.'
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
host:
|
||
type: string
|
||
port:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 65535
|
||
collection:
|
||
type: string
|
||
minLength: 1
|
||
embeddingModel:
|
||
type: string
|
||
minLength: 1
|
||
apiKey:
|
||
type: string
|
||
description: Empty string removes the key
|
||
additionalProperties: false
|
||
responses:
|
||
"200":
|
||
description: Updated Qdrant settings
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/QdrantSettings"
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/settings/qdrant/health:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
summary: Qdrant health probe
|
||
description: Performs a liveness check against the configured Qdrant instance. Returns latency and any connection error (sanitized — no stack traces).
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Health result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/QdrantHealthResult"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/settings/qdrant/search:
|
||
post:
|
||
tags:
|
||
- Memory
|
||
summary: Qdrant semantic search test
|
||
description: "Performs a test semantic search against the Qdrant collection. Useful for validating that the integration works end-to-end. Schema: `QdrantSearchSchema`."
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- query
|
||
properties:
|
||
query:
|
||
type: string
|
||
minLength: 1
|
||
topK:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 50
|
||
default: 5
|
||
additionalProperties: false
|
||
responses:
|
||
"200":
|
||
description: Search results
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
results:
|
||
type: array
|
||
items:
|
||
type: object
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"503":
|
||
description: Qdrant unavailable (structured error, no stack trace)
|
||
/api/settings/qdrant/cleanup:
|
||
post:
|
||
tags:
|
||
- Memory
|
||
summary: Clean up expired Qdrant points
|
||
description: Removes Qdrant points for memories that have expired or exceeded the configured retention window.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Cleanup result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
deleted:
|
||
type: integer
|
||
checked:
|
||
type: integer
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"503":
|
||
description: Qdrant unavailable (structured error, no stack trace)
|
||
/api/settings/qdrant/embedding-models:
|
||
get:
|
||
tags:
|
||
- Memory
|
||
summary: List Qdrant embedding models
|
||
description: Returns the list of embedding models available for use with Qdrant.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Embedding models list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
models:
|
||
type: array
|
||
items:
|
||
type: string
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
# ─── Proxy Endpoints ──────────────────────────────────────────
|
||
|
||
/api/v1/chat/completions:
|
||
post:
|
||
tags: [Chat]
|
||
summary: Create chat completion
|
||
description: OpenAI-compatible chat completions endpoint. Routes to configured providers.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ChatCompletionRequest"
|
||
responses:
|
||
"200":
|
||
description: Chat completion response (or SSE stream)
|
||
headers:
|
||
X-OmniRoute-Response-Cost:
|
||
schema:
|
||
type: string
|
||
description: Request cost in USD, fixed 10 decimals (e.g. `0.0001234500`; `0.0000000000` for free/unpriced).
|
||
X-OmniRoute-Tokens-In:
|
||
schema:
|
||
type: string
|
||
description: Input (prompt) token count.
|
||
X-OmniRoute-Tokens-Out:
|
||
schema:
|
||
type: string
|
||
description: Output (completion) token count.
|
||
X-OmniRoute-Model:
|
||
schema:
|
||
type: string
|
||
description: Resolved model.
|
||
X-OmniRoute-Provider:
|
||
schema:
|
||
type: string
|
||
description: Resolved provider alias.
|
||
X-OmniRoute-Latency-Ms:
|
||
schema:
|
||
type: string
|
||
description: Handler latency in milliseconds.
|
||
X-OmniRoute-Cache-Hit:
|
||
schema:
|
||
type: string
|
||
enum: ["true", "false"]
|
||
description: Whether the response was served from cache.
|
||
X-OmniRoute-Fallback-Attempts:
|
||
schema:
|
||
type: string
|
||
description: Number of fallback attempts (only present when > 0).
|
||
X-OmniRoute-Decision:
|
||
schema:
|
||
type: string
|
||
description: >-
|
||
Routing decision trace: `strategy=<name>; provider=<alias>; latency_ms=<n>`.
|
||
`<name>` is the combo strategy (e.g. `priority`, `weighted`, `fusion`) or
|
||
`single` for a non-combo request. Emitted on every completion response.
|
||
X-OmniRoute-Request-Id:
|
||
schema:
|
||
type: string
|
||
description: Request correlation id (present when known).
|
||
X-OmniRoute-Version:
|
||
schema:
|
||
type: string
|
||
description: OmniRoute build version (always present).
|
||
X-OmniRoute-Cost-Saved:
|
||
schema:
|
||
type: string
|
||
description: >-
|
||
On a semantic-cache HIT, the original (would-have-been) cost in USD that
|
||
the cache avoided (fixed 10 decimals). Present only on cache hits;
|
||
X-OmniRoute-Response-Cost is 0 for the same response (incremental cost).
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ChatCompletionResponse"
|
||
text/event-stream:
|
||
schema:
|
||
type: string
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"502":
|
||
description: All upstream providers failed
|
||
|
||
/api/v1/ws:
|
||
get:
|
||
tags: [Chat]
|
||
summary: Chat completion over WebSocket (handshake + upgrade)
|
||
description: >-
|
||
OpenAI-compatible chat over a WebSocket connection. `GET` with
|
||
`?handshake=1` returns the connection descriptor (auth path, message
|
||
protocol and live-event channels) as JSON; a plain `GET` without an
|
||
Upgrade returns `426 Upgrade Required`. After upgrading, the client
|
||
exchanges JSON frames — `{type:"request", id, payload:{model, messages}}`
|
||
to start a completion and `{type:"cancel", id}` to abort it. A separate
|
||
live channel (default port `LIVE_WS_PORT=20129`, path `/live`) streams
|
||
dashboard events on the `requests`, `combo` and `credentials` topics with
|
||
a 15s heartbeat. Requires an API key.
|
||
security:
|
||
- BearerAuth: []
|
||
parameters:
|
||
- name: handshake
|
||
in: query
|
||
description: Set to `1` to receive the JSON connection descriptor instead of upgrading.
|
||
required: false
|
||
schema:
|
||
type: string
|
||
enum: ["1"]
|
||
responses:
|
||
"101":
|
||
description: WebSocket upgrade successful
|
||
"200":
|
||
description: Handshake descriptor (auth path, message protocol, live channels)
|
||
"401":
|
||
description: WebSocket auth required (no credential supplied)
|
||
"403":
|
||
description: Invalid WebSocket credential
|
||
"426":
|
||
description: Upgrade Required — connect via WebSocket or use `?handshake=1`
|
||
|
||
/api/v1/providers/{provider}/chat/completions:
|
||
post:
|
||
tags: [Chat]
|
||
summary: Create chat completion (provider-specific)
|
||
description: Routes to a specific provider by name.
|
||
security:
|
||
- BearerAuth: []
|
||
parameters:
|
||
- name: provider
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ChatCompletionRequest"
|
||
responses:
|
||
"200":
|
||
description: Chat completion response
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
|
||
/api/v1/api/chat:
|
||
post:
|
||
tags: [Chat]
|
||
summary: Ollama-compatible chat endpoint
|
||
description: Provides compatibility with Ollama's /api/chat format.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Chat response (JSON or streaming)
|
||
|
||
/api/v1/messages:
|
||
post:
|
||
tags: [Messages]
|
||
summary: Create message (Anthropic-compatible)
|
||
description: Anthropic Messages API endpoint. Routes to Claude providers.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/MessagesRequest"
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Message response (or SSE stream). Non-streaming success responses
|
||
carry the `X-OmniRoute-*` cost-telemetry headers (see
|
||
`POST /api/v1/chat/completions`), including `X-OmniRoute-Request-Id`
|
||
and `X-OmniRoute-Version`.
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
|
||
/api/v1/messages/count_tokens:
|
||
post:
|
||
tags: [Messages]
|
||
summary: Count tokens for a message
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Token count
|
||
|
||
/api/v1/responses:
|
||
post:
|
||
tags: [Responses]
|
||
summary: Create response (OpenAI Responses API)
|
||
description: OpenAI Responses API endpoint.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Response object or SSE stream. Non-streaming success responses carry
|
||
the `X-OmniRoute-*` cost-telemetry headers (see
|
||
`POST /api/v1/chat/completions`), including `X-OmniRoute-Request-Id`
|
||
and `X-OmniRoute-Version`.
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
|
||
/api/v1/embeddings:
|
||
post:
|
||
tags: [Embeddings]
|
||
summary: Create embeddings
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [input, model]
|
||
properties:
|
||
input:
|
||
description: >-
|
||
Text, token IDs, or up to 32 canonical multimodal items. Structured media
|
||
input is accepted only when the resolved registry model advertises the
|
||
requested modalities. URL sources must be public HTTPS and are fetched
|
||
server-side into bounded inline media (redirect revalidation, timeout,
|
||
size limits, public DNS checks, and connection pinning) before provider
|
||
submission. Inline media is limited to 8 MiB decoded per item and 16 MiB
|
||
decoded per request. Canonical items are translated to provider-native
|
||
request shapes (Jina modality-keyed objects / Gemini embedContent parts)
|
||
rather than forwarded unchanged.
|
||
oneOf:
|
||
- type: string
|
||
- type: array
|
||
minItems: 1
|
||
items:
|
||
type: string
|
||
- type: array
|
||
minItems: 1
|
||
items:
|
||
type: integer
|
||
minimum: 0
|
||
- type: array
|
||
minItems: 1
|
||
items:
|
||
type: array
|
||
minItems: 1
|
||
items:
|
||
type: integer
|
||
minimum: 0
|
||
- type: array
|
||
minItems: 1
|
||
maxItems: 32
|
||
items:
|
||
$ref: "#/components/schemas/EmbeddingMultimodalItem"
|
||
model:
|
||
type: string
|
||
dimensions:
|
||
type: integer
|
||
minimum: 1
|
||
encoding_format:
|
||
type: string
|
||
enum: [float, base64]
|
||
additionalProperties: true
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Embedding vectors. Success responses carry the `X-OmniRoute-*`
|
||
cost-telemetry headers (see `POST /api/v1/chat/completions`); media
|
||
cost is computed per modality when pricing is available, otherwise
|
||
`0` (fail-open).
|
||
|
||
/api/v1/multimodal-embeddings:
|
||
post:
|
||
tags: [Embeddings]
|
||
summary: Create embeddings (Jina multimodal-embeddings alias)
|
||
description: >-
|
||
Same handler as `POST /api/v1/embeddings`. Provided so Jina-compatible
|
||
clients that call `/v1/multimodal-embeddings` do not receive HTTP 404
|
||
`unknown_route`.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [input, model]
|
||
additionalProperties: true
|
||
responses:
|
||
"200":
|
||
description: Embedding vectors (same contract as POST /api/v1/embeddings).
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
get:
|
||
tags: [Embeddings]
|
||
summary: List embedding models (Jina multimodal-embeddings alias)
|
||
security:
|
||
- BearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: Embedding model catalog (same as GET /api/v1/embeddings).
|
||
|
||
/api/v1/providers/{provider}/embeddings:
|
||
post:
|
||
tags: [Embeddings]
|
||
summary: Create embeddings (provider-specific)
|
||
security:
|
||
- BearerAuth: []
|
||
parameters:
|
||
- name: provider
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Embedding vectors
|
||
|
||
/api/v1/images/generations:
|
||
post:
|
||
tags: [Images]
|
||
summary: Generate images
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [prompt]
|
||
properties:
|
||
prompt:
|
||
type: string
|
||
model:
|
||
type: string
|
||
n:
|
||
type: integer
|
||
default: 1
|
||
size:
|
||
type: string
|
||
default: 1024x1024
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Generated images. Success responses carry the `X-OmniRoute-*`
|
||
cost-telemetry headers (see `POST /api/v1/chat/completions`); image
|
||
cost is computed per image when pricing is available, otherwise `0`
|
||
(fail-open).
|
||
|
||
/api/v1/providers/{provider}/images/generations:
|
||
post:
|
||
tags: [Images]
|
||
summary: Generate images (provider-specific)
|
||
security:
|
||
- BearerAuth: []
|
||
parameters:
|
||
- name: provider
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Generated images
|
||
|
||
/api/v1/audio/speech:
|
||
post:
|
||
tags: [Audio]
|
||
summary: Generate speech audio
|
||
description: Text-to-speech endpoint. Routes to configured TTS providers.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [input]
|
||
properties:
|
||
input:
|
||
type: string
|
||
model:
|
||
type: string
|
||
voice:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Audio data. Success responses carry the `X-OmniRoute-*`
|
||
cost-telemetry headers (see `POST /api/v1/chat/completions`); speech
|
||
cost is computed per character when pricing is available, otherwise
|
||
`0` (fail-open).
|
||
|
||
/api/v1/audio/transcriptions:
|
||
post:
|
||
tags: [Audio]
|
||
summary: Transcribe audio
|
||
description: Audio-to-text transcription endpoint.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
required: [file]
|
||
properties:
|
||
file:
|
||
type: string
|
||
format: binary
|
||
model:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Transcription result. Success responses carry the `X-OmniRoute-*`
|
||
cost-telemetry headers (see `POST /api/v1/chat/completions`);
|
||
transcription cost is computed per second when pricing is available,
|
||
otherwise `0` (fail-open).
|
||
|
||
/api/v1/moderations:
|
||
post:
|
||
tags: [Moderations]
|
||
summary: Create moderation
|
||
description: Content moderation endpoint. Routes to configured moderation providers.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [input]
|
||
properties:
|
||
input:
|
||
oneOf:
|
||
- type: string
|
||
- type: array
|
||
items:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Moderation result. Success responses carry the `X-OmniRoute-*`
|
||
cost-telemetry headers (see `POST /api/v1/chat/completions`);
|
||
moderations are always cost `0` (free).
|
||
|
||
/api/v1/rerank:
|
||
post:
|
||
tags: [Rerank]
|
||
summary: Rerank documents
|
||
description: Document reranking endpoint.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [query, documents]
|
||
properties:
|
||
query:
|
||
type: string
|
||
documents:
|
||
type: array
|
||
items:
|
||
type: string
|
||
model:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: >-
|
||
Reranked documents. Success responses carry the `X-OmniRoute-*`
|
||
cost-telemetry headers (see `POST /api/v1/chat/completions`); rerank
|
||
cost is computed per search-unit when pricing is available,
|
||
otherwise `0` (fail-open).
|
||
|
||
/api/v1:
|
||
get:
|
||
tags: [System]
|
||
summary: API v1 root endpoint
|
||
description: Returns basic API info and status.
|
||
security:
|
||
- BearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: API info
|
||
|
||
/api/v1/models:
|
||
get:
|
||
tags: [Models]
|
||
summary: List available models
|
||
description: Returns all models available across configured providers.
|
||
security:
|
||
- BearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: Model list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
object:
|
||
type: string
|
||
example: list
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/Model"
|
||
|
||
/api/v1/providers/{provider}/models:
|
||
get:
|
||
tags: [Models]
|
||
summary: List models for a specific provider
|
||
description: Returns only models for the selected provider with provider prefix removed from each model id.
|
||
security:
|
||
- BearerAuth: []
|
||
parameters:
|
||
- in: path
|
||
name: provider
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Provider id or alias (for example `openai`, `claude`, `cc`).
|
||
responses:
|
||
"200":
|
||
description: Provider-scoped model list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
object:
|
||
type: string
|
||
example: list
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/Model"
|
||
"400":
|
||
description: Unknown provider
|
||
|
||
/api/models:
|
||
get:
|
||
tags: [Models]
|
||
summary: List models (management)
|
||
responses:
|
||
"200":
|
||
description: Internal model list with aliases
|
||
|
||
/api/models/alias:
|
||
post:
|
||
tags: [Models]
|
||
summary: Create or update a model alias
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Alias created/updated
|
||
|
||
/api/models/catalog:
|
||
get:
|
||
tags: [Models]
|
||
summary: Get full model catalog
|
||
responses:
|
||
"200":
|
||
description: Complete catalog with all providers
|
||
|
||
# ─── Management Endpoints ──────────────────────────────────────
|
||
|
||
/api/providers:
|
||
get:
|
||
tags: [Providers]
|
||
summary: List provider connections
|
||
responses:
|
||
"200":
|
||
description: Provider connection list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
connections:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ProviderConnection"
|
||
post:
|
||
tags: [Providers]
|
||
summary: Create provider connection
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ProviderConnectionCreate"
|
||
responses:
|
||
"201":
|
||
description: Created provider connection
|
||
|
||
/api/providers/{id}:
|
||
get:
|
||
tags: [Providers]
|
||
summary: Get provider connection
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Provider connection details
|
||
"404":
|
||
description: Provider not found
|
||
patch:
|
||
tags: [Providers]
|
||
summary: Update provider connection
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ProviderConnectionCreate"
|
||
responses:
|
||
"200":
|
||
description: Updated provider
|
||
delete:
|
||
tags: [Providers]
|
||
summary: Delete provider connection
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Provider deleted
|
||
|
||
/api/providers/{id}/test:
|
||
post:
|
||
tags: [Providers]
|
||
summary: Test provider connection
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Test result
|
||
|
||
/api/providers/{id}/models:
|
||
get:
|
||
tags: [Providers]
|
||
summary: List models for a provider
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Provider model list
|
||
|
||
/api/providers/cursor/agent-availability:
|
||
get:
|
||
tags: [Providers]
|
||
summary: Check cursor-agent availability
|
||
description: "Credential-free, informational check for whether cursor-agent is installed and authenticated on this host — backs the dashboard's dismissible install-nudge banner. Returns only cursorAgentAvailable (boolean); never tokens or machineId."
|
||
x-loopback-only: true
|
||
responses:
|
||
"200":
|
||
description: Availability result
|
||
|
||
/api/providers/test-batch:
|
||
post:
|
||
tags: [Providers]
|
||
summary: Test multiple providers at once
|
||
responses:
|
||
"200":
|
||
description: Batch test results
|
||
|
||
/api/providers/validate:
|
||
post:
|
||
tags: [Providers]
|
||
summary: Validate provider credentials
|
||
responses:
|
||
"200":
|
||
description: Validation result
|
||
|
||
/api/providers/client:
|
||
get:
|
||
tags: [Providers]
|
||
summary: Get client-side provider info
|
||
responses:
|
||
"200":
|
||
description: Provider info for frontend
|
||
|
||
/api/providers/agy-auth/import:
|
||
post:
|
||
tags: [Providers]
|
||
summary: Import an Antigravity CLI (agy) token file as an `agy` connection
|
||
responses:
|
||
"200":
|
||
description: Created or updated provider connection
|
||
|
||
/api/providers/agy-auth/import-bulk:
|
||
post:
|
||
tags: [Providers]
|
||
summary: Bulk-import multiple Antigravity CLI (agy) token files (up to 50)
|
||
responses:
|
||
"200":
|
||
description: Per-entry import results (success/failed counts)
|
||
|
||
/api/providers/agy-auth/zip-extract:
|
||
post:
|
||
tags: [Providers]
|
||
summary: Extract `.json` token files from an uploaded ZIP for agy bulk import
|
||
responses:
|
||
"200":
|
||
description: Extracted token-file entries
|
||
|
||
/api/providers/agy-auth/apply-local:
|
||
post:
|
||
tags: [Providers]
|
||
summary: Auto-detect and import the local Antigravity CLI (agy) login from disk
|
||
responses:
|
||
"200":
|
||
description: Created or updated provider connection
|
||
"404":
|
||
description: No local agy login found
|
||
|
||
/api/provider-nodes:
|
||
get:
|
||
tags: [Provider Nodes]
|
||
summary: List provider nodes
|
||
responses:
|
||
"200":
|
||
description: Provider node list
|
||
post:
|
||
tags: [Provider Nodes]
|
||
summary: Create provider node
|
||
responses:
|
||
"201":
|
||
description: Created node
|
||
|
||
/api/provider-nodes/{id}:
|
||
patch:
|
||
tags: [Provider Nodes]
|
||
summary: Update provider node
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Updated node
|
||
delete:
|
||
tags: [Provider Nodes]
|
||
summary: Delete provider node
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Node deleted
|
||
|
||
/api/provider-nodes/validate:
|
||
post:
|
||
tags: [Provider Nodes]
|
||
summary: Validate a provider node
|
||
responses:
|
||
"200":
|
||
description: Validation result
|
||
|
||
/api/provider-models:
|
||
get:
|
||
tags: [Provider Nodes]
|
||
summary: List provider models
|
||
responses:
|
||
"200":
|
||
description: Provider model list
|
||
|
||
/api/keys:
|
||
get:
|
||
tags: [API Keys]
|
||
summary: List API keys
|
||
responses:
|
||
"200":
|
||
description: API key list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
keys:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ApiKey"
|
||
"401":
|
||
description: Authentication required
|
||
post:
|
||
tags: [API Keys]
|
||
summary: Create API key
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [label]
|
||
properties:
|
||
label:
|
||
type: string
|
||
responses:
|
||
"201":
|
||
description: Created API key (includes full key value)
|
||
"401":
|
||
description: Authentication required
|
||
|
||
/api/keys/{id}:
|
||
get:
|
||
tags: [API Keys]
|
||
summary: Get API key
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: API key metadata
|
||
"401":
|
||
description: Authentication required
|
||
"404":
|
||
description: Key not found
|
||
patch:
|
||
tags: [API Keys]
|
||
summary: Update API key
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
responses:
|
||
"200":
|
||
description: API key settings updated
|
||
"400":
|
||
description: Invalid update request
|
||
"401":
|
||
description: Authentication required
|
||
"404":
|
||
description: Key not found
|
||
delete:
|
||
tags: [API Keys]
|
||
summary: Delete API key
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Key deleted
|
||
"401":
|
||
description: Authentication required
|
||
"404":
|
||
description: Key not found
|
||
|
||
/api/combos:
|
||
get:
|
||
tags: [Combos]
|
||
summary: List routing combos
|
||
responses:
|
||
"200":
|
||
description: Combo list
|
||
post:
|
||
tags: [Combos]
|
||
summary: Create routing combo
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ComboCreate"
|
||
responses:
|
||
"201":
|
||
description: Created combo
|
||
|
||
/api/combos/{id}:
|
||
get:
|
||
tags: [Combos]
|
||
summary: Get combo by ID
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Combo details
|
||
"404":
|
||
description: Combo not found
|
||
put:
|
||
tags: [Combos]
|
||
summary: Update combo
|
||
description: >-
|
||
Partial update: the body is merged onto the stored combo, so a field left out keeps
|
||
its current value. An array that IS sent replaces the stored one outright.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated combo
|
||
"400":
|
||
description: Invalid body, or the resulting combo fails validation
|
||
"404":
|
||
description: Combo not found
|
||
"409":
|
||
description: Name already taken, or the combo is quota-share managed
|
||
patch:
|
||
tags: [Combos]
|
||
summary: Update combo
|
||
description: >-
|
||
Partial update: the body is merged onto the stored combo, so a field left out keeps
|
||
its current value. An array that IS sent replaces the stored one outright.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated combo
|
||
"400":
|
||
description: Invalid body, or the resulting combo fails validation
|
||
"404":
|
||
description: Combo not found
|
||
"409":
|
||
description: Name already taken, or the combo is quota-share managed
|
||
delete:
|
||
tags: [Combos]
|
||
summary: Delete combo
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Combo deleted
|
||
|
||
/api/combos/metrics:
|
||
get:
|
||
tags: [Combos]
|
||
summary: Get combo metrics
|
||
responses:
|
||
"200":
|
||
description: Metrics for combos
|
||
|
||
/api/combos/test:
|
||
post:
|
||
tags: [Combos]
|
||
summary: Test a combo configuration
|
||
responses:
|
||
"200":
|
||
description: Test result
|
||
|
||
/api/settings:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get application settings
|
||
responses:
|
||
"200":
|
||
description: Current settings
|
||
patch:
|
||
tags: [Settings]
|
||
summary: Update settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated settings
|
||
|
||
/api/settings/purge-request-history:
|
||
post:
|
||
tags: [Settings]
|
||
summary: Clear request log history
|
||
description: Deletes `call_logs`, legacy `request_detail_logs`, and local request artifact files under `DATA_DIR/call_logs`.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Request history cleared
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
deleted:
|
||
type: integer
|
||
deletedArtifacts:
|
||
type: integer
|
||
deletedDetailedLogs:
|
||
type: integer
|
||
errors:
|
||
type: integer
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Cleanup failed or reported errors
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
deleted:
|
||
type: integer
|
||
deletedArtifacts:
|
||
type: integer
|
||
deletedDetailedLogs:
|
||
type: integer
|
||
errors:
|
||
type: integer
|
||
error:
|
||
type: object
|
||
|
||
/api/settings/compression:
|
||
get:
|
||
tags: [Compression]
|
||
summary: Get global compression settings
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Current compression settings
|
||
put:
|
||
tags: [Compression]
|
||
summary: Update global compression settings
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
defaultMode:
|
||
type: string
|
||
enum: [off, lite, standard, aggressive, ultra, rtk, stacked]
|
||
autoTriggerMode:
|
||
type: string
|
||
enum: [off, lite, standard, aggressive, ultra, rtk, stacked]
|
||
autoTriggerTokens:
|
||
type: integer
|
||
minimum: 0
|
||
rtkConfig:
|
||
type: object
|
||
additionalProperties: true
|
||
stackedPipeline:
|
||
type: array
|
||
items:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated compression settings
|
||
|
||
/api/settings/compression/mcp-accessibility:
|
||
get:
|
||
tags: [Compression]
|
||
summary: Get the MCP tool-output accessibility (trimming) config
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Current mcpAccessibility config
|
||
put:
|
||
tags: [Compression]
|
||
summary: Update the MCP tool-output accessibility (trimming) config
|
||
description: >-
|
||
Partial-merge update. Numeric floors (e.g. a maxTextChars below the truncation-tail
|
||
reserve) are folded back to the safe defaults server-side, so the response reflects the
|
||
effective config.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
maxTextChars:
|
||
type: integer
|
||
minimum: 1
|
||
collapseThreshold:
|
||
type: integer
|
||
minimum: 1
|
||
collapseKeepHead:
|
||
type: integer
|
||
minimum: 0
|
||
collapseKeepTail:
|
||
type: integer
|
||
minimum: 0
|
||
minLengthToProcess:
|
||
type: integer
|
||
minimum: 1
|
||
responses:
|
||
"200":
|
||
description: Updated mcpAccessibility config (numeric floors applied)
|
||
|
||
/api/compression/preview:
|
||
post:
|
||
tags: [Compression]
|
||
summary: Preview compression for a message payload
|
||
security:
|
||
- BearerAuth: []
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [messages, mode]
|
||
properties:
|
||
mode:
|
||
type: string
|
||
enum: [off, lite, standard, aggressive, ultra, rtk, stacked]
|
||
messages:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [role, content]
|
||
properties:
|
||
role:
|
||
type: string
|
||
content:
|
||
oneOf:
|
||
- type: string
|
||
- type: array
|
||
items: {}
|
||
config:
|
||
type: object
|
||
additionalProperties: true
|
||
responses:
|
||
"200":
|
||
description: Compression preview with diff, validation, and stats
|
||
|
||
/api/compression/language-packs:
|
||
get:
|
||
tags: [Compression]
|
||
summary: List Caveman compression language packs
|
||
security:
|
||
- BearerAuth: []
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Available languages and rule-pack metadata
|
||
|
||
/api/compression/rules:
|
||
get:
|
||
tags: [Compression]
|
||
summary: List Caveman compression rule metadata
|
||
security:
|
||
- BearerAuth: []
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Caveman rule metadata
|
||
|
||
/api/context/rtk/config:
|
||
get:
|
||
tags: [Compression]
|
||
summary: Get RTK compression settings
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Current RTK config
|
||
put:
|
||
tags: [Compression]
|
||
summary: Update RTK compression settings
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
intensity:
|
||
type: string
|
||
enum: [minimal, standard, aggressive]
|
||
customFiltersEnabled:
|
||
type: boolean
|
||
trustProjectFilters:
|
||
type: boolean
|
||
rawOutputRetention:
|
||
type: string
|
||
enum: [never, failures, always]
|
||
rawOutputMaxBytes:
|
||
type: integer
|
||
responses:
|
||
"200":
|
||
description: Updated RTK config
|
||
|
||
/api/context/rtk/filters:
|
||
get:
|
||
tags: [Compression]
|
||
summary: List RTK filters and load diagnostics
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: RTK filter catalog and diagnostics
|
||
|
||
/api/context/rtk/import:
|
||
post:
|
||
tags: [Compression]
|
||
summary: Validate or install an RTK TOML schema v1 filter file
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [action, content]
|
||
additionalProperties: false
|
||
properties:
|
||
action:
|
||
type: string
|
||
enum: [validate, install]
|
||
content:
|
||
type: string
|
||
maxLength: 1048576
|
||
overwrite:
|
||
type: boolean
|
||
description: Replace an existing global file and create a backup
|
||
responses:
|
||
"200":
|
||
description: Filter metadata, inline-test outcomes, warnings, and installation status
|
||
"400":
|
||
description: Invalid TOML, schema, regular expression, inline test, or install request
|
||
|
||
/api/context/rtk/test:
|
||
post:
|
||
tags: [Compression]
|
||
summary: Run RTK compression preview for text
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [text]
|
||
properties:
|
||
text:
|
||
type: string
|
||
command:
|
||
type: string
|
||
config:
|
||
type: object
|
||
additionalProperties: true
|
||
responses:
|
||
"200":
|
||
description: Detection and RTK compression result
|
||
|
||
/api/context/rtk/raw-output/{id}:
|
||
get:
|
||
tags: [Compression]
|
||
summary: Read retained redacted RTK raw output
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema:
|
||
type: string
|
||
pattern: "^[a-f0-9]{24}$"
|
||
responses:
|
||
"200":
|
||
description: Raw output text
|
||
"404":
|
||
description: Raw output not found
|
||
|
||
/api/settings/payload-rules:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get payload rules configuration
|
||
description: |
|
||
Returns the current payload rules used to mutate outgoing request payloads before they
|
||
are sent upstream.
|
||
|
||
Requires a dashboard management session cookie when management auth is enabled.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Current payload rules configuration
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PayloadRulesConfig"
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
"500":
|
||
description: Failed to read payload rules configuration
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ApiErrorResponse"
|
||
put:
|
||
tags: [Settings]
|
||
summary: Update payload rules configuration
|
||
description: |
|
||
Persists and hot reloads payload rules. The legacy input field `default-raw` is accepted
|
||
on writes and normalized to `defaultRaw` in responses/runtime state.
|
||
|
||
Requires a dashboard management session cookie when management auth is enabled.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/UpdatePayloadRulesRequest"
|
||
responses:
|
||
"200":
|
||
description: Updated payload rules configuration
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PayloadRulesConfig"
|
||
"400":
|
||
$ref: "#/components/responses/ValidationError"
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
"500":
|
||
description: Failed to update payload rules configuration
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ApiErrorResponse"
|
||
|
||
/api/settings/combo-defaults:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get combo default settings
|
||
responses:
|
||
"200":
|
||
description: Default combo settings
|
||
|
||
/api/settings/proxy:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get proxy settings
|
||
responses:
|
||
"200":
|
||
description: Current proxy settings
|
||
patch:
|
||
tags: [Settings]
|
||
summary: Update proxy settings
|
||
responses:
|
||
"200":
|
||
description: Updated proxy settings
|
||
|
||
/api/settings/proxy/test:
|
||
post:
|
||
tags: [Settings]
|
||
summary: Test proxy connection
|
||
responses:
|
||
"200":
|
||
description: Test result
|
||
|
||
/api/settings/require-login:
|
||
post:
|
||
tags: [Settings]
|
||
summary: Toggle login requirement
|
||
responses:
|
||
"200":
|
||
description: Updated
|
||
|
||
/api/settings/ip-filter:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get IP filter configuration
|
||
description: Returns the current IP filter settings including blacklist, whitelist, and temp bans.
|
||
responses:
|
||
"200":
|
||
description: IP filter configuration
|
||
put:
|
||
tags: [Settings]
|
||
summary: Update IP filter configuration
|
||
description: |
|
||
Configure IP filtering with blacklist/whitelist modes, add/remove individual IPs, and manage temp bans.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
mode:
|
||
type: string
|
||
enum: [blacklist, whitelist]
|
||
blacklist:
|
||
type: array
|
||
items:
|
||
type: string
|
||
whitelist:
|
||
type: array
|
||
items:
|
||
type: string
|
||
addBlacklist:
|
||
type: string
|
||
removeBlacklist:
|
||
type: string
|
||
addWhitelist:
|
||
type: string
|
||
removeWhitelist:
|
||
type: string
|
||
tempBan:
|
||
type: object
|
||
properties:
|
||
ip:
|
||
type: string
|
||
durationMs:
|
||
type: integer
|
||
reason:
|
||
type: string
|
||
removeBan:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Updated IP filter configuration
|
||
|
||
/api/settings/system-prompt:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get system prompt configuration
|
||
description: Returns the current system prompt injection settings.
|
||
responses:
|
||
"200":
|
||
description: System prompt configuration
|
||
put:
|
||
tags: [Settings]
|
||
summary: Update system prompt configuration
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
prompt:
|
||
type: string
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"200":
|
||
description: Updated system prompt configuration
|
||
|
||
/api/settings/thinking-budget:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get thinking budget configuration
|
||
description: Returns the current thinking/reasoning budget settings for AI models.
|
||
responses:
|
||
"200":
|
||
description: Thinking budget configuration
|
||
put:
|
||
tags: [Settings]
|
||
summary: Update thinking budget configuration
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
mode:
|
||
type: string
|
||
description: Thinking mode (e.g., auto, manual, disabled)
|
||
customBudget:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 131072
|
||
effortLevel:
|
||
type: string
|
||
enum: [none, low, medium, high]
|
||
responses:
|
||
"200":
|
||
description: Updated thinking budget configuration
|
||
|
||
/api/rate-limit:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get rate limit configuration
|
||
responses:
|
||
"200":
|
||
description: Rate limit settings
|
||
post:
|
||
tags: [Settings]
|
||
summary: Update rate limit configuration
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated rate limit settings
|
||
|
||
/api/tags:
|
||
get:
|
||
tags: [System]
|
||
summary: List Ollama-compatible model tags
|
||
description: Returns models in Ollama /api/tags format for Ollama client compatibility
|
||
responses:
|
||
"200":
|
||
description: Ollama model tags
|
||
|
||
# ─── Proxy Subscriptions ───────────────────────────────────────
|
||
|
||
/api/v1/management/proxy-subscriptions:
|
||
get:
|
||
tags: [Proxy Subscriptions]
|
||
summary: List proxy subscriptions
|
||
description: >-
|
||
Lists all operator-supplied proxy subscription links. Also starts the
|
||
background auto-refresh scheduler (idempotent) so enabled subscriptions
|
||
stay in sync. Credentials embedded in `url` are redacted in the response.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Subscription list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ProxySubscription"
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
post:
|
||
tags: [Proxy Subscriptions]
|
||
summary: Create a proxy subscription
|
||
description: >-
|
||
Creates a subscription record. If `mode` is `rule`, at least one entry in
|
||
`ruleProviders` is required. `updateIntervalMinutes` defaults to 60 and
|
||
`enabled` defaults to `false` when omitted or not exactly `true`.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [name, url]
|
||
properties:
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
url:
|
||
type: string
|
||
minLength: 1
|
||
mode:
|
||
type: string
|
||
enum: [global, rule]
|
||
default: global
|
||
ruleProviders:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Required (non-empty) when mode is "rule".
|
||
localCoreEndpoint:
|
||
type: string
|
||
nullable: true
|
||
updateIntervalMinutes:
|
||
type: integer
|
||
default: 60
|
||
enabled:
|
||
type: boolean
|
||
default: false
|
||
responses:
|
||
"201":
|
||
description: Created subscription (url redacted)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ProxySubscription"
|
||
"400":
|
||
description: Missing name/url, or ruleProviders empty while mode is "rule"
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
|
||
/api/v1/management/proxy-subscriptions/{id}:
|
||
get:
|
||
tags: [Proxy Subscriptions]
|
||
summary: Get a proxy subscription
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Subscription detail (url redacted)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ProxySubscription"
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
"404":
|
||
description: Subscription not found
|
||
patch:
|
||
tags: [Proxy Subscriptions]
|
||
summary: Update a proxy subscription
|
||
description: >-
|
||
Partial update — only fields present in the body are changed
|
||
(name/url/mode/ruleProviders/localCoreEndpoint/updateIntervalMinutes/enabled).
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
url:
|
||
type: string
|
||
mode:
|
||
type: string
|
||
enum: [global, rule]
|
||
ruleProviders:
|
||
type: array
|
||
items:
|
||
type: string
|
||
localCoreEndpoint:
|
||
type: string
|
||
nullable: true
|
||
updateIntervalMinutes:
|
||
type: integer
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"200":
|
||
description: Updated subscription (url redacted)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ProxySubscription"
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
"404":
|
||
description: Subscription not found
|
||
delete:
|
||
tags: [Proxy Subscriptions]
|
||
summary: Delete a proxy subscription
|
||
description: Removes the subscription record and unbinds/drops its synced proxy_registry rows.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Deleted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
deleted:
|
||
type: boolean
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
"404":
|
||
description: Subscription not found
|
||
|
||
/api/v1/management/proxy-subscriptions/{id}/nodes:
|
||
get:
|
||
tags: [Proxy Subscriptions]
|
||
summary: Get a subscription's last-parsed node summary
|
||
description: >-
|
||
Returns the last-parsed node list without re-fetching the (possibly slow)
|
||
subscription URL.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Last-parsed node summary
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
mode:
|
||
type: string
|
||
enum: [global, rule]
|
||
enabled:
|
||
type: boolean
|
||
status:
|
||
type: string
|
||
enum: [ok, error, empty]
|
||
error:
|
||
type: string
|
||
nullable: true
|
||
lastFetchedAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
nodes:
|
||
type: array
|
||
items: {}
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
"404":
|
||
description: Subscription not found
|
||
|
||
/api/v1/management/proxy-subscriptions/{id}/refresh:
|
||
post:
|
||
tags: [Proxy Subscriptions]
|
||
summary: Refresh a proxy subscription
|
||
description: >-
|
||
Re-fetches and re-parses the subscription URL, syncs its nodes into
|
||
`proxy_registry`, and (re)binds the pool.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Sync result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
subscriptionId:
|
||
type: string
|
||
nodes:
|
||
type: integer
|
||
needsCore:
|
||
type: integer
|
||
boundProxies:
|
||
type: integer
|
||
status:
|
||
type: string
|
||
enum: [ok, error, empty]
|
||
error:
|
||
type: string
|
||
nullable: true
|
||
applied:
|
||
type: boolean
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
"404":
|
||
description: Subscription not found
|
||
|
||
# ─── Usage & Analytics ─────────────────────────────────────────
|
||
|
||
/api/usage/analytics:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get usage analytics
|
||
parameters:
|
||
- name: period
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [day, week, month]
|
||
default: day
|
||
responses:
|
||
"200":
|
||
description: Usage analytics data
|
||
|
||
/api/usage/call-logs:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get call logs
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 50
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 0
|
||
responses:
|
||
"200":
|
||
description: Paginated call logs
|
||
|
||
/api/usage/call-logs/{id}:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get a specific call log
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Call log detail
|
||
|
||
/api/usage/{connectionId}:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get usage for a specific connection
|
||
parameters:
|
||
- name: connectionId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Connection usage data
|
||
|
||
/api/usage/history:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get usage history
|
||
responses:
|
||
"200":
|
||
description: Historical usage data
|
||
|
||
/api/usage/logs:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get usage logs
|
||
responses:
|
||
"200":
|
||
description: Usage log entries
|
||
|
||
/api/usage/proxy-logs:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get proxy logs
|
||
responses:
|
||
"200":
|
||
description: Proxy log entries
|
||
|
||
/api/usage/request-logs:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get request logs
|
||
responses:
|
||
"200":
|
||
description: Request log entries
|
||
|
||
/api/usage/budget:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get usage budget status
|
||
description: Returns current budget limits and consumption.
|
||
responses:
|
||
"200":
|
||
description: Budget status
|
||
post:
|
||
tags: [Usage]
|
||
summary: Configure usage budget
|
||
description: Set or update budget limits for usage tracking.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated budget configuration
|
||
|
||
/api/usage/cache-health:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get prompt-cache health summary
|
||
description: |
|
||
Summarizes the `write/read` cache ratio from `call_logs` for a time window:
|
||
distribution (p50/p90/p99/max of cache-write tokens), warm/cold/rewrite/uncached
|
||
call counts, the "heavy write" outlier share (10x the window median, floored at
|
||
1024 tokens — Anthropic's cache-creation minimum), and a per-model breakdown.
|
||
Only successful (`status = 200`) calls with a non-null cache column are counted.
|
||
parameters:
|
||
- name: range
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [1h, 24h, 7d, 30d]
|
||
default: 24h
|
||
- name: model
|
||
in: query
|
||
description: Filter to one model or requested-model alias (1-200 chars).
|
||
schema:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 200
|
||
responses:
|
||
"200":
|
||
description: Cache health summary for the requested window
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
totalCalls:
|
||
type: integer
|
||
cacheReadTotal:
|
||
type: integer
|
||
cacheWriteTotal:
|
||
type: integer
|
||
writeReadRatio:
|
||
type: number
|
||
warmCalls:
|
||
type: integer
|
||
coldCalls:
|
||
type: integer
|
||
rewriteCalls:
|
||
type: integer
|
||
uncachedCalls:
|
||
type: integer
|
||
writeP50:
|
||
type: integer
|
||
writeP90:
|
||
type: integer
|
||
writeP99:
|
||
type: integer
|
||
writeMax:
|
||
type: integer
|
||
heavyWriteCalls:
|
||
type: integer
|
||
heavyWriteCallShare:
|
||
type: number
|
||
heavyWriteTokenShare:
|
||
type: number
|
||
heavyWriteThreshold:
|
||
type: integer
|
||
verdict:
|
||
type: string
|
||
enum: [healthy, degraded, thrash, no-data]
|
||
byModel:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
model:
|
||
type: string
|
||
calls:
|
||
type: integer
|
||
cacheReadTotal:
|
||
type: integer
|
||
cacheWriteTotal:
|
||
type: integer
|
||
writeReadRatio:
|
||
type: number
|
||
heavyWriteCalls:
|
||
type: integer
|
||
timeRange:
|
||
type: string
|
||
since:
|
||
type: string
|
||
format: date-time
|
||
truncated:
|
||
type: boolean
|
||
description: True when the window held more than 5000 rows and only the newest were summarized.
|
||
"400":
|
||
description: Invalid query parameters
|
||
|
||
/api/usage/model-latency-stats:
|
||
get:
|
||
tags: [Usage]
|
||
summary: Get per-model/provider latency statistics
|
||
description: >-
|
||
Aggregates `usage_history` rows into per-(provider, model) latency stats
|
||
(avg/p50/p95/p99, std-dev, TTFT, tokens/sec) over a rolling window. Falls
|
||
back from successful-only to all-sample rows when the successful count is
|
||
below `minSamples`.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
parameters:
|
||
- name: windowHours
|
||
in: query
|
||
schema:
|
||
type: number
|
||
minimum: 0
|
||
exclusiveMinimum: true
|
||
maximum: 720
|
||
default: 24
|
||
- name: minSamples
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
default: 1
|
||
- name: maxRows
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 50000
|
||
default: 10000
|
||
- name: provider
|
||
in: query
|
||
schema:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
- name: model
|
||
in: query
|
||
schema:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 256
|
||
responses:
|
||
"200":
|
||
description: Latency stats keyed by provider/model, plus the window used
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
entries:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
provider:
|
||
type: string
|
||
model:
|
||
type: string
|
||
key:
|
||
type: string
|
||
totalRequests:
|
||
type: integer
|
||
successfulRequests:
|
||
type: integer
|
||
successRate:
|
||
type: number
|
||
avgLatencyMs:
|
||
type: number
|
||
p50LatencyMs:
|
||
type: number
|
||
p95LatencyMs:
|
||
type: number
|
||
p99LatencyMs:
|
||
type: number
|
||
latencyStdDev:
|
||
type: number
|
||
windowHours:
|
||
type: number
|
||
avgTtftMs:
|
||
type: number
|
||
avgE2ELatencyMs:
|
||
type: number
|
||
avgTokensPerSecond:
|
||
type: number
|
||
windowHours:
|
||
type: number
|
||
generatedAt:
|
||
type: string
|
||
format: date-time
|
||
"400":
|
||
description: Invalid query parameters
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"403":
|
||
$ref: "#/components/responses/ManagementInvalidToken"
|
||
|
||
# ─── Pricing ───────────────────────────────────────────────────
|
||
|
||
/api/pricing:
|
||
get:
|
||
tags: [Pricing]
|
||
summary: Get model pricing
|
||
responses:
|
||
"200":
|
||
description: Current pricing configuration
|
||
post:
|
||
tags: [Pricing]
|
||
summary: Set model pricing
|
||
responses:
|
||
"200":
|
||
description: Updated pricing
|
||
|
||
/api/pricing/defaults:
|
||
get:
|
||
tags: [Pricing]
|
||
summary: Get default pricing
|
||
responses:
|
||
"200":
|
||
description: Default pricing data
|
||
|
||
/api/pricing/models:
|
||
get:
|
||
tags: [Pricing]
|
||
summary: Get pricing per model
|
||
description: Returns pricing information organized by model.
|
||
responses:
|
||
"200":
|
||
description: Per-model pricing data
|
||
|
||
# ─── Translator ────────────────────────────────────────────────
|
||
|
||
/api/translator/detect:
|
||
post:
|
||
tags: [Translator]
|
||
summary: Detect request format
|
||
description: Detects the API format of a request body (OpenAI, Claude, Gemini, etc.)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [body]
|
||
properties:
|
||
body:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Detected format
|
||
|
||
/api/translator/translate:
|
||
post:
|
||
tags: [Translator]
|
||
summary: Translate between formats
|
||
description: Converts a request between API formats (e.g. Claude → OpenAI)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [sourceFormat, targetFormat, body]
|
||
properties:
|
||
step:
|
||
type: string
|
||
sourceFormat:
|
||
type: string
|
||
targetFormat:
|
||
type: string
|
||
provider:
|
||
type: string
|
||
body:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Translated request
|
||
|
||
/api/translator/send:
|
||
post:
|
||
tags: [Translator]
|
||
summary: Send translated request to provider
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [provider, body]
|
||
properties:
|
||
provider:
|
||
type: string
|
||
body:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Provider response (may be SSE stream)
|
||
|
||
/api/translator/history:
|
||
get:
|
||
tags: [Translator]
|
||
summary: Get translation history
|
||
description: Returns recent translation events for the Live Monitor
|
||
responses:
|
||
"200":
|
||
description: Translation history entries
|
||
|
||
# ─── CLI Remote Mode ───────────────────────────────────────────
|
||
|
||
/api/cli/connect:
|
||
post:
|
||
tags: [CLI Remote Mode]
|
||
summary: Exchange the management password for a scoped CLI access token
|
||
description: >
|
||
Remote-mode bootstrap. Public (password-gated) route: verifies the
|
||
management password with brute-force lockout, then mints an `oma_`
|
||
access token. The plaintext token is returned once.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [password]
|
||
properties:
|
||
password: { type: string }
|
||
name: { type: string }
|
||
scope: { type: string, enum: [read, write, admin] }
|
||
expiresInDays: { type: integer, minimum: 1, maximum: 3650 }
|
||
responses:
|
||
"200":
|
||
description: Token minted (token returned once)
|
||
"401":
|
||
description: Invalid password
|
||
"429":
|
||
description: Too many failed attempts
|
||
|
||
/api/cli/whoami:
|
||
get:
|
||
tags: [CLI Remote Mode]
|
||
summary: Report the current credential (scope, name, expiry)
|
||
responses:
|
||
"200":
|
||
description: Authenticated; access-token details when applicable
|
||
"401":
|
||
description: Authentication required
|
||
|
||
/api/cli/tokens:
|
||
get:
|
||
tags: [CLI Remote Mode]
|
||
summary: List access tokens (masked) — admin scope
|
||
responses:
|
||
"200":
|
||
description: Masked token list
|
||
"403":
|
||
description: Insufficient scope
|
||
post:
|
||
tags: [CLI Remote Mode]
|
||
summary: Create a scoped access token — admin scope
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [name]
|
||
properties:
|
||
name: { type: string }
|
||
scope: { type: string, enum: [read, write, admin] }
|
||
expiresInDays: { type: integer, minimum: 1, maximum: 3650 }
|
||
responses:
|
||
"200":
|
||
description: Token created (token returned once)
|
||
"403":
|
||
description: Insufficient scope
|
||
|
||
/api/cli/tokens/{id}:
|
||
delete:
|
||
tags: [CLI Remote Mode]
|
||
summary: Revoke an access token by id or display prefix — admin scope
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema: { type: string }
|
||
responses:
|
||
"200":
|
||
description: Token revoked
|
||
"403":
|
||
description: Insufficient scope
|
||
"404":
|
||
description: Token not found or already revoked
|
||
|
||
# ─── CLI Tools ─────────────────────────────────────────────────
|
||
|
||
/api/cli-tools/backups:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: List CLI tool backups
|
||
responses:
|
||
"200":
|
||
description: Backup list
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Create CLI tool backup
|
||
responses:
|
||
"200":
|
||
description: Backup created
|
||
|
||
/api/cli-tools/runtime/{toolId}:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get runtime status for a CLI tool
|
||
parameters:
|
||
- name: toolId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Runtime status
|
||
|
||
/api/cli-tools/guide-settings/{toolId}:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get guide settings for a tool
|
||
parameters:
|
||
- name: toolId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Guide settings
|
||
|
||
/api/cli-tools/antigravity-mitm:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Antigravity MITM proxy settings
|
||
responses:
|
||
"200":
|
||
description: MITM proxy configuration
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Update Antigravity MITM proxy settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated MITM proxy configuration
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Reset Antigravity MITM proxy settings
|
||
responses:
|
||
"200":
|
||
description: MITM proxy settings reset
|
||
|
||
/api/cli-tools/antigravity-mitm/alias:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Antigravity MITM alias configuration
|
||
responses:
|
||
"200":
|
||
description: Alias configuration
|
||
put:
|
||
tags: [CLI Tools]
|
||
summary: Update Antigravity MITM alias configuration
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated alias configuration
|
||
|
||
/api/cli-tools/claude-settings:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Claude CLI settings
|
||
responses:
|
||
"200":
|
||
description: Claude CLI configuration
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Apply Claude CLI settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Claude CLI settings applied
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Reset Claude CLI settings
|
||
responses:
|
||
"200":
|
||
description: Claude CLI settings reset
|
||
|
||
/api/cli-tools/cline-settings:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Cline CLI settings
|
||
responses:
|
||
"200":
|
||
description: Cline CLI configuration
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Apply Cline CLI settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Cline CLI settings applied
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Reset Cline CLI settings
|
||
responses:
|
||
"200":
|
||
description: Cline CLI settings reset
|
||
|
||
/api/cli-tools/codex-profiles:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Codex profiles
|
||
responses:
|
||
"200":
|
||
description: Codex profile list
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Create Codex profile
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Profile created
|
||
put:
|
||
tags: [CLI Tools]
|
||
summary: Update Codex profile
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Profile updated
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Delete Codex profile
|
||
responses:
|
||
"200":
|
||
description: Profile deleted
|
||
|
||
/api/cli-tools/codex-settings:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Codex CLI settings
|
||
responses:
|
||
"200":
|
||
description: Codex CLI configuration
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Apply Codex CLI settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Codex CLI settings applied
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Reset Codex CLI settings
|
||
responses:
|
||
"200":
|
||
description: Codex CLI settings reset
|
||
|
||
/api/cli-tools/droid-settings:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Droid CLI settings
|
||
responses:
|
||
"200":
|
||
description: Droid CLI configuration
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Apply Droid CLI settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Droid CLI settings applied
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Reset Droid CLI settings
|
||
responses:
|
||
"200":
|
||
description: Droid CLI settings reset
|
||
|
||
/api/cli-tools/kilo-settings:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get Kilo CLI settings
|
||
responses:
|
||
"200":
|
||
description: Kilo CLI configuration
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Apply Kilo CLI settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Kilo CLI settings applied
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Reset Kilo CLI settings
|
||
responses:
|
||
"200":
|
||
description: Kilo CLI settings reset
|
||
|
||
/api/cli-tools/openclaw-settings:
|
||
get:
|
||
tags: [CLI Tools]
|
||
summary: Get OpenClaw CLI settings
|
||
responses:
|
||
"200":
|
||
description: OpenClaw CLI configuration
|
||
post:
|
||
tags: [CLI Tools]
|
||
summary: Apply OpenClaw CLI settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: OpenClaw CLI settings applied
|
||
delete:
|
||
tags: [CLI Tools]
|
||
summary: Reset OpenClaw CLI settings
|
||
responses:
|
||
"200":
|
||
description: OpenClaw CLI settings reset
|
||
|
||
# ─── Embedded Services ─────────────────────────────────────────
|
||
# All routes LOCAL_ONLY (loopback only) — hard rule #17.
|
||
# See docs/frameworks/EMBEDDED-SERVICES.md for full reference.
|
||
|
||
/api/services/9router/install:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Install 9Router from npm
|
||
description: >-
|
||
Installs the `9router` npm package under DATA_DIR/services/9router/.
|
||
Uses execFile (no shell interpolation — hard rule #13).
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
description: npm version tag or semver to install
|
||
responses:
|
||
"200":
|
||
description: Install succeeded
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
path:
|
||
type: string
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: npm install failed
|
||
|
||
/api/services/9router/start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Start 9Router
|
||
description: >-
|
||
Spawns the 9Router process. Idempotent if already running.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service started (or already running)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
"409":
|
||
description: 9Router is not installed
|
||
"503":
|
||
description: Start failed
|
||
|
||
/api/services/9router/stop:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Stop 9Router
|
||
description: >-
|
||
Gracefully stops 9Router (SIGTERM → 15 s → SIGKILL). Idempotent.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service stopped
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
"503":
|
||
description: Stop failed
|
||
|
||
/api/services/9router/restart:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Restart 9Router
|
||
description: >-
|
||
Equivalent to stop() then start() under the operation lock.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service restarted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
|
||
/api/services/9router/update:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Update 9Router to a newer npm version
|
||
description: >-
|
||
Stops the service (if running), installs the newer npm version, then restarts.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
responses:
|
||
"200":
|
||
description: Update succeeded
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
previousVersion:
|
||
type: string
|
||
installedVersion:
|
||
type: string
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/9router/rotate-key:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Rotate the 9Router API key
|
||
description: >-
|
||
Generates a new API key, encrypts it at-rest, and restarts the service to
|
||
apply it. The plaintext key is never returned.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Key rotated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
keyRotated:
|
||
type: boolean
|
||
restarted:
|
||
type: boolean
|
||
"500":
|
||
description: Rotation failed
|
||
|
||
/api/services/9router/status:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: Get 9Router status
|
||
description: >-
|
||
Returns combined live supervisor state and DB metadata.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Status response
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatusExtended"
|
||
"500":
|
||
description: Status read failed
|
||
|
||
/api/services/9router/auto-start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle 9Router auto-start
|
||
description: >-
|
||
When enabled, 9Router starts automatically on the next OmniRoute boot.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"200":
|
||
description: Auto-start flag updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
autoStart:
|
||
type: boolean
|
||
"400":
|
||
description: Invalid request body
|
||
|
||
/api/services/9router/auto-restart-adopted:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle 9Router auto-restart-when-adopted
|
||
description: >-
|
||
When enabled, an externally-adopted (not OmniRoute-spawned) 9Router
|
||
process is restarted under OmniRoute's own supervisor on the next
|
||
health-check cycle instead of being left as adopted-only.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"204":
|
||
description: Flag updated
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/cliproxy/install:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Install CLIProxyAPI from npm
|
||
description: >-
|
||
Installs the CLIProxyAPI package under DATA_DIR/services/cliproxy/.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
responses:
|
||
"200":
|
||
description: Install succeeded
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: npm install failed
|
||
|
||
/api/services/cliproxy/start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Start CLIProxyAPI
|
||
description: >-
|
||
Spawns the CLIProxyAPI process. Idempotent if already running.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service started
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
"409":
|
||
description: CLIProxyAPI is not installed
|
||
"503":
|
||
description: Start failed
|
||
|
||
/api/services/cliproxy/stop:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Stop CLIProxyAPI
|
||
description: >-
|
||
Gracefully stops CLIProxyAPI. Idempotent.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service stopped
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
|
||
/api/services/cliproxy/restart:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Restart CLIProxyAPI
|
||
description: >-
|
||
stop() then start() under the operation lock.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service restarted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
|
||
/api/services/cliproxy/update:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Update CLIProxyAPI to a newer npm version
|
||
description: >-
|
||
Stops, installs newer version, restarts.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
responses:
|
||
"200":
|
||
description: Update succeeded
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/cliproxy/status:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: Get CLIProxyAPI status
|
||
description: >-
|
||
Returns live supervisor state and DB metadata (no apiKeyMasked — CLIProxyAPI
|
||
does not use an injected API key).
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Status response
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
|
||
/api/services/cliproxy/auto-start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle CLIProxyAPI auto-start
|
||
description: >-
|
||
When enabled, CLIProxyAPI starts automatically on the next OmniRoute boot.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"200":
|
||
description: Auto-start flag updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
autoStart:
|
||
type: boolean
|
||
"400":
|
||
description: Invalid request body
|
||
|
||
/api/services/cliproxy/auto-restart-adopted:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle CLIProxyAPI auto-restart-when-adopted
|
||
description: >-
|
||
When enabled, an externally-adopted (not OmniRoute-spawned) CLIProxyAPI
|
||
process is restarted under OmniRoute's own supervisor on the next
|
||
health-check cycle instead of being left as adopted-only.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"204":
|
||
description: Flag updated
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/mux/install:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Install Mux from npm
|
||
description: >-
|
||
Installs the `mux` npm package (coder/mux — local agent-orchestration
|
||
daemon) under DATA_DIR/services/mux/. **LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
responses:
|
||
"200":
|
||
description: Install succeeded
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: npm install failed
|
||
|
||
/api/services/mux/start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Start Mux
|
||
description: >-
|
||
Spawns `mux server --host 127.0.0.1 --port <port>`. Idempotent if
|
||
already running. **LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service started
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
"409":
|
||
description: Mux is not installed
|
||
"503":
|
||
description: Start failed
|
||
|
||
/api/services/mux/stop:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Stop Mux
|
||
description: >-
|
||
Gracefully stops Mux. Idempotent.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service stopped
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
|
||
/api/services/mux/restart:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Restart Mux
|
||
description: >-
|
||
stop() then start() under the operation lock.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service restarted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
|
||
/api/services/mux/update:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Update Mux to a newer npm version
|
||
description: >-
|
||
Stops, installs newer version, restarts.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
responses:
|
||
"200":
|
||
description: Update succeeded
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/mux/status:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: Get Mux status
|
||
description: >-
|
||
Returns live supervisor state and DB metadata.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Status response
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
|
||
/api/services/mux/auto-start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle Mux auto-start
|
||
description: >-
|
||
When enabled, Mux starts automatically on the next OmniRoute boot.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"200":
|
||
description: Auto-start flag updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
autoStart:
|
||
type: boolean
|
||
"400":
|
||
description: Invalid request body
|
||
|
||
/api/services/mux/auto-restart-adopted:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle Mux auto-restart-when-adopted
|
||
description: >-
|
||
When enabled, an externally-adopted (not OmniRoute-spawned) Mux
|
||
process is restarted under OmniRoute's own supervisor on the next
|
||
health-check cycle instead of being left as adopted-only.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"204":
|
||
description: Flag updated
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/bifrost/install:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Install Bifrost
|
||
description: >-
|
||
Installs the `@maximhq/bifrost` npm package under DATA_DIR/services/bifrost/.
|
||
The package downloads the Go binary on first run. Accepts an optional `version`
|
||
field (semver or `latest`). **LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
responses:
|
||
"200":
|
||
description: Installation result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
installPath:
|
||
type: string
|
||
durationMs:
|
||
type: number
|
||
|
||
/api/services/bifrost/start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Start Bifrost
|
||
description: Starts the supervised Bifrost process. **LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service status after start
|
||
"409":
|
||
description: Bifrost is not installed
|
||
|
||
/api/services/bifrost/stop:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Stop Bifrost
|
||
description: Stops the supervised Bifrost process. **LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service status after stop
|
||
|
||
/api/services/bifrost/restart:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Restart Bifrost
|
||
description: Restarts the supervised Bifrost process. **LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service status after restart
|
||
"409":
|
||
description: Bifrost is not installed
|
||
|
||
/api/services/bifrost/update:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Update Bifrost
|
||
description: >-
|
||
Updates Bifrost to the latest npm version. Stops the running process,
|
||
installs the new version, and restarts if it was previously running.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Update result
|
||
|
||
/api/services/bifrost/status:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: Get Bifrost status
|
||
description: Returns live and DB status for the supervised Bifrost service. **LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Bifrost service status
|
||
|
||
/api/services/bifrost/auto-start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle Bifrost auto-start
|
||
description: >-
|
||
When enabled, Bifrost starts automatically on the next OmniRoute boot.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"204":
|
||
description: Auto-start flag updated
|
||
"400":
|
||
description: Invalid request body
|
||
|
||
/api/services/bifrost/auto-restart-adopted:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle Bifrost auto-restart-when-adopted
|
||
description: >-
|
||
When enabled, an externally-adopted (not OmniRoute-spawned) Bifrost
|
||
process is restarted under OmniRoute's own supervisor on the next
|
||
health-check cycle instead of being left as adopted-only.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"204":
|
||
description: Flag updated
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/dario/install:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Install Dario from npm
|
||
description: >-
|
||
Installs the `@askalf/dario` npm package (Claude-account-pool proxy) under
|
||
DATA_DIR/services/dario/. Uses execFile (no shell interpolation — hard rule
|
||
#13). **LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
version:
|
||
type: string
|
||
default: latest
|
||
description: npm version tag or semver to install
|
||
responses:
|
||
"200":
|
||
description: Install succeeded
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
path:
|
||
type: string
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: npm install failed
|
||
|
||
/api/services/dario/start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Start Dario
|
||
description: >-
|
||
Spawns the Dario process. Idempotent if already running.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service started (or already running)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
"409":
|
||
description: Dario is not installed
|
||
"503":
|
||
description: Start failed
|
||
|
||
/api/services/dario/stop:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Stop Dario
|
||
description: >-
|
||
Gracefully stops Dario. Idempotent — returns a stopped status even if no
|
||
supervisor is currently tracking the process.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service stopped
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
"500":
|
||
description: Stop failed
|
||
|
||
/api/services/dario/restart:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Restart Dario
|
||
description: >-
|
||
Equivalent to stop() then start() under the operation lock.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Service restarted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatus"
|
||
"409":
|
||
description: Dario is not installed
|
||
"503":
|
||
description: Restart failed
|
||
|
||
/api/services/dario/update:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Update Dario to a newer npm version
|
||
description: >-
|
||
Stops the service (if running), installs the newer npm version, then
|
||
restarts it if it was running before the update. **LOCAL_ONLY** — loopback
|
||
only.
|
||
responses:
|
||
"200":
|
||
description: Update result (no-op if already on the latest version)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
updated:
|
||
type: boolean
|
||
installedVersion:
|
||
type: string
|
||
latestVersion:
|
||
type: string
|
||
oldVersion:
|
||
type: string
|
||
nullable: true
|
||
newVersion:
|
||
type: string
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/dario/status:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: Get Dario status
|
||
description: >-
|
||
Returns combined live supervisor state and DB metadata, including the
|
||
auto-start / auto-restart-adopted flags and whether an update is available.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Status response
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ServiceStatusExtended"
|
||
"500":
|
||
description: Status read failed
|
||
|
||
/api/services/dario/auto-start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle Dario auto-start
|
||
description: >-
|
||
When enabled, Dario starts automatically on the next OmniRoute boot.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"204":
|
||
description: Auto-start flag updated
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/dario/auto-restart-adopted:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Toggle Dario auto-restart-when-adopted
|
||
description: >-
|
||
When enabled, an externally-adopted (not OmniRoute-spawned) Dario process
|
||
is restarted under OmniRoute's own supervisor on the next health-check
|
||
cycle instead of being left as adopted-only.
|
||
**LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"204":
|
||
description: Flag updated
|
||
"400":
|
||
description: Invalid request body
|
||
"500":
|
||
description: Update failed
|
||
|
||
/api/services/dario/admin/login-start:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Start a Dario account-pool login (device-code style)
|
||
description: >-
|
||
Forwards to the running Dario instance's `POST /admin/login/start` using
|
||
the stored admin token. The operator opens the returned `authorize_url`,
|
||
approves in their own Claude account, then posts the displayed code to
|
||
`/admin/login-complete`. **LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
alias:
|
||
type: string
|
||
description: Optional account alias; Dario assigns one if omitted.
|
||
responses:
|
||
"200":
|
||
description: Login challenge created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
alias:
|
||
type: string
|
||
authorize_url:
|
||
type: string
|
||
expires_at:
|
||
type: string
|
||
instructions:
|
||
type: string
|
||
"400":
|
||
description: Invalid request body
|
||
"401":
|
||
description: Missing or invalid admin auth
|
||
"502":
|
||
description: Dario did not respond or Dario is not running
|
||
|
||
/api/services/dario/admin/login-complete:
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Complete a Dario account-pool login
|
||
description: >-
|
||
Forwards to the running Dario instance's `POST /admin/login/complete`.
|
||
On success the account becomes routable immediately (Dario hot-reloads
|
||
its pool). **LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [alias, code]
|
||
properties:
|
||
alias:
|
||
type: string
|
||
code:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Account added
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
alias:
|
||
type: string
|
||
status:
|
||
type: string
|
||
expires_at:
|
||
type: string
|
||
"400":
|
||
description: Invalid request body
|
||
"401":
|
||
description: Missing or invalid admin auth
|
||
"502":
|
||
description: Dario did not respond or Dario is not running
|
||
|
||
/api/services/dario/admin/accounts:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: List Dario account-pool accounts
|
||
description: >-
|
||
Forwards to the running Dario instance's `GET /admin/accounts`.
|
||
**LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Account list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
accounts:
|
||
type: array
|
||
items:
|
||
type: object
|
||
count:
|
||
type: integer
|
||
"401":
|
||
description: Missing or invalid admin auth
|
||
"502":
|
||
description: Dario did not respond or Dario is not running
|
||
delete:
|
||
tags: [Embedded Services]
|
||
summary: Remove a Dario account-pool account
|
||
description: >-
|
||
Forwards to the running Dario instance's `DELETE /admin/accounts/<alias>`.
|
||
The alias is taken from a `?alias=` query param or a `{ alias }` JSON body.
|
||
**LOCAL_ONLY** — loopback only.
|
||
parameters:
|
||
- name: alias
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
alias:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Account removed
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
alias:
|
||
type: string
|
||
removed:
|
||
type: boolean
|
||
"400":
|
||
description: Missing alias
|
||
"401":
|
||
description: Missing or invalid admin auth
|
||
"502":
|
||
description: Dario did not respond or Dario is not running
|
||
|
||
/api/services/dario/admin/import-from-omniroute:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: List OmniRoute claude connections eligible for Dario import
|
||
description: >-
|
||
Returns eligible OmniRoute `claude` OAuth provider connections (metadata
|
||
only — id/name/email/org tier, never tokens) so the UI can offer a picker
|
||
when more than one exists. **LOCAL_ONLY** — loopback only.
|
||
responses:
|
||
"200":
|
||
description: Eligible connections
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
connections:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
email:
|
||
type: string
|
||
nullable: true
|
||
organizationType:
|
||
type: string
|
||
nullable: true
|
||
organizationRateLimitTier:
|
||
type: string
|
||
nullable: true
|
||
"401":
|
||
description: Missing or invalid admin auth
|
||
post:
|
||
tags: [Embedded Services]
|
||
summary: Import an OmniRoute claude connection's OAuth tokens into Dario
|
||
description: >-
|
||
Writes the source connection's access/refresh token pair directly into
|
||
Dario's own account-file store (`~/.dario/accounts/<alias>.json`), reusing
|
||
the shared Claude Code OAuth client_id, then restarts the Dario supervisor
|
||
so it picks up the new account. **LOCAL_ONLY** — loopback only.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [connectionId]
|
||
properties:
|
||
connectionId:
|
||
type: string
|
||
alias:
|
||
type: string
|
||
description: Optional custom alias; derived from the source email if omitted.
|
||
responses:
|
||
"200":
|
||
description: Account imported
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
alias:
|
||
type: string
|
||
imported:
|
||
type: boolean
|
||
sourceConnectionId:
|
||
type: string
|
||
sourceEmail:
|
||
type: string
|
||
nullable: true
|
||
"400":
|
||
description: Invalid request body, unsupported connection, or missing tokens
|
||
"401":
|
||
description: Missing or invalid admin auth
|
||
"404":
|
||
description: Connection not found
|
||
"500":
|
||
description: Import failed
|
||
|
||
/api/services/{name}/logs:
|
||
get:
|
||
tags: [Embedded Services]
|
||
summary: Stream service logs via SSE
|
||
description: >-
|
||
Returns a Server-Sent Events stream from the service's in-memory ring buffer
|
||
(5 MB, circular). Sends a `snapshot` event with historical lines first, then
|
||
live `log` events, plus a `heartbeat` every 15 s.
|
||
**LOCAL_ONLY** — loopback only.
|
||
parameters:
|
||
- name: name
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
enum: [9router, cliproxy]
|
||
- name: tail
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 200
|
||
maximum: 1000
|
||
description: Number of historical lines to include in the initial snapshot
|
||
- name: filter
|
||
in: query
|
||
schema:
|
||
type: string
|
||
maxLength: 200
|
||
description: >-
|
||
Case-insensitive substring filter applied to log lines.
|
||
No regex — ReDoS-safe by design.
|
||
responses:
|
||
"200":
|
||
description: SSE log stream
|
||
content:
|
||
text/event-stream:
|
||
schema:
|
||
type: string
|
||
description: >-
|
||
Events: `snapshot` (LogLine[]), `log` (LogLine), `heartbeat` ({})
|
||
"400":
|
||
description: filter parameter exceeds maximum length
|
||
"404":
|
||
description: Service not found
|
||
|
||
# ─── OAuth ─────────────────────────────────────────────────────
|
||
|
||
/api/oauth/{provider}/{action}:
|
||
get:
|
||
tags: [OAuth]
|
||
summary: OAuth flow handler
|
||
description: Handles OAuth authorization and callback for providers
|
||
parameters:
|
||
- name: provider
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
- name: action
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
enum: [authorize, callback, refresh, status]
|
||
responses:
|
||
"200":
|
||
description: OAuth flow response
|
||
"302":
|
||
description: Redirect to provider auth page
|
||
|
||
/api/oauth/cursor/auto-import:
|
||
get:
|
||
tags: [OAuth]
|
||
summary: Auto-import Cursor OAuth credentials
|
||
description: Automatically detects and imports Cursor credentials from local config.
|
||
responses:
|
||
"200":
|
||
description: Import result
|
||
|
||
/api/oauth/cursor/import:
|
||
get:
|
||
tags: [OAuth]
|
||
summary: Get Cursor import status
|
||
responses:
|
||
"200":
|
||
description: Current import status
|
||
post:
|
||
tags: [OAuth]
|
||
summary: Import Cursor OAuth credentials
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Credentials imported
|
||
|
||
/api/oauth/kiro/auto-import:
|
||
get:
|
||
tags: [OAuth]
|
||
summary: Auto-import Kiro OAuth credentials
|
||
description: Automatically detects and imports Kiro credentials from local config.
|
||
responses:
|
||
"200":
|
||
description: Import result
|
||
|
||
/api/oauth/kiro/import:
|
||
get:
|
||
tags: [OAuth]
|
||
summary: Get Kiro import status
|
||
responses:
|
||
"200":
|
||
description: Current import status
|
||
post:
|
||
tags: [OAuth]
|
||
summary: Import Kiro OAuth credentials
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Credentials imported
|
||
|
||
/api/oauth/kiro/social-authorize:
|
||
get:
|
||
tags: [OAuth]
|
||
summary: Initiate Kiro social OAuth authorization
|
||
description: Starts the social OAuth flow for Kiro.
|
||
responses:
|
||
"302":
|
||
description: Redirect to OAuth provider
|
||
|
||
/api/oauth/kiro/social-exchange:
|
||
post:
|
||
tags: [OAuth]
|
||
summary: Exchange Kiro social OAuth token
|
||
description: Exchanges the authorization code for access tokens.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Token exchange result
|
||
|
||
# ─── Cloud ─────────────────────────────────────────────────────
|
||
|
||
/api/cloud/auth:
|
||
post:
|
||
tags: [Cloud]
|
||
summary: Authenticate with cloud worker
|
||
description: Authenticates with the OmniRoute cloud worker for remote access.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Authentication result
|
||
|
||
/api/cloud/credentials/update:
|
||
put:
|
||
tags: [Cloud]
|
||
summary: Update cloud worker credentials
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Credentials updated
|
||
|
||
/api/cloud/model/resolve:
|
||
post:
|
||
tags: [Cloud]
|
||
summary: Resolve model via cloud
|
||
description: Resolves a model request through the cloud worker.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Resolved model info
|
||
|
||
/api/cloud/models/alias:
|
||
get:
|
||
tags: [Cloud]
|
||
summary: Get cloud model aliases
|
||
responses:
|
||
"200":
|
||
description: Cloud model alias list
|
||
put:
|
||
tags: [Cloud]
|
||
summary: Update cloud model alias
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Alias updated
|
||
|
||
# ─── Fallback ──────────────────────────────────────────────────
|
||
|
||
/api/fallback/chains:
|
||
get:
|
||
tags: [Fallback]
|
||
summary: List fallback chains
|
||
description: Returns all registered fallback chains for model routing.
|
||
responses:
|
||
"200":
|
||
description: Fallback chain list
|
||
post:
|
||
tags: [Fallback]
|
||
summary: Create fallback chain
|
||
description: Registers a fallback routing chain for a model.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [model, chain]
|
||
properties:
|
||
model:
|
||
type: string
|
||
chain:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
provider:
|
||
type: string
|
||
priority:
|
||
type: integer
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"200":
|
||
description: Fallback chain created
|
||
delete:
|
||
tags: [Fallback]
|
||
summary: Delete fallback chain
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [model]
|
||
properties:
|
||
model:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Fallback chain deleted
|
||
|
||
# ─── System ────────────────────────────────────────────────────
|
||
|
||
/api/auth/login:
|
||
post:
|
||
tags: [System]
|
||
summary: Authenticate user
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [password]
|
||
properties:
|
||
password:
|
||
type: string
|
||
minLength: 1
|
||
responses:
|
||
"200":
|
||
description: JWT token returned
|
||
"400":
|
||
description: Invalid login request
|
||
"401":
|
||
description: Invalid password
|
||
"403":
|
||
description: Password setup required
|
||
"429":
|
||
description: Too many failed attempts
|
||
|
||
/api/auth/logout:
|
||
post:
|
||
tags: [System]
|
||
summary: Log out
|
||
responses:
|
||
"200":
|
||
description: Session cleared
|
||
|
||
/api/auth/oidc/login:
|
||
get:
|
||
tags: [System]
|
||
summary: Start OIDC login for the dashboard admin gate
|
||
description: |
|
||
Builds an authorization URL from the configured OIDC issuer/client (discovered
|
||
via `{issuer}/.well-known/openid-configuration`, falling back to `{issuer}/authorize`),
|
||
sets a short-lived `oidc_state` cookie, and redirects the browser. Password login
|
||
remains available as a fallback while OIDC is enabled.
|
||
responses:
|
||
"302":
|
||
description: Redirect to the identity provider's authorization endpoint
|
||
"400":
|
||
description: OIDC is not configured (missing issuer, client id/secret, or disabled)
|
||
|
||
/api/auth/oidc/callback:
|
||
get:
|
||
tags: [System]
|
||
summary: Complete OIDC login for the dashboard admin gate
|
||
description: |
|
||
Validates the `state` cookie, exchanges the authorization `code` for tokens,
|
||
verifies the ID token against the issuer's JWKS (audience = client id), and —
|
||
if `oidcAllowedSubjects` is configured — checks the token's `sub`/`email` against
|
||
that allowlist. On success it mints the same 30-day `auth_token` dashboard-session
|
||
JWT used by password login and redirects to `/dashboard`.
|
||
parameters:
|
||
- name: code
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
- name: state
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"302":
|
||
description: >-
|
||
Redirect to `/dashboard` on success, or to
|
||
`/login?oidc_error={missing_code|invalid_state|not_configured|token_exchange|token_response|no_id_token|subject_not_allowed|id_token_invalid|server_misconfigured}`
|
||
on failure.
|
||
|
||
/api/init:
|
||
get:
|
||
tags: [System]
|
||
summary: Initialize application
|
||
responses:
|
||
"200":
|
||
description: Init status
|
||
|
||
/api/restart:
|
||
post:
|
||
tags: [System]
|
||
summary: Restart the application
|
||
responses:
|
||
"200":
|
||
description: Restart initiated
|
||
|
||
/api/shutdown:
|
||
post:
|
||
tags: [System]
|
||
summary: Shutdown the application
|
||
x-always-protected: true
|
||
responses:
|
||
"200":
|
||
description: Shutdown initiated
|
||
|
||
/api/db-backups:
|
||
get:
|
||
tags: [System]
|
||
summary: List database backups
|
||
responses:
|
||
"200":
|
||
description: Backup list
|
||
post:
|
||
tags: [System]
|
||
summary: Create database backup
|
||
responses:
|
||
"200":
|
||
description: Backup created
|
||
patch:
|
||
tags: [System]
|
||
summary: Save database backup retention settings
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
keepLatest:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 200
|
||
retentionDays:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 3650
|
||
responses:
|
||
"200":
|
||
description: Backup retention settings saved
|
||
|
||
/api/storage/health:
|
||
get:
|
||
tags: [System]
|
||
summary: Check storage health
|
||
responses:
|
||
"200":
|
||
description: Storage health status
|
||
|
||
/api/sync/cloud:
|
||
post:
|
||
tags: [System]
|
||
summary: Sync with cloud
|
||
responses:
|
||
"200":
|
||
description: Sync result
|
||
|
||
/api/sync/initialize:
|
||
post:
|
||
tags: [System]
|
||
summary: Initialize cloud sync
|
||
responses:
|
||
"200":
|
||
description: Sync initialized
|
||
|
||
# ─── Background Jobs (local-only administration) ───────────────
|
||
|
||
/api/jobs:
|
||
get:
|
||
tags: [System]
|
||
summary: List registered background jobs
|
||
description: Local-only runtime administration. Returns each registered job and its latest run.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Registered jobs
|
||
"500":
|
||
description: Failed to list jobs
|
||
|
||
/api/jobs/{id}/enable:
|
||
post:
|
||
tags: [System]
|
||
summary: Enable a background job
|
||
description: Local-only runtime administration. Enables the job and restarts its timer.
|
||
x-internal: true
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Job enabled
|
||
"404":
|
||
description: Job not found
|
||
"500":
|
||
description: Failed to enable job
|
||
|
||
/api/jobs/{id}/disable:
|
||
post:
|
||
tags: [System]
|
||
summary: Disable a background job
|
||
description: Local-only runtime administration. Disables the job and stops its timer.
|
||
x-internal: true
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Job disabled
|
||
"404":
|
||
description: Job not found
|
||
"500":
|
||
description: Failed to disable job
|
||
|
||
/api/jobs/{id}/run-now:
|
||
post:
|
||
tags: [System]
|
||
summary: Trigger a background job
|
||
description: >-
|
||
Local-only runtime administration. Starts the job, or waits for an in-flight
|
||
run before queueing the next one, subject to OMNIROUTE_RUNNOW_TIMEOUT_MS.
|
||
x-internal: true
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Job trigger accepted
|
||
"404":
|
||
description: Job not found
|
||
"500":
|
||
description: Failed to trigger job
|
||
|
||
/api/jobs/{id}/runs:
|
||
get:
|
||
tags: [System]
|
||
summary: Read background-job run history
|
||
description: Local-only runtime administration. Returns newest-first run history for one job.
|
||
x-internal: true
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Job run history
|
||
"404":
|
||
description: Job not found
|
||
"500":
|
||
description: Failed to load job runs
|
||
|
||
# ─── Resilience & Monitoring ────────────────────────────────────
|
||
|
||
/api/resilience:
|
||
get:
|
||
tags: [System]
|
||
summary: Get resilience configuration
|
||
responses:
|
||
"200":
|
||
description: Request queue, connection cooldown, provider breaker, and wait settings
|
||
patch:
|
||
tags: [System]
|
||
summary: Update resilience configuration
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Updated resilience configuration
|
||
|
||
/api/resilience/connections:
|
||
get:
|
||
tags: [System]
|
||
summary: Inspect connection resilience state
|
||
description: >-
|
||
Local-only operational view of per-connection cooldowns, provider circuit
|
||
breakers, model lockouts, and recent breaker transitions. Credential columns
|
||
are excluded by an explicit database whitelist.
|
||
x-internal: true
|
||
parameters:
|
||
- name: windowMs
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 86400000
|
||
default: 3600000
|
||
- name: provider
|
||
in: query
|
||
schema:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
responses:
|
||
"200":
|
||
description: Connection, breaker, lockout, window, and degradation metadata
|
||
"400":
|
||
description: Invalid query parameters
|
||
"500":
|
||
description: Failed to collect resilience state
|
||
|
||
/api/telegram/update:
|
||
post:
|
||
tags: [System]
|
||
summary: Receive Telegram updates or Mini App messages
|
||
description: >-
|
||
Public Telegram integration endpoint. Bot updates are acknowledged after
|
||
reply dispatch is queued. Mini App requests must include Telegram-signed
|
||
initData, which is verified with TELEGRAM_BOT_TOKEN before chat proxying.
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
properties:
|
||
initData:
|
||
type: string
|
||
message:
|
||
type: string
|
||
update_id:
|
||
type: integer
|
||
responses:
|
||
"200":
|
||
description: Update acknowledged or Mini App reply returned
|
||
"400":
|
||
description: Invalid JSON, request shape, or missing Mini App message
|
||
"401":
|
||
description: Invalid Mini App initData signature
|
||
"503":
|
||
description: Telegram integration is not configured
|
||
|
||
/api/resilience/reset:
|
||
post:
|
||
tags: [System]
|
||
summary: Reset circuit breakers
|
||
responses:
|
||
"200":
|
||
description: Circuit breakers reset
|
||
|
||
/api/monitoring/health:
|
||
get:
|
||
tags: [System]
|
||
summary: System health check
|
||
description: Returns system health including uptime, memory, circuit breakers, rate limits
|
||
responses:
|
||
"200":
|
||
description: Health status
|
||
|
||
/api/rate-limits:
|
||
get:
|
||
tags: [System]
|
||
summary: Get per-account rate limit status
|
||
responses:
|
||
"200":
|
||
description: Rate limit status by account
|
||
|
||
/api/sessions:
|
||
get:
|
||
tags: [System]
|
||
summary: Get active sessions
|
||
responses:
|
||
"200":
|
||
description: Active session list
|
||
|
||
/api/cache:
|
||
get:
|
||
tags: [System]
|
||
summary: Get cache statistics
|
||
responses:
|
||
"200":
|
||
description: Semantic cache and idempotency stats
|
||
delete:
|
||
tags: [System]
|
||
summary: Clear all caches
|
||
responses:
|
||
"200":
|
||
description: Caches cleared
|
||
|
||
/api/modality-bridge/stats:
|
||
get:
|
||
tags: [System]
|
||
summary: Get Modality Bridge telemetry
|
||
description: In-memory per-modality bridge counters (attempts, successes, bridged, cacheHits, failures, totalLatencyMs, latencySamples, averageLatencyMs, lastUsedAt). The bridged field is the backward-compatible success count. Latency averages include sampled operations only; an unsampled Vision or Audio operation does not fabricate a zero-millisecond sample. Counters reset on process restart.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Per-modality bridge stats (vision, audio, video)
|
||
"401":
|
||
description: Unauthorized
|
||
|
||
/api/modality-bridge/video/runtime:
|
||
get:
|
||
x-loopback-only: true
|
||
tags: [System]
|
||
summary: Get Video Bridge runtime status
|
||
description: Requires trusted loopback locality before authentication or probing, then management authentication. Returns sanitized FFmpeg and ffprobe availability and versions. The response never contains commands, paths, or stderr.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Video Bridge runtime availability
|
||
"401":
|
||
description: Unauthorized
|
||
"403":
|
||
description: Localhost access required
|
||
|
||
/api/modality-bridge/video/extract:
|
||
post:
|
||
x-loopback-only: true
|
||
tags: [System]
|
||
summary: Extract bounded Video Bridge frames through the internal broker
|
||
description: Internal per-process-authenticated trusted-loopback broker. Accepts at most 50 MiB of video bytes; URLs, paths, executable names, and command arguments are not part of the contract. The body pipeline and streamed handler reader both enforce the input cap. The broker applies fixed FFmpeg/ffprobe confinement, a single extraction slot with four pending jobs/100 MiB queued input, a 4 MiB per-frame cap, and a 32 MiB total response cap. Optional focus bounds and scene-aware sampling are deterministic and bounded. Transcript provenance is a metadata contract on the parent video part, not an instruction to run speech-to-text. This is not a public upload API.
|
||
security: []
|
||
parameters:
|
||
- in: query
|
||
name: frames
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 16
|
||
- in: query
|
||
name: samplingPolicy
|
||
required: false
|
||
description: Optional deterministic sampling policy. Scene-aware detection falls back to uniform sampling on detector failure.
|
||
schema:
|
||
type: string
|
||
enum: [uniform, scene_aware, segment_aware]
|
||
default: uniform
|
||
- in: query
|
||
name: start
|
||
required: false
|
||
description: Optional focus-window start in seconds. The broker clamps it to the media duration.
|
||
schema:
|
||
type: number
|
||
minimum: 0
|
||
- in: query
|
||
name: end
|
||
required: false
|
||
description: Optional focus-window end in seconds. It must be greater than the normalized start.
|
||
schema:
|
||
type: number
|
||
minimum: 0
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/octet-stream:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
maxLength: 52428800
|
||
responses:
|
||
"200":
|
||
description: Sanitized duration and bounded JPEG data-URI frames
|
||
"400":
|
||
description: Invalid fixed broker contract
|
||
"403":
|
||
description: Authenticated trusted-loopback broker identity required
|
||
"413":
|
||
description: Input exceeds the 50 MiB byte limit
|
||
"422":
|
||
description: Media rejected or extraction failed
|
||
"499":
|
||
description: Client request aborted
|
||
"503":
|
||
description: Queue capacity is exhausted, or FFmpeg/ffprobe is unavailable on PATH
|
||
headers:
|
||
Retry-After:
|
||
description: Present with value 1 when queue capacity is exhausted
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
"504":
|
||
description: Fixed 120-second broker extraction deadline exceeded
|
||
|
||
/api/modality-bridge/video/drilldown:
|
||
get:
|
||
x-loopback-only: true
|
||
tags: [System]
|
||
summary: Read a bounded Video Bridge drill-down slice
|
||
description: Internal loopback/token-authenticated lookup into a short-lived per-session frame cache. It never downloads media or starts a subprocess; start/end and frame count only select already materialized frames.
|
||
security: []
|
||
parameters:
|
||
- in: query
|
||
name: sessionId
|
||
required: true
|
||
schema: { type: string, maxLength: 128 }
|
||
- in: query
|
||
name: videoRef
|
||
required: true
|
||
schema: { type: string, maxLength: 4096 }
|
||
- in: query
|
||
name: start
|
||
required: false
|
||
schema: { type: number, minimum: 0 }
|
||
- in: query
|
||
name: end
|
||
required: false
|
||
schema: { type: number, minimum: 0 }
|
||
- in: query
|
||
name: frames
|
||
required: false
|
||
schema: { type: integer, minimum: 1, maximum: 16 }
|
||
responses:
|
||
"200": { description: Bounded cached frame slice }
|
||
"403": { description: Trusted loopback/token identity required }
|
||
"404": { description: Drill-down session or media key was not found }
|
||
post:
|
||
x-loopback-only: true
|
||
tags: [System]
|
||
summary: Store a bounded Video Bridge drill-down result
|
||
description: Internal lifecycle operation for explicitly authorized callers. The short-lived session cache is isolated by session and media reference and does not alter the primary request cost.
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [sessionId, videoRef, durationSeconds, frames]
|
||
properties:
|
||
sessionId: { type: string, maxLength: 128 }
|
||
videoRef: { type: string, maxLength: 4096 }
|
||
durationSeconds: { type: number, exclusiveMinimum: 0, maximum: 600 }
|
||
frames:
|
||
type: array
|
||
minItems: 1
|
||
maxItems: 16
|
||
items:
|
||
type: object
|
||
required: [timestampSeconds, dataUri]
|
||
properties:
|
||
timestampSeconds: { type: number, minimum: 0 }
|
||
dataUri: { type: string, pattern: "^data:image/jpeg;base64," }
|
||
responses:
|
||
"201": { description: Drill-down result stored }
|
||
"403": { description: Trusted loopback/token identity required }
|
||
"413": { description: Payload exceeds the bounded session budget }
|
||
delete:
|
||
x-loopback-only: true
|
||
tags: [System]
|
||
summary: Delete a Video Bridge drill-down session
|
||
security: []
|
||
parameters:
|
||
- in: query
|
||
name: sessionId
|
||
required: true
|
||
schema: { type: string, maxLength: 128 }
|
||
responses:
|
||
"200": { description: Session entries removed }
|
||
"403": { description: Trusted loopback/token identity required }
|
||
|
||
/api/cache/stats:
|
||
get:
|
||
tags: [System]
|
||
summary: Get detailed cache statistics
|
||
description: Returns detailed statistics for all cache layers.
|
||
responses:
|
||
"200":
|
||
description: Detailed cache stats
|
||
delete:
|
||
tags: [System]
|
||
summary: Clear cache statistics
|
||
responses:
|
||
"200":
|
||
description: Cache stats cleared
|
||
|
||
# ─── Telemetry & Token Health ───────────────────────────────────
|
||
|
||
/api/telemetry/summary:
|
||
get:
|
||
tags: [Telemetry]
|
||
summary: Get telemetry summary
|
||
description: Returns aggregated telemetry data including request metrics and performance stats.
|
||
responses:
|
||
"200":
|
||
description: Telemetry summary data
|
||
|
||
/api/token-health:
|
||
get:
|
||
tags: [Telemetry]
|
||
summary: Get token health status
|
||
description: Returns health status of OAuth tokens across all providers.
|
||
responses:
|
||
"200":
|
||
description: Token health status
|
||
|
||
# ─── Evals & Policies ──────────────────────────────────────────
|
||
|
||
/api/evals:
|
||
get:
|
||
tags: [System]
|
||
summary: List eval suites
|
||
responses:
|
||
"200":
|
||
description: Eval suite list
|
||
post:
|
||
tags: [System]
|
||
summary: Run evaluation
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Eval results
|
||
|
||
/api/evals/{suiteId}:
|
||
get:
|
||
tags: [System]
|
||
summary: Get eval suite details
|
||
parameters:
|
||
- name: suiteId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Eval suite details
|
||
|
||
/api/policies:
|
||
get:
|
||
tags: [System]
|
||
summary: List routing policies
|
||
responses:
|
||
"200":
|
||
description: Policy list
|
||
post:
|
||
tags: [System]
|
||
summary: Create routing policy
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"201":
|
||
description: Created policy
|
||
delete:
|
||
tags: [System]
|
||
summary: Delete routing policy
|
||
responses:
|
||
"200":
|
||
description: Policy deleted
|
||
|
||
/api/compliance/audit-log:
|
||
get:
|
||
tags: [System]
|
||
summary: Get compliance audit log
|
||
description: >
|
||
Returns paginated audit log entries. Use `level=high` to filter to
|
||
high-level actions only (powers the Activity feed). Use `level=all`
|
||
(default) for full compliance table.
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: level
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [high, all]
|
||
default: all
|
||
description: "high = Activity feed events only; all = all audit events"
|
||
- name: action
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by exact action string (e.g. "provider.added")
|
||
- name: actor
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by actor identifier
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 50
|
||
maximum: 500
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 0
|
||
responses:
|
||
"200":
|
||
description: Audit log entries
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
|
||
# ─── Quota Sharing (Group B, plan 22) ────────────────────────────
|
||
|
||
/api/quota/pools:
|
||
get:
|
||
tags: [Quota]
|
||
summary: List quota pools
|
||
security:
|
||
- bearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: Array of QuotaPool objects
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/QuotaPool"
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
post:
|
||
tags: [Quota]
|
||
summary: Create quota pool
|
||
security:
|
||
- bearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PoolCreate"
|
||
responses:
|
||
"201":
|
||
description: Pool created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/QuotaPool"
|
||
"400":
|
||
description: Validation error (Zod)
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
|
||
/api/quota/pools/{id}:
|
||
get:
|
||
tags: [Quota]
|
||
summary: Get quota pool by ID
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: QuotaPool object
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/QuotaPool"
|
||
"401":
|
||
description: Unauthorized
|
||
"404":
|
||
description: Pool not found
|
||
"500":
|
||
description: Internal server error
|
||
patch:
|
||
tags: [Quota]
|
||
summary: Update quota pool (name or allocations)
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PoolUpdate"
|
||
responses:
|
||
"200":
|
||
description: Updated pool
|
||
"400":
|
||
description: Validation error
|
||
"401":
|
||
description: Unauthorized
|
||
"404":
|
||
description: Pool not found
|
||
"500":
|
||
description: Internal server error
|
||
delete:
|
||
tags: [Quota]
|
||
summary: Delete quota pool
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"204":
|
||
description: Deleted
|
||
"401":
|
||
description: Unauthorized
|
||
"404":
|
||
description: Pool not found
|
||
"500":
|
||
description: Internal server error
|
||
|
||
/api/quota/pools/{id}/usage:
|
||
get:
|
||
tags: [Quota]
|
||
summary: Get pool usage snapshot (per-key consumption + burn rate)
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: PoolUsageSnapshot
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PoolUsageSnapshot"
|
||
"401":
|
||
description: Unauthorized
|
||
"404":
|
||
description: Pool not found
|
||
"500":
|
||
description: Internal server error
|
||
|
||
/api/quota/plans:
|
||
get:
|
||
tags: [Quota]
|
||
summary: List resolved provider plans (catalog + manual overrides)
|
||
security:
|
||
- bearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: Array of ProviderPlan
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
|
||
/api/quota/plans/{connectionId}:
|
||
get:
|
||
tags: [Quota]
|
||
summary: Get resolved plan for a connection
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: connectionId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: ProviderPlan (source = auto | manual)
|
||
"401":
|
||
description: Unauthorized
|
||
"404":
|
||
description: Connection not found
|
||
"500":
|
||
description: Internal server error
|
||
put:
|
||
tags: [Quota]
|
||
summary: Upsert manual plan override for a connection
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: connectionId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PlanUpsert"
|
||
responses:
|
||
"200":
|
||
description: Updated plan
|
||
"400":
|
||
description: Validation error (Zod)
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
delete:
|
||
tags: [Quota]
|
||
summary: Delete manual plan override (reverts to catalog/auto)
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: connectionId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"204":
|
||
description: Override deleted
|
||
"401":
|
||
description: Unauthorized
|
||
"404":
|
||
description: Override not found
|
||
"500":
|
||
description: Internal server error
|
||
|
||
/api/quota/preview:
|
||
get:
|
||
tags: [Quota]
|
||
summary: Dry-run quota enforcement check (preview only, no consumption recorded)
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: apiKeyId
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
- name: poolId
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
- name: estimatedTokens
|
||
in: query
|
||
schema:
|
||
type: number
|
||
- name: estimatedUsd
|
||
in: query
|
||
schema:
|
||
type: number
|
||
- name: estimatedRequests
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
responses:
|
||
"200":
|
||
description: EnforceDecision (allow/block + reason)
|
||
"400":
|
||
description: Validation error (Zod)
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
|
||
/api/settings/quota-store:
|
||
get:
|
||
tags: [Settings]
|
||
summary: Get current quota store driver settings
|
||
description: Redis URL is masked in the response (shows only scheme+host).
|
||
security:
|
||
- bearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: QuotaStoreSettings (driver + masked redisUrl)
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
put:
|
||
tags: [Settings]
|
||
summary: Update quota store driver settings
|
||
security:
|
||
- bearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/QuotaStoreSettings"
|
||
responses:
|
||
"200":
|
||
description: Settings updated
|
||
"400":
|
||
description: Validation error (Zod) — e.g. driver=redis without valid URL
|
||
"401":
|
||
description: Unauthorized
|
||
"500":
|
||
description: Internal server error
|
||
|
||
# ─── v1beta (Gemini-Compatible) ─────────────────────────────────
|
||
|
||
/api/v1beta/models:
|
||
get:
|
||
tags: [Models]
|
||
summary: List models (Gemini format)
|
||
description: Returns models in Gemini v1beta format for native SDK compatibility
|
||
security:
|
||
- BearerAuth: []
|
||
responses:
|
||
"200":
|
||
description: Model list in Gemini format
|
||
|
||
/api/v1beta/models/{path}:
|
||
post:
|
||
tags: [Models]
|
||
summary: Gemini generateContent
|
||
description: Gemini-compatible generateContent endpoint
|
||
security:
|
||
- BearerAuth: []
|
||
parameters:
|
||
- name: path
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: Generated content
|
||
|
||
# ─── AgentBridge ──────────────────────────────────────────────
|
||
|
||
/api/tools/agent-bridge/agents:
|
||
get:
|
||
tags: [AgentBridge]
|
||
summary: List all 9 IDE agents with current state
|
||
description: >-
|
||
Returns the state (dns_enabled, cert_trusted, setup_completed, last_started_at,
|
||
last_error) for all 9 configured IDE agents. LOCAL_ONLY.
|
||
responses:
|
||
"200":
|
||
description: Array of agent state rows
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AgentBridgeAgentState"
|
||
"403":
|
||
description: Loopback-only — request came from a non-loopback address
|
||
|
||
/api/tools/agent-bridge/state:
|
||
get:
|
||
tags: [AgentBridge]
|
||
summary: Get global AgentBridge server state
|
||
description: Returns running status, port, cert info, and intercepted request count.
|
||
responses:
|
||
"200":
|
||
description: Server state
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AgentBridgeServerState"
|
||
|
||
/api/tools/agent-bridge/server:
|
||
post:
|
||
tags: [AgentBridge]
|
||
summary: Control AgentBridge MITM server
|
||
description: Start, stop, restart, trust-cert, or regenerate-cert. SPAWN_CAPABLE.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AgentBridgeServerAction"
|
||
responses:
|
||
"200":
|
||
description: Action executed
|
||
"400":
|
||
description: Invalid action
|
||
"409":
|
||
description: Port 443 conflict
|
||
|
||
/api/tools/agent-bridge/agents/{agentId}/dns:
|
||
post:
|
||
tags: [AgentBridge]
|
||
summary: Enable or disable DNS for one agent
|
||
description: Adds or removes /etc/hosts entries for the agent's host list. SPAWN_CAPABLE.
|
||
parameters:
|
||
- name: agentId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
$ref: "#/components/schemas/AgentId"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AgentBridgeDnsAction"
|
||
responses:
|
||
"200":
|
||
description: DNS updated
|
||
"400":
|
||
description: Validation error
|
||
|
||
/api/tools/agent-bridge/agents/{agentId}/mappings:
|
||
get:
|
||
tags: [AgentBridge]
|
||
summary: Get model mappings for one agent
|
||
parameters:
|
||
- name: agentId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
$ref: "#/components/schemas/AgentId"
|
||
responses:
|
||
"200":
|
||
description: Array of source→target model mappings
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AgentBridgeMappingRow"
|
||
put:
|
||
tags: [AgentBridge]
|
||
summary: Update model mappings for one agent
|
||
parameters:
|
||
- name: agentId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
$ref: "#/components/schemas/AgentId"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AgentBridgeMappingPut"
|
||
responses:
|
||
"200":
|
||
description: Mappings updated
|
||
|
||
/api/tools/agent-bridge/bypass:
|
||
get:
|
||
tags: [AgentBridge]
|
||
summary: List bypass patterns (hosts never decrypted)
|
||
responses:
|
||
"200":
|
||
description: Bypass patterns
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AgentBridgeBypassRow"
|
||
put:
|
||
tags: [AgentBridge]
|
||
summary: Update user bypass patterns
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AgentBridgeBypassUpsert"
|
||
responses:
|
||
"200":
|
||
description: Patterns updated
|
||
|
||
/api/tools/agent-bridge/cert:
|
||
post:
|
||
tags: [AgentBridge]
|
||
summary: Download or regenerate the AgentBridge CA certificate
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [action]
|
||
properties:
|
||
action:
|
||
type: string
|
||
enum: [download, regenerate]
|
||
responses:
|
||
"200":
|
||
description: CA certificate PEM (download) or regeneration confirmation
|
||
|
||
/api/tools/agent-bridge/upstream-ca:
|
||
get:
|
||
tags: [AgentBridge]
|
||
summary: Get configured upstream CA cert path
|
||
responses:
|
||
"200":
|
||
description: Upstream CA configuration
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
path:
|
||
type: string
|
||
nullable: true
|
||
post:
|
||
tags: [AgentBridge]
|
||
summary: Set upstream CA cert path for corporate TLS environments
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AgentBridgeUpstreamCaPost"
|
||
responses:
|
||
"200":
|
||
description: Upstream CA configured
|
||
"400":
|
||
description: Path does not exist or is not readable
|
||
|
||
# ─── Traffic Inspector ─────────────────────────────────────────
|
||
|
||
/api/tools/traffic-inspector/requests:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: List intercepted requests (filterable)
|
||
parameters:
|
||
- name: profile
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [llm, custom, all]
|
||
- name: host
|
||
in: query
|
||
schema:
|
||
type: string
|
||
- name: agent
|
||
in: query
|
||
schema:
|
||
$ref: "#/components/schemas/AgentId"
|
||
- name: status
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: ["2xx", "3xx", "4xx", "5xx", error]
|
||
- name: source
|
||
in: query
|
||
schema:
|
||
$ref: "#/components/schemas/CaptureSource"
|
||
- name: sessionId
|
||
in: query
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Array of intercepted requests
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/InterceptedRequest"
|
||
delete:
|
||
tags: [Traffic Inspector]
|
||
summary: Clear the in-memory traffic buffer
|
||
responses:
|
||
"204":
|
||
description: Buffer cleared
|
||
|
||
/api/tools/traffic-inspector/requests/{id}:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: Get a single intercepted request by ID
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Intercepted request details
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InterceptedRequest"
|
||
"404":
|
||
description: Request not found in buffer
|
||
|
||
/api/tools/traffic-inspector/requests/{id}/replay:
|
||
post:
|
||
tags: [Traffic Inspector]
|
||
summary: Replay a captured request through OmniRoute router
|
||
description: Re-executes the original request body against /v1/chat/completions. Consumes quota.
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Replay response (streaming or JSON)
|
||
"404":
|
||
description: Request not found
|
||
|
||
/api/tools/traffic-inspector/requests/{id}/annotation:
|
||
put:
|
||
tags: [Traffic Inspector]
|
||
summary: Save or update annotation on a request
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorAnnotationPut"
|
||
responses:
|
||
"200":
|
||
description: Annotation saved
|
||
|
||
/api/tools/traffic-inspector/ws:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: Live WebSocket stream of intercepted requests
|
||
description: >-
|
||
Upgrade to WebSocket. On connect, server sends `{type:"snapshot", data:[...]}`.
|
||
Subsequent events: `{type:"new", data:{...}}`, `{type:"update", data:{...}}`,
|
||
`{type:"clear"}`. LOCAL_ONLY.
|
||
responses:
|
||
"101":
|
||
description: WebSocket upgrade successful
|
||
"403":
|
||
description: Non-loopback origin rejected
|
||
|
||
/api/tools/traffic-inspector/export.har:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: Export current filtered request list as HAR 1.2
|
||
parameters:
|
||
- name: profile
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [llm, custom, all]
|
||
- name: sessionId
|
||
in: query
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: HAR file (JSON)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
description: HAR 1.2 format
|
||
|
||
/api/tools/traffic-inspector/hosts:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: List custom capture hosts
|
||
responses:
|
||
"200":
|
||
description: Custom hosts list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/InspectorCustomHost"
|
||
post:
|
||
tags: [Traffic Inspector]
|
||
summary: Add a custom capture host (edits /etc/hosts)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorCustomHostCreate"
|
||
responses:
|
||
"201":
|
||
description: Host added
|
||
"409":
|
||
description: Host already exists
|
||
|
||
/api/tools/traffic-inspector/hosts/{host}:
|
||
delete:
|
||
tags: [Traffic Inspector]
|
||
summary: Remove a custom capture host
|
||
parameters:
|
||
- name: host
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"204":
|
||
description: Host removed
|
||
patch:
|
||
tags: [Traffic Inspector]
|
||
summary: Toggle enabled state of a custom host
|
||
parameters:
|
||
- name: host
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
responses:
|
||
"200":
|
||
description: Host updated
|
||
|
||
/api/tools/traffic-inspector/capture-modes:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: Get state of all 4 capture modes
|
||
responses:
|
||
"200":
|
||
description: Capture modes state
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorCaptureModesState"
|
||
|
||
/api/tools/traffic-inspector/capture-modes/http-proxy:
|
||
post:
|
||
tags: [Traffic Inspector]
|
||
summary: Start or stop the HTTP_PROXY listener (port 8080)
|
||
description: SPAWN_CAPABLE — spawns a net.Server listener.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorCaptureModeAction"
|
||
responses:
|
||
"200":
|
||
description: Action executed
|
||
"409":
|
||
description: Port conflict (EADDRINUSE) when starting
|
||
|
||
/api/tools/traffic-inspector/capture-modes/system-proxy:
|
||
post:
|
||
tags: [Traffic Inspector]
|
||
summary: Apply or revert system-wide proxy settings
|
||
description: SPAWN_CAPABLE — executes networksetup/gsettings/netsh. Requires admin.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorSystemProxyAction"
|
||
responses:
|
||
"200":
|
||
description: System proxy updated
|
||
"500":
|
||
description: OS command failed (permission error)
|
||
|
||
/api/tools/traffic-inspector/capture-modes/tls-intercept:
|
||
post:
|
||
tags: [Traffic Inspector]
|
||
summary: Toggle TLS body decryption in HTTP_PROXY mode
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorTlsInterceptToggle"
|
||
responses:
|
||
"200":
|
||
description: TLS intercept mode updated
|
||
|
||
/api/tools/traffic-inspector/sessions:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: List all saved recording sessions
|
||
responses:
|
||
"200":
|
||
description: Sessions list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/InspectorSession"
|
||
post:
|
||
tags: [Traffic Inspector]
|
||
summary: Start a new recording session
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorSessionStart"
|
||
responses:
|
||
"201":
|
||
description: Session started
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorSession"
|
||
|
||
/api/tools/traffic-inspector/sessions/{id}:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: Get session snapshot (all captured requests)
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Session with embedded requests
|
||
"404":
|
||
description: Session not found
|
||
patch:
|
||
tags: [Traffic Inspector]
|
||
summary: Stop or rename a recording session
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InspectorSessionPatch"
|
||
responses:
|
||
"200":
|
||
description: Session updated
|
||
delete:
|
||
tags: [Traffic Inspector]
|
||
summary: Delete a recording session
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"204":
|
||
description: Session deleted
|
||
|
||
/api/tools/traffic-inspector/sessions/{id}/export.har:
|
||
get:
|
||
tags: [Traffic Inspector]
|
||
summary: Export a recorded session as HAR 1.2
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: HAR file for this session
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
description: HAR 1.2 format
|
||
"404":
|
||
description: Session not found
|
||
|
||
/api/tools/traffic-inspector/internal/ingest:
|
||
post:
|
||
tags: [Traffic Inspector]
|
||
summary: Internal ingest endpoint for server.cjs passthrough path
|
||
description: >-
|
||
Accepts a serialized InterceptedRequest from the CJS MITM server for requests
|
||
that do not go through TypeScript handlers (e.g., passthrough hosts). Requires
|
||
INSPECTOR_INTERNAL_INGEST_TOKEN header. LOCAL_ONLY.
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/InterceptedRequest"
|
||
responses:
|
||
"204":
|
||
description: Ingested
|
||
"401":
|
||
description: Invalid or missing ingest token
|
||
|
||
# ─── OpenAPI Spec ──────────────────────────────────────────────
|
||
|
||
/api/openapi/spec:
|
||
get:
|
||
tags: [System]
|
||
summary: Get OpenAPI specification catalog
|
||
description: >-
|
||
Returns a structured JSON catalog parsed from this `openapi.yaml`,
|
||
including info, servers, tags, schemas, and a flat list of endpoints
|
||
(method, path, tags, summary, security, parameters, responses).
|
||
Used by the in-app API explorer.
|
||
responses:
|
||
"200":
|
||
description: Parsed OpenAPI catalog
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
info:
|
||
type: object
|
||
servers:
|
||
type: array
|
||
items:
|
||
type: object
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: object
|
||
endpoints:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
method:
|
||
type: string
|
||
path:
|
||
type: string
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
summary:
|
||
type: string
|
||
description:
|
||
type: string
|
||
security:
|
||
type: boolean
|
||
parameters:
|
||
type: array
|
||
items:
|
||
type: object
|
||
requestBody:
|
||
type: boolean
|
||
responses:
|
||
type: array
|
||
items:
|
||
type: string
|
||
schemas:
|
||
type: array
|
||
items:
|
||
type: string
|
||
"404":
|
||
description: openapi.yaml file not found on disk
|
||
"500":
|
||
description: Failed to parse OpenAPI spec
|
||
|
||
# ─── Agent Skills Catalog ────────────────────────────────────────────────────
|
||
|
||
/api/agent-skills:
|
||
get:
|
||
tags: [Agent Skills]
|
||
summary: List agent skills catalog
|
||
description: |
|
||
Returns the full 42-entry Agent Skills catalog with optional filtering.
|
||
Skills describe how to use OmniRoute's REST API and CLI — they are structured
|
||
SKILL.md documentation files discoverable by external agents, MCP clients, and
|
||
A2A orchestrators. No authentication required.
|
||
parameters:
|
||
- name: category
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: string
|
||
enum: [api, cli]
|
||
description: Filter by category (api = REST API skills, cli = CLI skills)
|
||
- name: area
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: string
|
||
description: Filter by area slug (e.g. "providers", "models", "cli-serve")
|
||
responses:
|
||
"200":
|
||
description: Catalog list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [skills, count, coverage]
|
||
properties:
|
||
skills:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AgentSkill"
|
||
count:
|
||
type: integer
|
||
coverage:
|
||
$ref: "#/components/schemas/SkillCoverage"
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
|
||
/api/agent-skills/{id}:
|
||
get:
|
||
tags: [Agent Skills]
|
||
summary: Get a single agent skill
|
||
description: |
|
||
Returns metadata for a single agent skill by its canonical ID
|
||
(e.g. `omni-providers`, `cli-serve`). No authentication required.
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
pattern: "^[a-z][a-z0-9-]*$"
|
||
description: Canonical skill ID
|
||
example: omni-providers
|
||
responses:
|
||
"200":
|
||
description: Agent skill metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AgentSkill"
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"404":
|
||
$ref: "#/components/responses/NotFound"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
|
||
/api/agent-skills/{id}/raw:
|
||
get:
|
||
tags: [Agent Skills]
|
||
summary: Get raw SKILL.md content
|
||
description: |
|
||
Returns the SKILL.md content for a skill as `text/markdown`.
|
||
Resolution order: local filesystem `skills/{id}/SKILL.md` → GitHub raw URL (1-hour cache).
|
||
No authentication required.
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
pattern: "^[a-z][a-z0-9-]*$"
|
||
description: Canonical skill ID
|
||
example: omni-providers
|
||
responses:
|
||
"200":
|
||
description: SKILL.md content as Markdown
|
||
headers:
|
||
X-Skill-Source:
|
||
schema:
|
||
type: string
|
||
enum: [filesystem, github, generated]
|
||
description: Where the content was loaded from
|
||
X-Skill-Fetched-At:
|
||
schema:
|
||
type: string
|
||
format: date-time
|
||
description: ISO timestamp of when the content was fetched
|
||
Cache-Control:
|
||
schema:
|
||
type: string
|
||
description: "public, max-age=3600"
|
||
content:
|
||
text/markdown:
|
||
schema:
|
||
type: string
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"404":
|
||
$ref: "#/components/responses/NotFound"
|
||
"502":
|
||
description: Upstream GitHub fetch failed
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ErrorResponse"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
|
||
/api/agent-skills/coverage:
|
||
get:
|
||
tags: [Agent Skills]
|
||
summary: Get SKILL.md coverage stats
|
||
description: |
|
||
Returns how many of the 22 API skills and 20 CLI skills have SKILL.md
|
||
files on the local filesystem vs the catalog totals. No authentication required.
|
||
responses:
|
||
"200":
|
||
description: Coverage stats
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/SkillCoverage"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
|
||
/api/agent-skills/generate:
|
||
post:
|
||
tags: [Agent Skills]
|
||
summary: Trigger SKILL.md generator
|
||
description: |
|
||
Runs the Agent Skills generator which writes `skills/{id}/SKILL.md` for
|
||
all 42 catalog entries (or a subset via `onlyIds`). Preserves
|
||
`<!-- skill:custom-start --> ... <!-- skill:custom-end -->` blocks.
|
||
**Requires management authentication.**
|
||
security:
|
||
- BearerAuth: []
|
||
- ManagementSessionAuth: []
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
dryRun:
|
||
type: boolean
|
||
default: true
|
||
description: "If true, reports what would be generated without writing files"
|
||
prune:
|
||
type: boolean
|
||
default: false
|
||
description: "If true, deletes skill directories not in the catalog"
|
||
onlyIds:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: "If provided, only regenerate these skill IDs"
|
||
responses:
|
||
"200":
|
||
description: Generator report
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [generated, unchanged, pruned, orphansDetected, errors]
|
||
properties:
|
||
generated:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: IDs that got new/updated SKILL.md
|
||
unchanged:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: IDs whose content was already up to date
|
||
pruned:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: IDs whose directories were deleted (prune mode)
|
||
orphansDetected:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Directories found in skills/ not in the catalog
|
||
errors:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [id, error]
|
||
properties:
|
||
id:
|
||
type: string
|
||
error:
|
||
type: string
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
"503":
|
||
description: Generator module not available
|
||
/api/v1/ocr:
|
||
post:
|
||
tags:
|
||
- Images
|
||
summary: Document OCR
|
||
description: >-
|
||
Multi-provider document OCR endpoint (Mistral OCR–compatible request
|
||
and response shape). Accepts a JSON body referencing a document/image
|
||
and returns extracted text. `model` selects the provider via a
|
||
`provider/model` prefix (e.g. `mistral/mistral-ocr-latest`,
|
||
`azure-document-intelligence/prebuilt-read`,
|
||
`vertex-deepseek-ocr/deepseek-ocr-maas`); a bare model id (e.g.
|
||
`mistral-ocr-latest`) resolves to its registered provider, and an
|
||
omitted `model` defaults to Mistral. Azure Document Intelligence is
|
||
asynchronous upstream — the handler polls the returned operation
|
||
until it succeeds or fails before responding, so this endpoint can
|
||
take longer to return for that provider. Success responses carry the
|
||
`X-OmniRoute-*` cost-telemetry headers.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
model:
|
||
type: string
|
||
description: >-
|
||
`provider/model` id or bare model id. Registered ids:
|
||
`mistral/mistral-ocr-latest`,
|
||
`azure-document-intelligence/prebuilt-read`,
|
||
`vertex-deepseek-ocr/deepseek-ocr-maas`. Defaults to
|
||
`mistral-ocr-latest` when omitted.
|
||
document:
|
||
type: object
|
||
responses:
|
||
"200":
|
||
description: OCR result with extracted text.
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
/api/v1/audio/translations:
|
||
post:
|
||
tags:
|
||
- Audio
|
||
summary: Translate audio to English
|
||
description: >-
|
||
OpenAI Whisper–compatible audio translation (multipart/form-data).
|
||
Unlike `/api/v1/audio/transcriptions`, output is always English
|
||
regardless of the source language. Success responses carry the
|
||
`X-OmniRoute-*` cost-telemetry headers.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- file
|
||
properties:
|
||
file:
|
||
type: string
|
||
format: binary
|
||
model:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: English translation of the audio.
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
/api/v1/providers/suggested-models:
|
||
get:
|
||
tags:
|
||
- Providers
|
||
summary: Suggested media models
|
||
description: >-
|
||
Read-only server-side proxy to the public HuggingFace Hub models search
|
||
API, used by the dashboard to suggest models for a media provider kind
|
||
without exposing an HF token client-side. Never accepts or returns
|
||
credentials.
|
||
parameters:
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Media kind to search for (e.g. `image`, `audio`, `video`).
|
||
responses:
|
||
"200":
|
||
description: List of suggested HuggingFace Hub models.
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
/api/v1/provider-plugin-manifest:
|
||
get:
|
||
tags:
|
||
- Providers
|
||
summary: Provider plugin manifest
|
||
description: Returns the manifest describing installed provider plugins.
|
||
responses:
|
||
"200":
|
||
description: Provider plugin manifest.
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
/api/keys/{id}/devices:
|
||
get:
|
||
tags:
|
||
- API Keys
|
||
summary: List devices for an API key
|
||
description: >-
|
||
Lists the distinct devices (masked IP + User-Agent fingerprints)
|
||
tracked for an API key by the in-memory device tracker. IPs are masked
|
||
before storage; the route never sees the raw client IP.
|
||
x-internal: true
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Distinct devices seen for the API key.
|
||
"401":
|
||
$ref: "#/components/responses/ManagementAuthenticationRequired"
|
||
"404":
|
||
$ref: "#/components/responses/NotFound"
|
||
/api/settings/purge-usage-history:
|
||
post:
|
||
tags:
|
||
- Settings
|
||
summary: Purge usage history
|
||
description: Dashboard-only. Purges stored usage-history records.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Usage history purged.
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/oauth/codex/import-token:
|
||
post:
|
||
tags:
|
||
- OAuth
|
||
summary: Import a Codex connection from a bare access token
|
||
description: >-
|
||
Dashboard-only. Creates a Codex (ChatGPT/OpenAI) connection from a raw
|
||
access token with no refresh token (authType `access_token`).
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Connection imported.
|
||
"400":
|
||
$ref: "#/components/responses/BadRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
/api/cli-tools/crush-settings:
|
||
get:
|
||
tags:
|
||
- CLI Tools
|
||
summary: Read Crush CLI OmniRoute config
|
||
description: Local-only. Reads the OmniRoute provider block in Crush's config.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Current Crush config state.
|
||
post:
|
||
tags:
|
||
- CLI Tools
|
||
summary: Write Crush CLI OmniRoute config
|
||
description: Local-only. Registers OmniRoute as an `openai-compat` provider in Crush's config.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Crush config updated.
|
||
delete:
|
||
tags:
|
||
- CLI Tools
|
||
summary: Remove OmniRoute from Crush CLI config
|
||
description: Local-only. Removes the OmniRoute provider block from Crush's config.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Crush config entry removed.
|
||
/api/cli-tools/codewhale-settings:
|
||
get:
|
||
tags:
|
||
- CLI Tools
|
||
summary: Read CodeWhale CLI OmniRoute config
|
||
description: >-
|
||
Local-only. Reads the OmniRoute config block from
|
||
`~/.codewhale/config.toml` (with `~/.deepseek/config.toml` legacy
|
||
fallback).
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Current CodeWhale config state.
|
||
post:
|
||
tags:
|
||
- CLI Tools
|
||
summary: Write CodeWhale CLI OmniRoute config
|
||
description: Local-only. Writes the OmniRoute config block in CodeWhale TOML format.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: CodeWhale config updated.
|
||
delete:
|
||
tags:
|
||
- CLI Tools
|
||
summary: Remove OmniRoute from CodeWhale CLI config
|
||
description: Local-only. Removes the OmniRoute config block from CodeWhale's config.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: CodeWhale config entry removed.
|
||
|
||
components:
|
||
securitySchemes:
|
||
BearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
description: >
|
||
Two bearer families are accepted. Inference API keys (typically `sk-…`)
|
||
authorize `/v1/*`. Management routes also accept `oma_live_…` Access Tokens
|
||
(Settings → Access Tokens / `omniroute connect`) and API keys whose metadata
|
||
includes `manage` or `admin` scope. See docs/guides/MANAGEMENT-AUTH.md.
|
||
Bearer credentials are accepted on management routes that use this scheme;
|
||
they are not rejected solely for being Bearer.
|
||
ManagementSessionAuth:
|
||
type: apiKey
|
||
in: cookie
|
||
name: auth_token
|
||
description: Dashboard management session cookie (auth_token) for protected management routes. Distinct from Bearer Access Tokens and API keys. See docs/guides/MANAGEMENT-AUTH.md.
|
||
|
||
parameters:
|
||
ResourceId:
|
||
name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
|
||
responses:
|
||
Unauthorized:
|
||
description: Missing or invalid API key
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
error:
|
||
type: string
|
||
example: Unauthorized
|
||
ManagementAuthenticationRequired:
|
||
description: Authentication required for management routes
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ApiErrorResponse"
|
||
example:
|
||
error:
|
||
message: Authentication required
|
||
type: invalid_request
|
||
requestId: 3f9f6f5a-509a-4b35-b0a7-2d2d99d73a01
|
||
ManagementInvalidToken:
|
||
description: Bearer tokens are not accepted for management routes
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ApiErrorResponse"
|
||
example:
|
||
error:
|
||
message: Invalid management token
|
||
type: invalid_request
|
||
requestId: 1b6a6ff8-d60c-4900-8d0a-25f81749f0a3
|
||
ValidationError:
|
||
description: Request body failed validation
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ValidationErrorResponse"
|
||
BadRequest:
|
||
description: The request was malformed or failed validation
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ApiErrorResponse"
|
||
example:
|
||
error:
|
||
message: Invalid request
|
||
type: invalid_request_error
|
||
requestId: 8c2b1d44-7a3e-4c91-9b0f-1e2d3c4b5a60
|
||
NotFound:
|
||
description: The requested resource was not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ApiErrorResponse"
|
||
example:
|
||
error:
|
||
message: Resource not found
|
||
type: not_found_error
|
||
requestId: 4d5e6f70-1a2b-3c4d-5e6f-7a8b9c0d1e2f
|
||
InternalError:
|
||
description: An unexpected server error occurred
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ApiErrorResponse"
|
||
example:
|
||
error:
|
||
message: Internal server error
|
||
type: api_error
|
||
requestId: 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d
|
||
|
||
schemas:
|
||
ExclusiveConnectionLeaseLifecycle:
|
||
type: object
|
||
required: [state, generation, acquiredAt, renewedAt, expiresAt]
|
||
properties:
|
||
state: { type: string, enum: [ACTIVE, RELEASED] }
|
||
generation: { type: integer, minimum: 1 }
|
||
acquiredAt: { type: string, format: date-time }
|
||
renewedAt: { type: string, format: date-time }
|
||
expiresAt: { type: string, format: date-time }
|
||
ExclusiveConnectionLeaseCapacity:
|
||
type: object
|
||
required: [state, error, reason, retryAfter, eligibleCount, freeCount]
|
||
properties:
|
||
state: { type: string, const: WAITING_FOR_CAPACITY }
|
||
error:
|
||
type: object
|
||
required: [type, code, message]
|
||
properties:
|
||
type: { type: string, const: lease_error }
|
||
code: { type: string, const: LEASE_CAPACITY_UNAVAILABLE }
|
||
message: { type: string }
|
||
reason: { type: string, const: NO_FREE_ELIGIBLE_CONNECTION }
|
||
retryAfter: { type: integer, minimum: 1, maximum: 3600 }
|
||
eligibleCount: { type: integer, minimum: 0 }
|
||
freeCount: { type: integer, minimum: 0 }
|
||
EmbeddingMultimodalItem:
|
||
oneOf:
|
||
- type: object
|
||
required: [type, text]
|
||
properties:
|
||
type:
|
||
type: string
|
||
const: text
|
||
text:
|
||
type: string
|
||
minLength: 1
|
||
- type: object
|
||
required: [type, source]
|
||
properties:
|
||
type:
|
||
type: string
|
||
enum: [image, audio, video, document]
|
||
source:
|
||
oneOf:
|
||
- type: object
|
||
required: [type, url]
|
||
properties:
|
||
type:
|
||
type: string
|
||
const: url
|
||
url:
|
||
type: string
|
||
format: uri
|
||
description: Public HTTPS URL.
|
||
- type: object
|
||
required: [type, data, media_type]
|
||
properties:
|
||
type:
|
||
type: string
|
||
const: base64
|
||
data:
|
||
type: string
|
||
format: byte
|
||
media_type:
|
||
type: string
|
||
description: Provider-neutral structured embedding input item.
|
||
|
||
PlaygroundPreset:
|
||
type: object
|
||
required:
|
||
- id
|
||
- name
|
||
- endpoint
|
||
- model
|
||
- params
|
||
- created_at
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
name:
|
||
type: string
|
||
maxLength: 100
|
||
endpoint:
|
||
type: string
|
||
description: Playground endpoint key (e.g. "chat.completions")
|
||
model:
|
||
type: string
|
||
system:
|
||
type: string
|
||
nullable: true
|
||
params:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Serialized parameter values (temperature, max_tokens, etc.)
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
PlaygroundPresetCreate:
|
||
type: object
|
||
required:
|
||
- name
|
||
- endpoint
|
||
- model
|
||
properties:
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 100
|
||
endpoint:
|
||
type: string
|
||
minLength: 1
|
||
model:
|
||
type: string
|
||
minLength: 1
|
||
system:
|
||
type: string
|
||
nullable: true
|
||
params:
|
||
type: object
|
||
additionalProperties: true
|
||
default: {}
|
||
MemoryEntry:
|
||
type: object
|
||
description: A single persisted memory entry
|
||
properties:
|
||
id:
|
||
type: string
|
||
description: UUID
|
||
apiKeyId:
|
||
type: string
|
||
sessionId:
|
||
type: string
|
||
nullable: true
|
||
type:
|
||
type: string
|
||
enum:
|
||
- factual
|
||
- episodic
|
||
- procedural
|
||
- semantic
|
||
key:
|
||
type: string
|
||
description: Stable upsert key (e.g. preference:i_prefer_python)
|
||
content:
|
||
type: string
|
||
metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
expiresAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
needsReindex:
|
||
type: integer
|
||
description: 1 if the vector for this memory is stale or missing
|
||
MemorySettingsExtended:
|
||
type: object
|
||
description: Extended memory settings including 7 new fields from plan 21. All fields are optional for PUT (patch semantics).
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
maxTokens:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 16000
|
||
retentionDays:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 365
|
||
strategy:
|
||
type: string
|
||
enum:
|
||
- recent
|
||
- semantic
|
||
- hybrid
|
||
skillsEnabled:
|
||
type: boolean
|
||
embeddingSource:
|
||
type: string
|
||
enum:
|
||
- remote
|
||
- static
|
||
- transformers
|
||
- auto
|
||
description: Which embedding source to use. "auto" = remote > static > transformers.
|
||
embeddingProviderModel:
|
||
type: string
|
||
nullable: true
|
||
description: Embedding provider/model in "provider/model" format (e.g. openai/text-embedding-3-small).
|
||
transformersEnabled:
|
||
type: boolean
|
||
description: Opt-in for Transformers.js local MiniLM model (~400MB RAM)
|
||
staticEnabled:
|
||
type: boolean
|
||
description: Opt-in for static potion-base-8M local model
|
||
rerankEnabled:
|
||
type: boolean
|
||
description: Enable reranking step (+200-500ms/req)
|
||
rerankProviderModel:
|
||
type: string
|
||
nullable: true
|
||
description: Rerank provider/model in "provider/model" format
|
||
vectorStore:
|
||
type: string
|
||
enum:
|
||
- sqlite-vec
|
||
- qdrant
|
||
- auto
|
||
description: Which vector backend to use
|
||
QdrantSettings:
|
||
type: object
|
||
description: Qdrant vector database configuration (read shape — no raw apiKey)
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
host:
|
||
type: string
|
||
port:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 65535
|
||
collection:
|
||
type: string
|
||
embeddingModel:
|
||
type: string
|
||
hasApiKey:
|
||
type: boolean
|
||
apiKeyMasked:
|
||
type: string
|
||
nullable: true
|
||
description: First 4 chars of the configured API key, or null
|
||
QdrantHealthResult:
|
||
type: object
|
||
description: Result of a Qdrant liveness probe
|
||
properties:
|
||
ok:
|
||
type: boolean
|
||
latencyMs:
|
||
type: number
|
||
error:
|
||
type: string
|
||
nullable: true
|
||
description: Sanitized error message (no stack traces)
|
||
AgentSkill:
|
||
type: object
|
||
description: >-
|
||
Single entry in the Agent Skills catalog. Describes one OmniRoute REST API surface
|
||
(category: api) or CLI subcommand group (category: cli) with a canonical ID and a
|
||
link to its SKILL.md documentation file.
|
||
required: [id, name, description, category, area, rawUrl, githubUrl]
|
||
properties:
|
||
id:
|
||
type: string
|
||
pattern: "^[a-z][a-z0-9-]*$"
|
||
description: Canonical skill ID (e.g. "omni-providers", "cli-serve")
|
||
example: omni-providers
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 100
|
||
description: Human-readable skill name
|
||
example: Provider Management
|
||
description:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 2000
|
||
description: One-paragraph description of what the skill covers
|
||
category:
|
||
type: string
|
||
enum: [api, cli]
|
||
description: "api = REST API skill; cli = CLI subcommand skill"
|
||
area:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 50
|
||
description: Functional area slug (e.g. "providers", "combos-routing", "cli-serve")
|
||
example: providers
|
||
endpoints:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: REST API endpoints (present for api-category skills only)
|
||
example: ["POST /api/providers", "GET /api/providers/:id"]
|
||
cliCommands:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: CLI subcommand names (present for cli-category skills only)
|
||
example: ["providers list", "providers test", "providers rotate"]
|
||
icon:
|
||
type: string
|
||
description: Material symbol icon name for dashboard display
|
||
isEntry:
|
||
type: boolean
|
||
description: Whether this is a recommended starting point
|
||
isNew:
|
||
type: boolean
|
||
description: Whether this skill was added in a recent release
|
||
rawUrl:
|
||
type: string
|
||
format: uri
|
||
description: GitHub raw URL of the SKILL.md file
|
||
example: "https://raw.githubusercontent.com/diegosouzapw/OmniRoute/refs/heads/main/skills/omni-providers/SKILL.md"
|
||
githubUrl:
|
||
type: string
|
||
format: uri
|
||
description: GitHub blob URL for viewing the SKILL.md in the browser
|
||
example: "https://github.com/diegosouzapw/OmniRoute/blob/main/skills/omni-providers/SKILL.md"
|
||
|
||
SkillCoverage:
|
||
type: object
|
||
description: >-
|
||
Coverage statistics for the Agent Skills catalog: how many of the 22 REST API
|
||
skills and 20 CLI skills have generated SKILL.md files on the local filesystem.
|
||
required: [api, cli, totalSkills, generatedAt]
|
||
properties:
|
||
api:
|
||
type: object
|
||
required: [have, total]
|
||
properties:
|
||
have:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 22
|
||
description: Number of API skills with SKILL.md on disk
|
||
total:
|
||
type: integer
|
||
enum: [22]
|
||
description: Canonical API skill count (always 22)
|
||
cli:
|
||
type: object
|
||
required: [have, total]
|
||
properties:
|
||
have:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 20
|
||
description: Number of CLI skills with SKILL.md on disk
|
||
total:
|
||
type: integer
|
||
enum: [20]
|
||
description: Canonical CLI skill count (always 20)
|
||
totalSkills:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 42
|
||
description: Sum of api.have + cli.have
|
||
generatedAt:
|
||
type: string
|
||
format: date-time
|
||
description: ISO datetime when coverage was last computed
|
||
|
||
ErrorResponse:
|
||
type: object
|
||
description: Standard error response body
|
||
required: [error]
|
||
properties:
|
||
error:
|
||
type: object
|
||
required: [message]
|
||
properties:
|
||
message:
|
||
type: string
|
||
description: Human-readable error message (never includes stack traces)
|
||
code:
|
||
type: string
|
||
description: Machine-readable error code
|
||
|
||
# ─── AgentBridge Schemas ────────────────────────────────────────
|
||
|
||
AgentId:
|
||
type: string
|
||
enum:
|
||
- antigravity
|
||
- kiro
|
||
- copilot
|
||
- codex
|
||
- cursor
|
||
- zed
|
||
- claude-code
|
||
- open-code
|
||
- trae
|
||
description: One of the 9 supported IDE agents
|
||
|
||
AgentBridgeAgentState:
|
||
type: object
|
||
description: Per-agent MITM state
|
||
properties:
|
||
agent_id:
|
||
$ref: "#/components/schemas/AgentId"
|
||
dns_enabled:
|
||
type: boolean
|
||
cert_trusted:
|
||
type: boolean
|
||
setup_completed:
|
||
type: boolean
|
||
last_started_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
last_error:
|
||
type: string
|
||
nullable: true
|
||
|
||
AgentBridgeServerState:
|
||
type: object
|
||
description: Global AgentBridge MITM server state
|
||
properties:
|
||
running:
|
||
type: boolean
|
||
port:
|
||
type: integer
|
||
example: 443
|
||
certReady:
|
||
type: boolean
|
||
interceptedCount:
|
||
type: integer
|
||
activeConnections:
|
||
type: integer
|
||
lastStartedAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
|
||
AgentBridgeServerAction:
|
||
type: object
|
||
required: [action]
|
||
properties:
|
||
action:
|
||
type: string
|
||
enum: [start, stop, restart, trust-cert, regenerate-cert]
|
||
|
||
AgentBridgeDnsAction:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
|
||
AgentBridgeMappingRow:
|
||
type: object
|
||
properties:
|
||
agent_id:
|
||
$ref: "#/components/schemas/AgentId"
|
||
source_model:
|
||
type: string
|
||
example: gpt-4o
|
||
target_model:
|
||
type: string
|
||
example: claude-sonnet-4.7
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
AgentBridgeMappingPut:
|
||
type: object
|
||
required: [mappings]
|
||
properties:
|
||
mappings:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [source, target]
|
||
properties:
|
||
source:
|
||
type: string
|
||
example: gpt-4o
|
||
target:
|
||
type: string
|
||
example: claude-sonnet-4.7
|
||
|
||
AgentBridgeBypassRow:
|
||
type: object
|
||
properties:
|
||
pattern:
|
||
type: string
|
||
example: "*.bank.*"
|
||
source:
|
||
type: string
|
||
enum: [default, user]
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
AgentBridgeBypassUpsert:
|
||
type: object
|
||
required: [patterns]
|
||
properties:
|
||
patterns:
|
||
type: array
|
||
items:
|
||
type: string
|
||
example: ["*.bank.*", "*.gov.*"]
|
||
|
||
AgentBridgeUpstreamCaPost:
|
||
type: object
|
||
required: [path]
|
||
properties:
|
||
path:
|
||
type: string
|
||
description: Absolute path to a PEM file for corporate upstream CA
|
||
example: "/etc/ssl/certs/corporate-ca.pem"
|
||
|
||
# ─── Traffic Inspector Schemas ──────────────────────────────────
|
||
|
||
CaptureSource:
|
||
type: string
|
||
enum: [agent-bridge, custom-host, http-proxy, system-proxy]
|
||
|
||
DetectedKind:
|
||
type: string
|
||
enum: [llm, app, unknown]
|
||
|
||
InterceptedRequest:
|
||
type: object
|
||
description: A single intercepted HTTP request captured by the Traffic Inspector
|
||
required:
|
||
[
|
||
id,
|
||
source,
|
||
timestamp,
|
||
method,
|
||
host,
|
||
path,
|
||
requestHeaders,
|
||
requestSize,
|
||
responseHeaders,
|
||
responseSize,
|
||
status,
|
||
]
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
source:
|
||
$ref: "#/components/schemas/CaptureSource"
|
||
agent:
|
||
$ref: "#/components/schemas/AgentId"
|
||
timestamp:
|
||
type: string
|
||
format: date-time
|
||
method:
|
||
type: string
|
||
example: POST
|
||
host:
|
||
type: string
|
||
example: api.githubcopilot.com
|
||
path:
|
||
type: string
|
||
example: /v1/chat/completions
|
||
requestHeaders:
|
||
type: object
|
||
additionalProperties:
|
||
type: string
|
||
requestBody:
|
||
type: string
|
||
nullable: true
|
||
description: Masked (secrets replaced with ***)
|
||
requestSize:
|
||
type: integer
|
||
responseHeaders:
|
||
type: object
|
||
additionalProperties:
|
||
type: string
|
||
responseBody:
|
||
type: string
|
||
nullable: true
|
||
responseSize:
|
||
type: integer
|
||
status:
|
||
oneOf:
|
||
- type: integer
|
||
- type: string
|
||
enum: [in-flight, error]
|
||
proxyLatencyMs:
|
||
type: number
|
||
nullable: true
|
||
upstreamLatencyMs:
|
||
type: number
|
||
nullable: true
|
||
totalLatencyMs:
|
||
type: number
|
||
nullable: true
|
||
error:
|
||
type: string
|
||
nullable: true
|
||
description: Sanitized error message (no stack traces)
|
||
sourceModel:
|
||
type: string
|
||
nullable: true
|
||
mappedModel:
|
||
type: string
|
||
nullable: true
|
||
detectedKind:
|
||
$ref: "#/components/schemas/DetectedKind"
|
||
contextKey:
|
||
type: string
|
||
nullable: true
|
||
description: 12-char SHA-256 hex of the system prompt (for conversation grouping)
|
||
example: a3f9c2b1d5e4
|
||
annotation:
|
||
type: string
|
||
nullable: true
|
||
sessionId:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
note:
|
||
type: string
|
||
nullable: true
|
||
description: Informational note (e.g. TLS tunnel metadata)
|
||
|
||
InspectorCustomHost:
|
||
type: object
|
||
properties:
|
||
host:
|
||
type: string
|
||
example: api.openai.com
|
||
enabled:
|
||
type: boolean
|
||
label:
|
||
type: string
|
||
nullable: true
|
||
kind:
|
||
type: string
|
||
enum: [llm, app, custom]
|
||
added_at:
|
||
type: string
|
||
format: date-time
|
||
last_seen_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
|
||
InspectorCustomHostCreate:
|
||
type: object
|
||
required: [host]
|
||
properties:
|
||
host:
|
||
type: string
|
||
minLength: 1
|
||
example: my-internal-llm.company.com
|
||
enabled:
|
||
type: boolean
|
||
default: true
|
||
label:
|
||
type: string
|
||
nullable: true
|
||
kind:
|
||
type: string
|
||
enum: [llm, app, custom]
|
||
default: custom
|
||
|
||
InspectorCaptureModesState:
|
||
type: object
|
||
properties:
|
||
agentBridge:
|
||
type: object
|
||
properties:
|
||
active:
|
||
type: boolean
|
||
customHosts:
|
||
type: object
|
||
properties:
|
||
active:
|
||
type: boolean
|
||
count:
|
||
type: integer
|
||
httpProxy:
|
||
type: object
|
||
properties:
|
||
active:
|
||
type: boolean
|
||
port:
|
||
type: integer
|
||
example: 8080
|
||
systemProxy:
|
||
type: object
|
||
properties:
|
||
active:
|
||
type: boolean
|
||
guardMinutes:
|
||
type: integer
|
||
|
||
InspectorCaptureModeAction:
|
||
type: object
|
||
required: [action]
|
||
properties:
|
||
action:
|
||
type: string
|
||
enum: [start, stop]
|
||
|
||
InspectorSystemProxyAction:
|
||
type: object
|
||
required: [action]
|
||
properties:
|
||
action:
|
||
type: string
|
||
enum: [apply, revert]
|
||
port:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 65535
|
||
example: 8080
|
||
guardMinutes:
|
||
type: integer
|
||
minimum: 1
|
||
example: 30
|
||
|
||
InspectorTlsInterceptToggle:
|
||
type: object
|
||
required: [enabled]
|
||
properties:
|
||
enabled:
|
||
type: boolean
|
||
|
||
InspectorAnnotationPut:
|
||
type: object
|
||
required: [annotation]
|
||
properties:
|
||
annotation:
|
||
type: string
|
||
maxLength: 10000
|
||
|
||
InspectorSession:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
name:
|
||
type: string
|
||
nullable: true
|
||
started_at:
|
||
type: string
|
||
format: date-time
|
||
ended_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
request_count:
|
||
type: integer
|
||
profile:
|
||
type: string
|
||
enum: [llm, custom, all]
|
||
nullable: true
|
||
|
||
InspectorSessionStart:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
example: "Antigravity test run #1"
|
||
|
||
InspectorSessionPatch:
|
||
type: object
|
||
required: [action]
|
||
properties:
|
||
action:
|
||
type: string
|
||
enum: [stop, rename]
|
||
name:
|
||
type: string
|
||
QuotaPool:
|
||
type: object
|
||
description: A quota sharing pool — binds a provider connection to allocation rules.
|
||
required: [id, connectionId, name, createdAt, allocations]
|
||
properties:
|
||
id:
|
||
type: string
|
||
connectionId:
|
||
type: string
|
||
name:
|
||
type: string
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
allocations:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PoolAllocation"
|
||
|
||
PoolAllocation:
|
||
type: object
|
||
required: [apiKeyId, weight, policy]
|
||
properties:
|
||
apiKeyId:
|
||
type: string
|
||
weight:
|
||
type: number
|
||
minimum: 0
|
||
maximum: 100
|
||
description: Share percentage (0–100)
|
||
capValue:
|
||
type: number
|
||
nullable: true
|
||
description: Absolute cap value (optional)
|
||
capUnit:
|
||
type: string
|
||
enum: [percent, requests, tokens, usd]
|
||
nullable: true
|
||
policy:
|
||
type: string
|
||
enum: [hard, soft, burst]
|
||
|
||
PoolCreate:
|
||
type: object
|
||
required: [connectionId, name]
|
||
properties:
|
||
connectionId:
|
||
type: string
|
||
name:
|
||
type: string
|
||
maxLength: 120
|
||
allocations:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PoolAllocation"
|
||
default: []
|
||
|
||
PoolUpdate:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
maxLength: 120
|
||
allocations:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PoolAllocation"
|
||
|
||
PoolUsageSnapshot:
|
||
type: object
|
||
required: [poolId, generatedAt, dimensions]
|
||
properties:
|
||
poolId:
|
||
type: string
|
||
generatedAt:
|
||
type: string
|
||
format: date-time
|
||
dimensions:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
unit:
|
||
type: string
|
||
enum: [percent, requests, tokens, usd]
|
||
window:
|
||
type: string
|
||
enum: ["5h", hourly, daily, weekly, monthly]
|
||
limit:
|
||
type: number
|
||
consumedTotal:
|
||
type: number
|
||
perKey:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
apiKeyId:
|
||
type: string
|
||
consumed:
|
||
type: number
|
||
fairShare:
|
||
type: number
|
||
deficit:
|
||
type: number
|
||
description: "Negative = surplus; positive = over-allocation"
|
||
borrowing:
|
||
type: boolean
|
||
burnRate:
|
||
type: object
|
||
nullable: true
|
||
properties:
|
||
tokensPerSecond:
|
||
type: number
|
||
timeToExhaustionMs:
|
||
type: number
|
||
nullable: true
|
||
|
||
QuotaDimension:
|
||
type: object
|
||
required: [unit, window, limit]
|
||
properties:
|
||
unit:
|
||
type: string
|
||
enum: [percent, requests, tokens, usd]
|
||
window:
|
||
type: string
|
||
enum: ["5h", hourly, daily, weekly, monthly]
|
||
limit:
|
||
type: number
|
||
minimum: 0
|
||
|
||
PlanUpsert:
|
||
type: object
|
||
required: [dimensions]
|
||
properties:
|
||
dimensions:
|
||
type: array
|
||
minItems: 1
|
||
items:
|
||
$ref: "#/components/schemas/QuotaDimension"
|
||
|
||
QuotaStoreSettings:
|
||
type: object
|
||
required: [driver]
|
||
properties:
|
||
driver:
|
||
type: string
|
||
enum: [sqlite, redis]
|
||
redisUrl:
|
||
type: string
|
||
format: uri
|
||
nullable: true
|
||
description: Redis connection URL (write-only; masked in GET responses)
|
||
|
||
ServiceStatus:
|
||
type: object
|
||
description: Live supervisor state for an embedded service
|
||
properties:
|
||
tool:
|
||
type: string
|
||
example: 9router
|
||
state:
|
||
type: string
|
||
enum: [not_installed, stopped, starting, running, stopping, error]
|
||
pid:
|
||
type: integer
|
||
nullable: true
|
||
port:
|
||
type: integer
|
||
example: 20130
|
||
health:
|
||
type: string
|
||
enum: [unknown, healthy, degraded]
|
||
startedAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
lastError:
|
||
type: string
|
||
nullable: true
|
||
|
||
ServiceStatusExtended:
|
||
allOf:
|
||
- $ref: "#/components/schemas/ServiceStatus"
|
||
- type: object
|
||
description: >-
|
||
Extended status including version metadata and (for 9Router) API key preview.
|
||
properties:
|
||
installedVersion:
|
||
type: string
|
||
nullable: true
|
||
latestVersion:
|
||
type: string
|
||
nullable: true
|
||
updateAvailable:
|
||
type: boolean
|
||
apiKeyMasked:
|
||
type: string
|
||
nullable: true
|
||
description: >-
|
||
Masked API key preview (e.g. "nr_****abcd").
|
||
Present only for services that use an injected API key (9Router).
|
||
autoStart:
|
||
type: boolean
|
||
providerExpose:
|
||
type: boolean
|
||
description: >-
|
||
Whether models from this service are exposed as a routing provider.
|
||
9Router only.
|
||
|
||
ApiErrorResponse:
|
||
type: object
|
||
properties:
|
||
error:
|
||
type: object
|
||
properties:
|
||
message:
|
||
type: string
|
||
type:
|
||
type: string
|
||
details:
|
||
description: Optional additional error details
|
||
requestId:
|
||
type: string
|
||
format: uuid
|
||
|
||
ValidationErrorResponse:
|
||
type: object
|
||
properties:
|
||
error:
|
||
type: object
|
||
required: [message, details]
|
||
properties:
|
||
message:
|
||
type: string
|
||
example: Invalid request
|
||
details:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [field, message]
|
||
properties:
|
||
field:
|
||
type: string
|
||
message:
|
||
type: string
|
||
|
||
PayloadRuleModelSpec:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [name]
|
||
properties:
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
protocol:
|
||
type: string
|
||
minLength: 1
|
||
|
||
PayloadMutationRule:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [models, params]
|
||
properties:
|
||
models:
|
||
type: array
|
||
minItems: 1
|
||
items:
|
||
$ref: "#/components/schemas/PayloadRuleModelSpec"
|
||
params:
|
||
type: object
|
||
minProperties: 1
|
||
additionalProperties: true
|
||
|
||
PayloadFilterRule:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [models, params]
|
||
properties:
|
||
models:
|
||
type: array
|
||
minItems: 1
|
||
items:
|
||
$ref: "#/components/schemas/PayloadRuleModelSpec"
|
||
params:
|
||
type: array
|
||
minItems: 1
|
||
items:
|
||
type: string
|
||
minLength: 1
|
||
|
||
PayloadRulesConfig:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [default, override, filter, defaultRaw]
|
||
properties:
|
||
default:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadMutationRule"
|
||
override:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadMutationRule"
|
||
filter:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadFilterRule"
|
||
defaultRaw:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadMutationRule"
|
||
|
||
UpdatePayloadRulesRequest:
|
||
type: object
|
||
additionalProperties: false
|
||
description: At least one payload-rules section must be present in the request body.
|
||
properties:
|
||
default:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadMutationRule"
|
||
override:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadMutationRule"
|
||
filter:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadFilterRule"
|
||
defaultRaw:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadMutationRule"
|
||
default-raw:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/PayloadMutationRule"
|
||
anyOf:
|
||
- required: [default]
|
||
- required: [override]
|
||
- required: [filter]
|
||
- required: [defaultRaw]
|
||
- required: [default-raw]
|
||
|
||
ChatCompletionRequest:
|
||
type: object
|
||
required: [model, messages]
|
||
properties:
|
||
model:
|
||
type: string
|
||
example: gpt-4o
|
||
messages:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [role]
|
||
properties:
|
||
role:
|
||
type: string
|
||
description: >-
|
||
Message role. The proxy accepts any non-empty string; common values
|
||
include system, user, assistant, tool, function, and developer.
|
||
example: user
|
||
content:
|
||
description: >-
|
||
Message content. May be a plain string, an array of content parts
|
||
for multimodal inputs (text, image, audio, etc.), or null when the
|
||
message only carries tool/function calls.
|
||
oneOf:
|
||
- type: string
|
||
- type: array
|
||
items:
|
||
type: object
|
||
- type: "null"
|
||
name:
|
||
type: string
|
||
tool_call_id:
|
||
type: string
|
||
tool_calls:
|
||
type: array
|
||
items:
|
||
type: object
|
||
function_call:
|
||
type: object
|
||
stream:
|
||
type: boolean
|
||
default: false
|
||
temperature:
|
||
type: number
|
||
minimum: 0
|
||
maximum: 2
|
||
max_tokens:
|
||
type: integer
|
||
top_p:
|
||
type: number
|
||
minimum: 0
|
||
maximum: 1
|
||
n:
|
||
type: integer
|
||
minimum: 1
|
||
default: 1
|
||
stop:
|
||
description: Up to 4 stop sequences (string or array of strings).
|
||
oneOf:
|
||
- type: string
|
||
- type: array
|
||
items:
|
||
type: string
|
||
maxItems: 4
|
||
frequency_penalty:
|
||
type: number
|
||
minimum: -2
|
||
maximum: 2
|
||
presence_penalty:
|
||
type: number
|
||
minimum: -2
|
||
maximum: 2
|
||
seed:
|
||
type: integer
|
||
logprobs:
|
||
type: boolean
|
||
top_logprobs:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 20
|
||
response_format:
|
||
type: object
|
||
description: Output format constraint (e.g. JSON mode or JSON Schema).
|
||
properties:
|
||
type:
|
||
type: string
|
||
example: json_object
|
||
tools:
|
||
type: array
|
||
description: Tool definitions available to the model.
|
||
items:
|
||
type: object
|
||
tool_choice:
|
||
description: Controls which tool (if any) is invoked by the model.
|
||
oneOf:
|
||
- type: string
|
||
example: auto
|
||
- type: object
|
||
parallel_tool_calls:
|
||
type: boolean
|
||
default: true
|
||
service_tier:
|
||
type: string
|
||
example: auto
|
||
user:
|
||
type: string
|
||
description: Stable end-user identifier for abuse monitoring.
|
||
|
||
ChatCompletionResponse:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
object:
|
||
type: string
|
||
example: chat.completion
|
||
choices:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
index:
|
||
type: integer
|
||
message:
|
||
type: object
|
||
properties:
|
||
role:
|
||
type: string
|
||
content:
|
||
type: string
|
||
finish_reason:
|
||
type: string
|
||
usage:
|
||
type: object
|
||
properties:
|
||
prompt_tokens:
|
||
type: integer
|
||
completion_tokens:
|
||
type: integer
|
||
total_tokens:
|
||
type: integer
|
||
|
||
MessagesRequest:
|
||
type: object
|
||
required: [model, messages, max_tokens]
|
||
properties:
|
||
model:
|
||
type: string
|
||
example: claude-sonnet-4-5-20250514
|
||
messages:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [role, content]
|
||
properties:
|
||
role:
|
||
type: string
|
||
enum: [user, assistant]
|
||
content:
|
||
type: string
|
||
max_tokens:
|
||
type: integer
|
||
stream:
|
||
type: boolean
|
||
default: false
|
||
system:
|
||
type: string
|
||
|
||
Model:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
object:
|
||
type: string
|
||
example: model
|
||
owned_by:
|
||
type: string
|
||
|
||
ProxySubscription:
|
||
type: object
|
||
description: >-
|
||
An operator-supplied proxy subscription link (Karing-style). `url` is
|
||
redacted (credentials stripped) whenever the record is returned by the API.
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
url:
|
||
type: string
|
||
description: >-
|
||
Redacted subscription URL. May be a local/loopback address
|
||
(e.g. `http://127.0.0.1:8080/list`) — local-first fetch targets
|
||
are allowed by default (`OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS`);
|
||
cloud-metadata / link-local endpoints (169.254.0.0/16) are always
|
||
blocked.
|
||
enabled:
|
||
type: boolean
|
||
mode:
|
||
type: string
|
||
enum: [global, rule]
|
||
ruleProviders:
|
||
type: array
|
||
items:
|
||
type: string
|
||
nullable: true
|
||
localCoreEndpoint:
|
||
type: string
|
||
nullable: true
|
||
updateIntervalMinutes:
|
||
type: integer
|
||
lastFetchedAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
status:
|
||
type: string
|
||
enum: [ok, error, empty]
|
||
error:
|
||
type: string
|
||
nullable: true
|
||
lastNodes:
|
||
type: array
|
||
items: {}
|
||
nullable: true
|
||
lastErrorAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
consecutiveFailures:
|
||
type: integer
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
|
||
ProviderConnection:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
provider:
|
||
type: string
|
||
name:
|
||
type: string
|
||
url:
|
||
type: string
|
||
isActive:
|
||
type: boolean
|
||
maxConcurrent:
|
||
type: integer
|
||
nullable: true
|
||
minimum: 0
|
||
priority:
|
||
type: integer
|
||
testStatus:
|
||
type: string
|
||
enum: [active, error, untested]
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
|
||
ProviderConnectionCreate:
|
||
type: object
|
||
required: [provider, url]
|
||
properties:
|
||
provider:
|
||
type: string
|
||
example: openai
|
||
name:
|
||
type: string
|
||
url:
|
||
type: string
|
||
apiKey:
|
||
type: string
|
||
isActive:
|
||
type: boolean
|
||
default: true
|
||
maxConcurrent:
|
||
type: integer
|
||
nullable: true
|
||
minimum: 0
|
||
|
||
ApiKey:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
label:
|
||
type: string
|
||
keyPreview:
|
||
type: string
|
||
description: Last 4 characters of the key
|
||
isActive:
|
||
type: boolean
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
|
||
ComboCreate:
|
||
type: object
|
||
required: [name, models]
|
||
properties:
|
||
name:
|
||
type: string
|
||
models:
|
||
type: array
|
||
minItems: 1
|
||
items:
|
||
oneOf:
|
||
- type: string
|
||
description: "provider/model reference"
|
||
- type: object
|
||
description: "structured combo step (provider, model, weight, ...)"
|
||
additionalProperties: true
|
||
strategy:
|
||
type: string
|
||
enum:
|
||
- priority
|
||
- weighted
|
||
- round-robin
|
||
- context-relay
|
||
- fill-first
|
||
- p2c
|
||
- random
|
||
- least-used
|
||
- cost-optimized
|
||
- reset-aware
|
||
- reset-window
|
||
- headroom
|
||
- strict-random
|
||
- auto
|
||
- lkgp
|
||
- context-optimized
|
||
- fusion
|
||
default: priority
|