mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 02:02:13 +03:00
* refactor(cursor): extracts token extraction into shared lib
Moves tryIdeAuth/tryAgentAuth and supporting helpers out of the
auto-import route into src/lib/cursor/tokenExtractor.ts, and adds
an agent-cli-state.json fallback candidate path to tryAgentAuth
(alongside the existing auth.json candidate) so the extraction
logic can be reused by the upcoming renewal orchestrator.
* feat(cursor): adds cursor-agent-backed token renewal orchestrator
Builds the renewal orchestrator in src/lib/cursor/renewal.ts: a
bounded, unattended-safe --list-models nudge, a side-effect-free
status availability check, an in-flight spawn lock keyed by
command, and renewCursorConnection() which nudges cursor-agent
then independently re-scrapes the IDE and cursor-agent credential
sources to detect whichever refreshed. Extends cursorAgent.ts's
binary resolution and spawn helper with fixed-paths-only mode and
a SIGKILL follow-up for background use. Adds a generic keyed-mutex
utility (src/shared/utils/keyedMutex.ts) for serializing a
connection's renew-then-persist cycle, and forwards a busy-timeout
through driverFactory's node:sqlite fallback path.
* feat(cursor): proactively renews Cursor sessions in the sweep
Adds src/lib/tokenHealthCheckCursor.ts, sweep-side glue that calls
the renewal orchestrator and persists the result, wired into
tokenHealthCheck.ts's checkConnection() via a new Cursor-specific
branch placed ahead of the generic no-refresh-token fallthrough.
Carves out a non-terminal exception for a Cursor connection that
already landed at testStatus "expired" via the request-time 401
path, excluding permanently-dead account_deactivated connections.
Extends buildRefreshFailureUpdate() with an overrides param so
Cursor's failure path can use a distinct, non-terminal errorCode
instead of the generic refresh_failed/expired taxonomy.
* feat(cursor): adds local-only manual refresh route
Adds POST /api/providers/[id]/refresh-cursor, a dedicated
loopback-only route that calls the renewal orchestrator on demand
for a single Cursor connection, bounded by a 30s per-connection
cooldown. Classifies the new route in LOCAL_ONLY_API_PATTERNS and
closes the manage-scope-bypass gap for dynamic-segment spawn-capable
routes under /api/providers/ via a new SPAWN_CAPABLE_PATTERNS /
SPAWN_CAPABLE_PATTERN_ANCESTORS mechanism, which also retroactively
covers the pre-existing /login route. The existing shared
/api/providers/[id]/refresh route is untouched and stays
remote-reachable for every other provider.
* feat(cursor): surfaces a dismissible cursor-agent nudge
Adds GET /api/providers/cursor/agent-availability, a credential-free
LOCAL_ONLY route returning only { cursorAgentAvailable: boolean },
backed by a 5-minute cached wrapper around the renewal orchestrator's
existing availability check. Surfaces a dismissible dashboard banner
on the Cursor provider page suggesting cursor-agent installation
when it isn't detected, following the existing dismissible-banner
convention. Also fixes a pre-existing bracket character in a
routeGuard.ts comment that was silently truncating
check-openapi-security-tiers.mjs's view of LOCAL_ONLY_API_PREFIXES.
* fix(cursor): wires manual refresh button to the new route
Branches handleRefreshToken to call the dedicated Cursor refresh
route instead of the generic /refresh route, which silently 502s
for Cursor connections today since they carry no refresh token.
Every other provider's refresh behavior is unaffected. Adds the
cursorSessionUnchanged i18n key and syncs it (plus a pre-existing,
unrelated 28-key backlog) across all 42 locale files.
* fix(cursor): addresses Phase 4/4.5 review findings
Restores the legacy stdout/stderr auth-pattern fallback in
checkCursorAgentAvailability() that the plan's Task 2 Step 4
required but the implementation had dropped. Threads an optional
deps parameter through checkCursorConnectionIfNeeded() so its
error branch is reachable in tests, and switches both it and the
manual-refresh route to exhaustive switch statements over the
renewal result. Adds a short-lived host-keyed dedup cache around
tryIdeAuth() so multiple due Cursor connections sharing a host
don't each open the same state.vscdb file in one sweep tick.
Adds opportunistic eviction to the manual-refresh cooldown map,
an outer try/catch to the availability route for defense-in-depth
consistency with the plan's other routes, and corrects a stale
JSDoc claim about the /login route's auth check. Documents the
now-empirically-confirmed agent-cli-state.json schema mismatch
found while validating against a real cursor-agent install.
* docs(cursor): adds changelog fragments for the renewal plan
Adds one fragment per user-facing outcome per changelog.d/README.md's
convention for a PR that both fixes and adds. PR number placeholder
to be filled in once the PR is opened.
* fix(i18n): translates the new Cursor keys into Vietnamese
The i18n:sync-ui run in an earlier commit left __MISSING__
sentinels for the 4 new Cursor keys in every locale, but
Vietnamese has a dedicated completeness test requiring zero
internal missing markers. Provides real translations for
cursorSessionUnchanged, cursorAgentNudgeTitle,
cursorAgentNudgeBody, and cursorAgentNudgeDismiss.
* fix(cursor): addresses quality-gate Layer 1.5 findings
Restores a comment that misrepresented execFile's actual argv shape
after an earlier bracket-removal fix, this time avoiding literal
closing-bracket characters entirely so the openapi checker's naive
array parser can't be broken by either version. Bounds the sweep-
and manual-route-triggered tryIdeAuth() busy-timeout to 250ms
(down from the interactive auto-import path's 2000ms), since both
share the main event loop with all other in-flight requests and
should fail fast on a WAL-lock collision rather than block the
whole instance for up to ~4s. Has the manual refresh route bypass
the sweep's IDE-auth dedup cache so a click always sees a fresh
read, consistent with this plan's existing "manual actions never
see stale cached data" convention. Documents the previously-missing
agent-availability route in ROUTE_GUARD_TIERS.md's spawn-capable
table.
* fix(cursor): adds SIGKILL follow-up to the status-check spawn
Matches the nudge spawn's existing SIGTERM+SIGKILL pattern so an
unresponsive cursor-agent status check can't leak a lingering
process if it ignores SIGTERM.
* docs(cursor): fills in the PR number for changelog fragments
Renames the 3 changelog.d fragments to their PR-numbered filenames and replaces the (#PR) placeholder with #9173, now that the PR exists.
* fix(cursor): corrects changelog fragments to reference PR #9173
The prior commit only staged the git mv rename — a git add invocation with a stale (pre-rename) pathspec aborted before the actual (#PR) -> (#9173) content edit was staged, so the rename landed without the fix it was meant to carry. This captures the actual content change.
* docs(cursor): regenerates the agent-skills catalog for the new route
check:agent-skills-sync (CI's Merge integrity gate) requires SKILL.md files to stay in sync with the live route catalog. Adding /api/providers/cursor/agent-availability in an earlier commit needed a regen this branch never ran.
* chore(quality): rebaselines file-size caps grown by agentrouter merges
Two already-merged agentrouter commits (564c204ef, ec150a006) on release/v3.8.50 grew open-sse/executors/base.ts, open-sse/handlers/chatCore.ts, and tests/unit/chatcore-translation-paths.test.ts past their frozen caps before this PR branched — unrelated to the Cursor renewal changes here. No PR branch is left to fix the growth in-place, so the caps are bumped to the current real sizes, following the existing release-green rebaseline precedent in this file.
* fix(sse): imports getModel helpers from db/models, not localDb
A recently-merged agentrouter commit added a @/lib/localDb import in chatCore.ts, violating the no-restricted-imports rule (Hard Rule #2 — never barrel-import from localDb.ts). Points the import at the owning module, src/lib/db/models.ts, where both functions are actually defined, and prunes the now-stale suppression entry.
* fix(sse): scopes CC-relay anthropic-beta to its own requestDefaults
Two already-merged agentrouter commits widened usesClaudeCodeProtocol()'s native-Claude system-transform block (billing header + selectBetaFlags-derived anthropic-beta) to also run for generic CC-compatible relay connections, not just real claude traffic and agentrouter's own wire-image mimicry. selectBetaFlags() has no visibility into a relay's own providerSpecificData.requestDefaults, so its header replacement silently wiped out an earlier context-1m append and force-included redact-thinking regardless of the relay's own opt-in. Restores both for plain CC-compatible relays only; real claude/agentrouter traffic is unaffected.
Also bumps four stale hardcoded Codex/Claude Code CLI version-string test assertions (0.144.1->0.146.0, 2.1.219->2.1.220) that drifted when the same two commits bumped the version constants without updating their tests, and rebaselines base.ts's frozen file-size cap for this fix's own +35 lines.
* fix(sse): preserves bare CC-relay native treatment and context-1m
The previous commit's fix was too broad in one direction: excluding ALL CC-compatible relays from the native-Claude header block broke two pre-existing tests (cc-compatible-provider.test.ts, v3.6.6) that rely on that treatment for a 'vanilla' relay with no providerSpecificData.requestDefaults configured.
Refines the gate to this whole native-Claude header-replacement block: replace headers for real claude traffic, agentrouter's wire-image mimicry, OR a CC-relay with no requestDefaults at all — only a relay with EXPLICIT requestDefaults (context1m/redactThinking/summarizeThinking) gets to keep buildHeaders()'s own correctly-computed header set. A redact-thinking-beta strip (unconditional, a no-op when native treatment didn't apply) covers the one remaining gap: selectBetaFlags() force-includes it for a bare relay's opaque client, which a bare relay never explicitly opted into.
Verified against all three previously-conflicting pre-existing tests simultaneously: executor-default-base.test.ts's '1M beta' test, both cc-compatible-provider.test.ts SSE-forcing tests, and provider-request-failure-pipeline.test.ts's 'keeps request beta headers' test (the last of which was already broken by the raw agentrouter merge, confirmed via direct comparison against that exact commit).
* fix(sse): fills in remaining stale CLI version literals
The same two agentrouter commits bumped Codex/Claude Code CLI version constants (0.144.1->0.146.0, 2.1.219->2.1.220) without updating every hardcoded test assertion. This round covers the ones the previous version-string commit missed: the anthropic-cache-fingerprint billing-version constant, a cc-bridge-transforms body assertion, the UI-mirror parity test's own snapshot plus its RoutingTab.tsx source of truth, an integration test's User-Agent assertion (inconsistent with its own dynamic Version assertion two lines up), and the translate-path golden snapshot. Also updates a stale doc comment referencing the old literal by value instead of by constant name.
* fix(cursor): imports from db/ modules, not the localDb barrel
Both files violated Hard Rule #2 (never barrel-import from localDb.ts) — a genuine lint error that had gone uncaught locally. refresh-cursor/route.ts imported getCachedProviderConnectionById from @/lib/localDb instead of its owning module, @/lib/db/readCache. tokenHealthCheckCursor.ts copied the same pattern from its sibling tokenHealthCheckCopilot.ts (an existing, already-suppressed violation) for updateProviderConnection; imports it from @/lib/db/providers instead, with no circular-import fallout (verified via the existing token-health-check-cursor and refresh-cursor-route test suites).
* fix(db): removes stale raw-SQL allowlist entry for cursor route
The cursor auto-import route no longer contains raw SQL — that query
now lives in src/lib/cursor/tokenExtractor.ts, outside the
route/handler scope check-db-rules scans. The allowlist entry was
stale, tripping the stale-enforcement gate.
* fix(test): registers cursor test files in stryker tap.testFiles
Three unit test files covering mutation-tested modules
(route-guard-cursor-agent-availability, route-guard-cursor-refresh,
cursor-renewal) were missing from stryker.conf.json's tap.testFiles,
tripping the mutation-test-coverage gate's drift detection.
* chore(ci): retriggers checks (stuck GH Actions runner on shard 2/4)
* fix(sse): restores CC-relay context1m/redact-thinking test coverage
Rebasing onto release/v3.8.50's new tip (35405be60, an unrelated
agentrouter protocol-inference commit) silently flipped two assertions
this branch's own earlier fix (687fbda62) depends on, in the same test
files that commit touched for other reasons:
- executor-default-base.test.ts: calls[0] (a bare CC-relay with no
requestDefaults) expected redact-thinking-beta absent; flipped to
present. calls[1] (context1m+redactThinking requestDefaults) expected
the context-1m beta preserved; flipped to absent.
- provider-request-failure-pipeline.test.ts: expected Accept:
text/event-stream and the context-1m beta present for a relay with
explicit requestDefaults; flipped to application/json and absent.
35405be60 did not touch open-sse/executors/base.ts at all, so these
were test-only edits made without visibility into the still-unmerged
CC-relay header-preservation fix on this branch — they quietly matched
the assertions back to the pre-fix (buggy) behavior instead. Restores
the original, validated expectations; all three interdependent test
files (executor-default-base, cc-compatible-provider,
provider-request-failure-pipeline) verified passing together again.
* ci: re-trigger checks after GitHub Actions incident (2026-08-07, resolved)
* ci: re-trigger checks (previous push event was dropped)
* fix(quality): restore dropped vi.json cursor-renewal keys + rebaseline test growth
vi.json was missing 4 keys (cursorSessionUnchanged, cursorAgentNudgeTitle/Body/Dismiss) that this PR's own pre-merge branch had translated -- the original merge's 'git checkout --theirs' resolution for the 7 conflicted locale files discarded them since upstream's vi.json has no cursor-token-renewal feature. Restored from pre-merge tip a38003e30. Also rebaselines combo-routing-engine.test.ts (3457->3464) for the comment growth from the ALL_ACCOUNTS_INACTIVE fix, caught by CI's PR-mode check:file-size.
* chore(tests): drop explanatory comments on ALL_TARGETS_SKIPPED assertions
Kept the assertion value fix (ALL_ACCOUNTS_INACTIVE -> ALL_TARGETS_SKIPPED); the comments were unnecessary. Reverts the file-size baseline bump these comments caused (combo-routing-engine.test.ts back to its original 3457).
8569 lines
246 KiB
YAML
8569 lines
246 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: 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:
|
||
# --- 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/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}:
|
||
patch:
|
||
tags: [Combos]
|
||
summary: Update combo
|
||
parameters:
|
||
- $ref: "#/components/parameters/ResourceId"
|
||
responses:
|
||
"200":
|
||
description: Updated combo
|
||
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 (bridged, cacheHits, failures, lastUsedAt). Counters reset on process restart.
|
||
security:
|
||
- ManagementSessionAuth: []
|
||
responses:
|
||
"200":
|
||
description: Per-modality bridge stats (vision, audio)
|
||
"401":
|
||
description: Unauthorized
|
||
|
||
/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: >-
|
||
Mistral OCR–compatible document OCR endpoint. Accepts a JSON body
|
||
referencing a document/image and returns extracted text. Success
|
||
responses carry the `X-OmniRoute-*` cost-telemetry headers.
|
||
security:
|
||
- BearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
model:
|
||
type: string
|
||
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: API key obtained from the OmniRoute dashboard
|
||
ManagementSessionAuth:
|
||
type: apiKey
|
||
in: cookie
|
||
name: auth_token
|
||
description: Dashboard management session cookie for protected management routes
|
||
|
||
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:
|
||
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.
|
||
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, model]
|
||
properties:
|
||
name:
|
||
type: string
|
||
model:
|
||
type: string
|
||
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
|
||
nodes:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
connectionId:
|
||
type: string
|
||
weight:
|
||
type: integer
|
||
priority:
|
||
type: integer
|