# API Reference (Deutsch) 🌐 **Languages:** 🇺🇸 [English](../../../../reference/API_REFERENCE.md) · 🇪🇹 [am](../../../am/docs/reference/API_REFERENCE.md) · 🇸🇦 [ar](../../../ar/docs/reference/API_REFERENCE.md) · 🇦🇿 [az](../../../az/docs/reference/API_REFERENCE.md) · 🇧🇬 [bg](../../../bg/docs/reference/API_REFERENCE.md) · 🇧🇩 [bn](../../../bn/docs/reference/API_REFERENCE.md) · 🇨🇿 [cs](../../../cs/docs/reference/API_REFERENCE.md) · 🇩🇰 [da](../../../da/docs/reference/API_REFERENCE.md) · 🇬🇷 [el](../../../el/docs/reference/API_REFERENCE.md) · 🇪🇸 [es](../../../es/docs/reference/API_REFERENCE.md) · 🇪🇪 [et](../../../et/docs/reference/API_REFERENCE.md) · 🇮🇷 [fa](../../../fa/docs/reference/API_REFERENCE.md) · 🇫🇮 [fi](../../../fi/docs/reference/API_REFERENCE.md) · 🇫🇷 [fr](../../../fr/docs/reference/API_REFERENCE.md) · 🇮🇪 [ga](../../../ga/docs/reference/API_REFERENCE.md) · 🇮🇳 [gu](../../../gu/docs/reference/API_REFERENCE.md) · 🇳🇬 [ha](../../../ha/docs/reference/API_REFERENCE.md) · 🇮🇱 [he](../../../he/docs/reference/API_REFERENCE.md) · 🇮🇳 [hi](../../../hi/docs/reference/API_REFERENCE.md) · 🇭🇷 [hr](../../../hr/docs/reference/API_REFERENCE.md) · 🇭🇺 [hu](../../../hu/docs/reference/API_REFERENCE.md) · 🇦🇲 [hy](../../../hy/docs/reference/API_REFERENCE.md) · 🇮🇩 [id](../../../id/docs/reference/API_REFERENCE.md) · 🇳🇬 [ig](../../../ig/docs/reference/API_REFERENCE.md) · 🇮🇹 [it](../../../it/docs/reference/API_REFERENCE.md) · 🇯🇵 [ja](../../../ja/docs/reference/API_REFERENCE.md) · 🇬🇪 [ka](../../../ka/docs/reference/API_REFERENCE.md) · 🇰🇭 [km](../../../km/docs/reference/API_REFERENCE.md) · 🇮🇳 [kn](../../../kn/docs/reference/API_REFERENCE.md) · 🇰🇷 [ko](../../../ko/docs/reference/API_REFERENCE.md) · 🇱🇹 [lt](../../../lt/docs/reference/API_REFERENCE.md) · 🇱🇻 [lv](../../../lv/docs/reference/API_REFERENCE.md) · 🇮🇳 [ml](../../../ml/docs/reference/API_REFERENCE.md) · 🇮🇳 [mr](../../../mr/docs/reference/API_REFERENCE.md) · 🇲🇾 [ms](../../../ms/docs/reference/API_REFERENCE.md) · 🇲🇹 [mt](../../../mt/docs/reference/API_REFERENCE.md) · 🇲🇲 [my](../../../my/docs/reference/API_REFERENCE.md) · 🇳🇵 [ne](../../../ne/docs/reference/API_REFERENCE.md) · 🇳🇱 [nl](../../../nl/docs/reference/API_REFERENCE.md) · 🇳🇴 [no](../../../no/docs/reference/API_REFERENCE.md) · 🇮🇳 [or](../../../or/docs/reference/API_REFERENCE.md) · 🇮🇳 [pa](../../../pa/docs/reference/API_REFERENCE.md) · 🇵🇭 [phi](../../../phi/docs/reference/API_REFERENCE.md) · 🇵🇱 [pl](../../../pl/docs/reference/API_REFERENCE.md) · 🇵🇹 [pt](../../../pt/docs/reference/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/reference/API_REFERENCE.md) · 🇷🇴 [ro](../../../ro/docs/reference/API_REFERENCE.md) · 🇷🇺 [ru](../../../ru/docs/reference/API_REFERENCE.md) · 🇱🇰 [si](../../../si/docs/reference/API_REFERENCE.md) · 🇸🇰 [sk](../../../sk/docs/reference/API_REFERENCE.md) · 🇸🇮 [sl](../../../sl/docs/reference/API_REFERENCE.md) · 🇷🇸 [sr](../../../sr/docs/reference/API_REFERENCE.md) · 🇸🇪 [sv](../../../sv/docs/reference/API_REFERENCE.md) · 🇰🇪 [sw](../../../sw/docs/reference/API_REFERENCE.md) · 🇮🇳 [ta](../../../ta/docs/reference/API_REFERENCE.md) · 🇮🇳 [te](../../../te/docs/reference/API_REFERENCE.md) · 🇹🇭 [th](../../../th/docs/reference/API_REFERENCE.md) · 🇹🇷 [tr](../../../tr/docs/reference/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/reference/API_REFERENCE.md) · 🇵🇰 [ur](../../../ur/docs/reference/API_REFERENCE.md) · 🇺🇿 [uz](../../../uz/docs/reference/API_REFERENCE.md) · 🇻🇳 [vi](../../../vi/docs/reference/API_REFERENCE.md) · 🇳🇬 [yo](../../../yo/docs/reference/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/reference/API_REFERENCE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/reference/API_REFERENCE.md) --- 🌐 **Sprachen:** 🇺🇸 [English](./API_REFERENCE.md) | 🇪🇹 [አማርኛ](../i18n/am/docs/reference/API_REFERENCE.md) | 🇸🇦 [العربية](../i18n/ar/docs/reference/API_REFERENCE.md) | 🇦🇿 [Azərbaycan dili](../i18n/az/docs/reference/API_REFERENCE.md) | 🇧🇬 [Български](../i18n/bg/docs/reference/API_REFERENCE.md) | 🇧🇩 [বাংলা](../i18n/bn/docs/reference/API_REFERENCE.md) | 🇨🇿 [Čeština](../i18n/cs/docs/reference/API_REFERENCE.md) | 🇩🇰 [Dansk](../i18n/da/docs/reference/API_REFERENCE.md) | 🇩🇪 [Deutsch](../i18n/de/docs/reference/API_REFERENCE.md) | 🇬🇷 [Ελληνικά](../i18n/el/docs/reference/API_REFERENCE.md) | 🇪🇸 [Español](../i18n/es/docs/reference/API_REFERENCE.md) | 🇪🇪 [Eesti](../i18n/et/docs/reference/API_REFERENCE.md) | 🇮🇷 [فارسی](../i18n/fa/docs/reference/API_REFERENCE.md) | 🇫🇮 [Suomi](../i18n/fi/docs/reference/API_REFERENCE.md) | 🇫🇷 [Français](../i18n/fr/docs/reference/API_REFERENCE.md) | 🇮🇪 [Gaeilge](../i18n/ga/docs/reference/API_REFERENCE.md) | 🇮🇳 [ગુજરાતી](../i18n/gu/docs/reference/API_REFERENCE.md) | 🇳🇬 [Hausa](../i18n/ha/docs/reference/API_REFERENCE.md) | 🇮🇱 [עברית](../i18n/he/docs/reference/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../i18n/hi/docs/reference/API_REFERENCE.md) | 🇭🇷 [Hrvatski](../i18n/hr/docs/reference/API_REFERENCE.md) | 🇭🇺 [Magyar](../i18n/hu/docs/reference/API_REFERENCE.md) | 🇦🇲 [Հայերեն](../i18n/hy/docs/reference/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../i18n/id/docs/reference/API_REFERENCE.md) | 🇳🇬 [Igbo](../i18n/ig/docs/reference/API_REFERENCE.md) | 🇮🇹 [Italiano](../i18n/it/docs/reference/API_REFERENCE.md) | 🇯🇵 [日本語](../i18n/ja/docs/reference/API_REFERENCE.md) | 🇬🇪 [ქართული](../i18n/ka/docs/reference/API_REFERENCE.md) | 🇰🇭 [ខ្មែរ](../i18n/km/docs/reference/API_REFERENCE.md) | 🇮🇳 [ಕನ್ನಡ](../i18n/kn/docs/reference/API_REFERENCE.md) | 🇰🇷 [한국어](../i18n/ko/docs/reference/API_REFERENCE.md) | 🇱🇹 [Lietuvių](../i18n/lt/docs/reference/API_REFERENCE.md) | 🇱🇻 [Latviešu](../i18n/lv/docs/reference/API_REFERENCE.md) | 🇮🇳 [മലയാളം](../i18n/ml/docs/reference/API_REFERENCE.md) | 🇮🇳 [मराठी](../i18n/mr/docs/reference/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../i18n/ms/docs/reference/API_REFERENCE.md) | 🇲🇹 [Malti](../i18n/mt/docs/reference/API_REFERENCE.md) | 🇲🇲 [မြန်မာ](../i18n/my/docs/reference/API_REFERENCE.md) | 🇳🇵 [नेपाली](../i18n/ne/docs/reference/API_REFERENCE.md) | 🇳🇱 [Nederlands](../i18n/nl/docs/reference/API_REFERENCE.md) | 🇳🇴 [Norsk](../i18n/no/docs/reference/API_REFERENCE.md) | 🇮🇳 [ଓଡ଼ିଆ](../i18n/or/docs/reference/API_REFERENCE.md) | 🇮🇳 [ਪੰਜਾਬੀ](../i18n/pa/docs/reference/API_REFERENCE.md) | 🇵🇭 [Filipino](../i18n/phi/docs/reference/API_REFERENCE.md) | 🇵🇱 [Polski](../i18n/pl/docs/reference/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../i18n/pt/docs/reference/API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../i18n/pt-BR/docs/reference/API_REFERENCE.md) | 🇷🇴 [Română](../i18n/ro/docs/reference/API_REFERENCE.md) | 🇷🇺 [Русский](../i18n/ru/docs/reference/API_REFERENCE.md) | 🇱🇰 [සිංහල](../i18n/si/docs/reference/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../i18n/sk/docs/reference/API_REFERENCE.md) | 🇸🇮 [Slovenščina](../i18n/sl/docs/reference/API_REFERENCE.md) | 🇷🇸 [Српски](../i18n/sr/docs/reference/API_REFERENCE.md) | 🇸🇪 [Svenska](../i18n/sv/docs/reference/API_REFERENCE.md) | 🇰🇪 [Kiswahili](../i18n/sw/docs/reference/API_REFERENCE.md) | 🇮🇳 [தமிழ்](../i18n/ta/docs/reference/API_REFERENCE.md) | 🇮🇳 [తెలుగు](../i18n/te/docs/reference/API_REFERENCE.md) | 🇹🇭 [ไทย](../i18n/th/docs/reference/API_REFERENCE.md) | 🇹🇷 [Türkçe](../i18n/tr/docs/reference/API_REFERENCE.md) | 🇺🇦 [Українська](../i18n/uk-UA/docs/reference/API_REFERENCE.md) | 🇵🇰 [اردو](../i18n/ur/docs/reference/API_REFERENCE.md) | 🇺🇿 [Oʻzbekcha](../i18n/uz/docs/reference/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../i18n/vi/docs/reference/API_REFERENCE.md) | 🇳🇬 [Yorùbá](../i18n/yo/docs/reference/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../i18n/zh-CN/docs/reference/API_REFERENCE.md) | 🇹🇼 [中文 (繁體)](../i18n/zh-TW/docs/reference/API_REFERENCE.md) Zentrale Referenz für die OmniRoute-API. Sie beschreibt die öffentliche `/v1`-Schnittstelle und die am häufigsten verwendeten Verwaltungsendpunkte; die maschinenlesbare Datei [`docs/openapi.yaml`](../openapi.yaml) und der Routenbaum unter `src/app/api/` sind die vollständigen Quellen. --- ## Inhaltsverzeichnis - [Chat-Vervollständigungen](#chat-completions) - [Exklusive verwaltete Sitzungspachtverträge](#exclusive-managed-session-leases) - [Einbettungen](#embeddings) - [Bilderzeugung](#image-generation) - [Dokument-OCR](#document-ocr) - [Modelle auflisten](#list-models) - [Manifest für Anbieter-Plugins](#provider-plugin-manifest) - [Kompatibilitätsendpunkte](#compatibility-endpoints) - [Dateien-API](#files-api) - [Batches-API](#batches-api) - [Such-API](#search-api) - [WebSocket-Streaming](#websocket-streaming) - [Kontingente und Problemberichte](#quotas--issues-reporting) - [Semantischer Cache](#semantic-cache) - [Dashboard und Verwaltung](#dashboard--management) - [Kombinationsverwaltung](#combo-management) - [Webhooks](#webhooks) - [Registrierte Schlüssel (automatische Verwaltung)](#registered-keys-auto-management) - [Agentenprotokoll](#agents-protocol) - [Verwaltungs-Proxys](#management-proxies) - [Ausfallsicherheit (erweitert)](#resilience-extended) - [Fähigkeiten](#skills) - [Speicher](#memory) - [MCP-Server](#mcp-server) - [A2A-Server](#a2a-server) - [Cloud, Evaluierungen und Assess](#cloud-evals--assess) - [Anfrageverarbeitung](#request-processing) - [Authentifizierung](#authentication) --- ## Chat-Vervollständigungen ```bash POST /v1/chat/completions Authorization: Bearer your-api-key Content-Type: application/json { "model": "cc/claude-opus-4-6", "messages": [ {"role": "user", "content": "Write a function to..."} ], "stream": true } ``` ### Benutzerdefinierte Header | Header | Richtung | Beschreibung | | ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `X-OmniRoute-No-Cache` | Anfrage | Auf `true` setzen, um den Cache zu umgehen | | `x-omniroute-no-memory` | Anfrage | Auf `true` setzen, um die Einspeisung von Speicher + Fähigkeiten für diese Anfrage zu überspringen (entspricht no-cache; vermeidet den Token-/Kostenaufwand pro Aufruf) | | `X-OmniRoute-Progress` | Anfrage | Für Fortschrittsereignisse auf `true` setzen | | `X-Session-Id` | Anfrage | Persistenter Sitzungsschlüssel für externe Sitzungsaffinität | | `x_session_id` | Anfrage | Variante mit Unterstrichen wird ebenfalls akzeptiert (direktes HTTP) | | `X-OmniRoute-Session-Id` | Anfrage | Vom Aufrufer bereitgestelltes Sitzungs-/Konversations-Tag (wird auch dem Speicher zugeführt). Wenn vorhanden, wird es unverändert in `call_logs.session_tag` zur sitzungsbezogenen Kostenzuordnung (#8249) gespeichert — bei Fehlen wird es niemals erzeugt | | `Idempotency-Key` | Anfrage | Deduplizierungsschlüssel (5-Sekunden-Fenster) | | `X-Request-Id` | Anfrage | Alternativer Deduplizierungsschlüssel | | `X-OmniRoute-Cache` | Antwort | `HIT` oder `MISS` (ohne Streaming) | | `X-OmniRoute-Idempotent` | Antwort | `true`, wenn dedupliziert | | `X-OmniRoute-Progress` | Antwort | `enabled`, wenn die Fortschrittsverfolgung aktiviert ist | | `X-OmniRoute-Session-Id` | Antwort | Von OmniRoute verwendete effektive Sitzungs-ID | | `X-OmniRoute-Request-Id` | Antwort | Korrelations-ID der Anfrage (sofern bekannt) | | `X-OmniRoute-Version` | Antwort | OmniRoute-Build-Version (immer vorhanden) | | `X-OmniRoute-Cost-Saved` | Antwort | Durch den Cache bei einem HIT vermiedene Kosten in USD (nur Cache-Treffer) | | `X-OmniRoute-Decision` | Antwort | Routing-Ablauf: `strategy=; provider=; latency_ms=` (`` ist die Kombinationsstrategie oder `single` für eine Anfrage ohne Kombination) — bei Abschlussantworten immer vorhanden | > Nginx-Hinweis: Wenn Sie Header mit Unterstrichen verwenden (zum Beispiel `x_session_id`), aktivieren Sie `underscores_in_headers on;`. > **Header zur Kostentelemetrie:** Nicht-streamende erfolgreiche Antworten enthalten ebenfalls den Kostentelemetrie-Satz `X-OmniRoute-*` — `X-OmniRoute-Response-Cost` (USD, fest auf 10 Dezimalstellen; `0.0000000000` für kostenlose/nicht bepreiste Anfragen), `X-OmniRoute-Tokens-In` / `X-OmniRoute-Tokens-Out`, `X-OmniRoute-Model`, `X-OmniRoute-Provider`, `X-OmniRoute-Latency-Ms`, `X-OmniRoute-Cache-Hit` und `X-OmniRoute-Fallback-Attempts` (nur wenn > 0) sowie `X-OmniRoute-Request-Id` und `X-OmniRoute-Version`. Diese werden von Chat Completions, `/v1/responses`, `/v1/messages` **und den Medienendpunkten** ausgegeben — `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/speech`, `/v1/audio/transcriptions`, `/v1/rerank`, `/v1/videos/generations`, `/v1/music/generations` und `/v1/moderations` (Kosten stets `0`). Die Medienkosten werden, sofern Preisinformationen verfügbar sind, je nach Modalität pro Bild, pro Sekunde, pro Zeichen oder pro Sucheinheit berechnet, andernfalls `0` (Fail-Open). > **Kostenberechnung bei Cache-Treffern:** Bei einem TREFFER im semantischen Cache (`X-OmniRoute-Cache-Hit: true`) erfolgt kein Upstream-Aufruf, daher beträgt `X-OmniRoute-Response-Cost` `0.0000000000` (die **inkrementellen** Kosten für die Bereitstellung des Treffers). Die ursprünglichen beziehungsweise andernfalls angefallenen Kosten werden separat in `X-OmniRoute-Cost-Saved` ausgewiesen. Abrechnungssysteme sollten `X-OmniRoute-Response-Cost` summieren (Treffer verursachen keine Kosten); für Cache-Analysen kann `X-OmniRoute-Cost-Saved` aggregiert werden. ## Exklusive verwaltete Sitzungslizenzen Die exklusive Vergabe verwalteter Sitzungslizenzen ist ein optionaler, clientneutraler Routing-Vertrag: Ein aktiver Besitzer hält eine geeignete OmniRoute-Verbindung. Dabei wird weder ein Modell reserviert noch OAuth vorausgesetzt, ein bestimmter Client identifiziert oder ein bestimmter Anbieter verlangt. Der zur Authentifizierung verwendete API-Schlüssel muss den Geltungsbereich `lease:exclusive` und eine explizite, nicht leere Liste `allowedConnections` besitzen. Die Mutationsgrenze der Datenbank erzwingt beide Felder gemeinsam bei der Schlüsselerstellung und bei partiellen Aktualisierungen. ```http POST /api/v1/session-leases Authorization: Bearer Content-Type: application/json X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> {"action":"acquire","model":"glm/glm-4.6"} ``` Erfolgreiche Antworten auf Erwerb, Verlängerung und Freigabe enthalten Zeitstempel, `state` und die exakte positive `generation`, jedoch niemals die ausgewählte Verbindung oder Anmeldedaten. Bei Verlängerung und Freigabe wird die Generation im JSON-Text angegeben: ```json { "action": "renew", "generation": 1 } ``` ```json { "action": "release", "generation": 1, "reason": "OWNER_EXIT" } ``` Der Besitzer einer aktiven Lizenz kann explizit datenschutzfreundliche Anzeigemetadaten für seine aktuelle Bindung anfordern: ```json { "action": "status", "generation": 1 } ``` ```json { "state": "ACTIVE", "generation": 1, "acquiredAt": "2026-08-28T12:00:00.000Z", "renewedAt": "2026-08-28T12:00:30.000Z", "expiresAt": "2026-08-28T12:02:30.000Z", "connection": { "displayName": "Primary Codex", "provider": "codex" } } ``` Diese optionale Statusaktion wird innerhalb einer einzigen Datenbanktransaktion durch den nicht transparenten Besitzer, den authentifizierten verwalteten API-Schlüssel und die exakte aktive Generation abgesichert. `displayName` ist ausschließlich der bereinigte konfigurierte Verbindungsname; wenn kein sicherer konfigurierter Name vorhanden ist, lautet der Wert `null`. OmniRoute ersetzt ihn niemals durch eine E-Mail-Adresse oder eine generierte Kontoidentität. Der Anbieterwert ist eine nicht vertrauliche Anzeigebezeichnung und niemals eine generierte Kennung eines kompatiblen Anbieters. Anmeldedaten, Tokens, Cookies, unverarbeitete Verbindungs- oder API-Schlüssel-IDs, Besitzer-Hashes, Fencing-Geheimnisse und interne Routing-Daten werden ausgeschlossen. Abfragen mit falschem Schlüssel, falschem Besitzer, veralteter Generation sowie Abfragen fehlender, abgelaufener, freigegebener oder ungültig gemachter Lizenzen geben alle denselben Fehler `409 LEASE_FENCE_STALE` ohne Verbindungsmetadaten zurück. Ein Client, der die Antwort zum Warten auf Kapazität erhalten hat, besitzt keine aktive Bindung, die geprüft werden könnte. Wenn das Routing eine aktive Lizenz auf eine andere Verbindung umstellt, bleibt dieselbe Generation gültig, und der Status gibt atomar die neue Bindung zurück, niemals die alte. Bestehende Clients bleiben unverändert, da die Antworten für Erwerb, Verlängerung, Freigabe und Wartezustände ihre bisherigen Strukturen beibehalten. Dieser Serververtrag ändert den standardmäßigen OpenAI-Codex-Endpunkt `/status` nicht. Standard-Codex meldet derzeit seinen Modellanbieter und den integrierten Authentifizierungs-/Kontostatus, stellt jedoch keine beliebigen benutzerdefinierten Anbieter-Kontometadaten dar; eine spätere Clientintegration muss diese Aktion aufrufen und entscheiden, wie `connection.displayName` angezeigt werden soll. Jede verwaltete Inferenzanfrage übermittelt anschließend beide Steuerungsheader: ```http X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> X-OmniRoute-Lease-Generation: 1 ``` Der exakte Besitzer, die Generation, die aktive Verbindung und der authentifizierte API-Schlüssel werden unmittelbar vor jedem unterstützten Upstream-Versuch abgesichert. Die Wiederverwendung von Besitzer und Generation mit einem anderen Schlüssel schlägt selbst dann fehl, wenn dieser Schlüssel dieselbe Verbindung zulässt. Unverarbeitete Besitzerwerte werden weder persistiert noch protokolliert, im Anfrage-Snapshot beibehalten oder an den Upstream weitergeleitet. Vorübergehende Ressourcenkonkurrenz gibt HTTP `429` mit `Retry-After` und Folgendem zurück: ```json { "state": "WAITING_FOR_CAPACITY", "error": { "type": "lease_error", "code": "LEASE_CAPACITY_UNAVAILABLE" }, "reason": "NO_FREE_ELIGIBLE_CONNECTION", "retryAfter": 30 } ``` Diese Antwort bedeutet lediglich, dass die reguläre Menge geeigneter Verbindungen nicht leer war und jeder freie Kandidat durch eine fremde aktive Lizenz belegt war. Nicht unterstützte Modelle/Anbieter, Richtlinienabweichungen, Abklingzeiten, Kontingente, Integritätszustände und andere reguläre Eignungsfehler behalten ihre bestehenden OmniRoute-Antworten bei. ### `x-omniroute-compression` Anfragebezogene Überschreibung des Komprimierungsplans. Höchste Priorität — hat Vorrang vor der Routing-Kombinationsüberschreibung, dem aktiven Profil, der automatischen Auslösung und der Standardeinstellung des Panels. Werte: | Wert | Wirkung | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `off` | Keine Komprimierung für diese Anfrage. | | `default` | Das vom Panel abgeleitete Standardprofil (ignoriert das aktive Profil). | | `engine:` | Eine einzelne Engine, sofern aktiviert, z. B. `engine:rtk`. | | `` | Eine benannte Kombination, die zuerst anhand des Namens (ohne Beachtung der Groß-/Kleinschreibung) und dann anhand der ID abgeglichen wird. | Hinweise: - Unbekannte Werte werden ignoriert (die Anfrage wird niemals abgelehnt); die Auflösung greift auf die normale Operatorrangfolge zurück. - Wenn mehrere Kombinationen denselben Namen verwenden, geben Sie für eine deterministische Übereinstimmung die **id** der Kombination an. - Eine Kombination mit dem Namen `off` oder `default` kann nicht anhand ihres Namens ausgewählt werden (diese Schlüsselwörter werden zuerst interpretiert); referenzieren Sie eine solche Kombination anhand ihrer ID. - Der Hauptschalter für die Komprimierung ist eine feste Sperre: Wenn die Komprimierung global deaktiviert ist, kann sie durch diesen Header nicht aktiviert werden. Der angewendete Plan wird im Antwortheader zurückgegeben: ``` X-OmniRoute-Compression: ; source= ``` Dabei ist `` einer der Werte `request-header`, `routing-override`, `active-profile`, `auto-trigger`, `default` oder `off`. --- ## Embeddings ```bash POST /v1/embeddings Authorization: Bearer your-api-key Content-Type: application/json { "model": "nebius/Qwen/Qwen3-Embedding-8B", "input": "The food was delicious" } ``` Verfügbare Anbieter: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, Jina AI. Katalog-IDs haben das Format `provider/model` (Beispiel: `jina-ai/jina-embeddings-v5-omni-small`). Reine Jina-Modell-IDs, die in der Registry aufgeführt sind (zum Beispiel `jina-embeddings-v5-text-small`, `jina-reranker-v3.5`), werden ebenfalls aufgelöst. Jina-Operationen zum Einbetten, Reranking, Klassifizieren und Segmentieren verwenden zuerst die `jina-ai`-Anmeldedaten aus dem Dashboard; `JINA_AI_API_KEY` dient nur als Fallback, wenn kein Dashboard-Schlüssel vorhanden ist. Die Karte `jina-reader` ist ausschließlich für Reader / `r.jina.ai` (`POST /v1/web/fetch`) bestimmt und stellt niemals Embeddings oder Reranking bereit. Registry-Modelle, die multimodale Unterstützung angeben, akzeptieren außerdem bis zu 32 anbieterneutrale strukturierte Elemente. Die Medienelementtypen sind `text`, `image`, `audio`, `video` und `document`. Ihre Medien-`source` ist entweder `{"type":"url","url":"https://..."}` oder `{"type":"base64","data":"...","media_type":"..."}`. Jina v5 Omni (`jina-ai/jina-embeddings-v5-omni-small`, `jina-ai/jina-embeddings-v5-omni-nano` und der Familienalias `jina-ai/jina-embeddings-v5-omni` → omni-small) akzeptiert außerdem die nativen EmbeddingsV5Request-Dokumente von Jina und **leitet sie unverändert** an `https://api.jina.ai/v1/embeddings` weiter: ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "task": "retrieval.query", "normalized": true, "input": [ { "text": "a red bicycle" }, { "image": "https://example.com/bike.png" }, { "content": [{ "text": "caption" }, { "image": "data:image/png;base64,..." }] } ] } ``` Native `{ image | audio | video | pdf }`-Werte können eine öffentliche HTTPS-URL, eine `data:`-URI oder rohe Base64-Daten sein. OmniRoute wandelt diese Objekte nicht in Strings um und ruft native Bild-URLs nicht ab — Jina ruft öffentliche Medien selbst ab. Zusätzliche Jina-Felder (`task`, `normalized`, `truncate`, `embedding_type`) werden weitergeleitet. Jina-SKUs, die ausschließlich Text unterstützen, lehnen weiterhin Dokumente ab, die nicht aus Text bestehen. Sicherheits- und Transportbeschränkungen: - Remote-Medien-URLs müssen öffentliches HTTPS verwenden. Kanonische `{type,source:url}`-Elemente werden serverseitig abgerufen (erneute Validierung von Weiterleitungen, Zeitüberschreitung, Größenbeschränkungen, öffentliches DNS, Verbindungs-Pinning) und vor dem Anbieteraufruf eingebettet. Jina-native `{image:"https://..."}`-Elemente werden nach derselben Prüfung auf öffentliches HTTPS unverändert weitergeleitet; Jina ruft die URL ab. - Inline-Base64-Medien sind auf 8 MiB dekodiert pro Element und 16 MiB dekodiert für die gesamte Anfrage begrenzt. Anbieterübersetzung (kanonische Elemente werden niemals unverändert weitergeleitet): - Multimodale Jina-Modelle: Jedes Element der obersten Ebene wird zu einem Objekt mit einem Modalitätsschlüssel (`text` / `image` / `audio` / `video` / `pdf`), wobei für Inline-Medien Daten-URIs verwendet werden; ein Vektor pro Element der obersten Ebene. - Gemini Embedding 2-Familie: Ein Array der obersten Ebene wird zu einer einzelnen nativen `models/{model}:embedContent`-Anfrage mit `content.parts` (`text` oder `inline_data`). - Unbekannte/dynamische Modelle ohne explizite Modalitätsmetadaten lehnen strukturierte Eingaben mit HTTP 400 ab. ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "input": [ { "type": "text", "text": "A red bicycle" }, { "type": "image", "source": { "type": "url", "url": "https://example.com/bicycle.png" } } ], "dimensions": 512, "encoding_format": "float" } ``` Nicht unterstützte Modell-/Modalitätskombinationen geben HTTP 400 zurück, anstatt das Element zu konvertieren. Erweiterungsfelder, die nicht zur Eingabe gehören, werden bei älteren String-/Token-Anfragen weiterhin unverändert durchgereicht. ```bash # Alle Embedding-Modelle auflisten GET /v1/embeddings ``` --- ## Bildgenerierung ```bash POST /v1/images/generations Authorization: Bearer your-api-key Content-Type: application/json { "model": "openai/gpt-image-2", "prompt": "Ein wunderschöner Sonnenuntergang über Bergen", "size": "1024x1024" } ``` Verfügbare Anbieter: OpenAI (GPT Image 2), xAI (Grok Image), Together AI (FLUX), Fireworks AI, Nebius (FLUX), Hyperbolic, NanoBanana, **OpenRouter**, SD WebUI (lokal), ComfyUI (lokal). ```bash # Alle Bildmodelle auflisten GET /v1/images/generations ``` --- ## Dokument-OCR ```bash POST /v1/ocr Authorization: Bearer your-api-key Content-Type: application/json { "model": "mistral/mistral-ocr-latest", "document": { "type": "document_url", "document_url": "https://example.com/invoice.pdf" } } ``` `model` wählt den OCR-Anbieter über das Präfix `provider/model` aus; eine reine Modell-ID (z. B. `mistral-ocr-latest`) wird dem registrierten Anbieter zugeordnet, und wenn `model` weggelassen wird, wird standardmäßig Mistral (`mistral-ocr-latest`) verwendet. Registrierte Anbieter (`open-sse/config/ocrRegistry.ts`): | Anbieter-ID | Modell-ID | `model`-Wert | Hinweise | | ----------------------------- | -------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | | `mistral` | `mistral-ocr-latest` | `mistral/mistral-ocr-latest` (oder nur `mistral-ocr-latest`) | Synchron — die Antwort wird direkt vom einzelnen Upstream-Aufruf zurückgegeben. | | `azure-document-intelligence` | `prebuilt-read` | `azure-document-intelligence/prebuilt-read` | Asynchroner Upstream (`analyze` + Polling) — siehe unten. | | `vertex-deepseek-ocr` | `deepseek-ocr-maas` | `vertex-deepseek-ocr/deepseek-ocr-maas` | Synchron, über den Partner-Endpunkt `openapi/chat/completions` von Vertex AI — Authentifizierung/URL siehe unten. | Alle drei Anbieter antworten mit demselben an Mistral angelehnten Body: ```json { "pages": [{ "index": 0, "markdown": "# Extrahierter Text ..." }], "model": "mistral-ocr-latest", "usage_info": { "pages_processed": 1 } } ``` ### Polling-Ablauf von Azure Document Intelligence Die `analyze`-API von Azure Document Intelligence ist asynchron: Die ursprüngliche Anfrage gibt statt eines Bodys einen `Operation-Location`-Header zurück, und das Ergebnis muss durch Polling abgefragt werden. Der Handler (`open-sse/handlers/ocr.ts`) fragt diese URL bis zu 30-mal im Sekundentakt ab, bricht bei einer Polling-Antwort, die nicht `ok` ist, oder einem Status `"failed"` sofort mit einem Fehler ab (ohne das Polling fortzusetzen) und gibt `504` zurück, wenn der Vorgang nach Ausschöpfung der maximalen Versuche noch immer läuft. Die endgültige Azure-Antwort wird vor der Rückgabe an den Aufrufer in dieselbe von Mistral verwendete `pages`-/`markdown`-Struktur normalisiert, sodass der Clientcode den Anbieter nicht gesondert behandeln muss. ### Authentifizierung und Endpunktauflösung für Vertex AI DeepSeek OCR `vertex-deepseek-ocr` verwendet dieselbe Vertex-AI-Authentifizierung wieder, die OmniRoute bereits für Chat-/Bilddatenverkehr unterstützt (`open-sse/executors/vertex.ts`): Der API-Schlüssel der Verbindung ist entweder eine Service-Account-JSON-Anmeldeinformation (die über den JWT-Bearer-Ablauf gegen ein kurzlebiges OAuth-Zugriffstoken ausgetauscht wird) oder ein bereits ausgestelltes OAuth-Zugriffstoken, das unverändert verwendet wird. Die URL des Upstream-Endpunkts ist der generische Partner-Endpunkt `openapi/chat/completions` von Vertex und wird aus dem Projekt und der Region der Verbindung erstellt — explizite Werte für `providerSpecificData.project`/`providerSpecificData.region` haben immer Vorrang; andernfalls wird das Projekt aus `project_id` im Service-Account-JSON abgeleitet, und für die Region wird standardmäßig `us-central1` verwendet. Beide Auflösungen erfolgen in `open-sse/handlers/ocr.ts` (`resolveVertexOcrAccessToken`, `resolveVertexOcrBaseUrl`) und werden von `src/app/api/v1/ocr/route.ts` verwendet, bevor die Anfrage an `handleOcr` weitergeleitet wird. --- ## Modelle auflisten ```bash GET /v1/models Authorization: Bearer your-api-key → Gibt alle Chat-, Embedding- und Bildmodelle sowie Kombinationen im OpenAI-Format zurück ``` ### Modell-ID-Präfixe (`?prefix=`) Die meisten Modelle werden unter einem **Anbieterpräfix** angeboten. Welches Präfix verwendet wird, wird durch das Feature-Flag `MODELS_CATALOG_PREFIX_MODE` gesteuert und kann **pro Anfrage** mit einem Abfrageparameter überschrieben werden — nützlich für einen Client, der eine übersichtliche Liste erhalten möchte, ohne die serverweite Einstellung für alle anderen zu ändern: ```bash GET /v1/models?prefix=alias # eine ID pro Modell — das kurze Aliaspräfix GET /v1/models?prefix=dual # beide Formen (Serverstandard) GET /v1/models?prefix=canonical # nur das vollständige Anbieter-ID-Präfix ``` | Modus | Gibt aus | Hinweise | | ----------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `dual` | `cc/claude-sonnet-4-6` **und** `claude/claude-sonnet-4-6` | **Standard.** Beide IDs werden an dasselbe Modell weitergeleitet; dies bleibt so bestehen, damit Client-Konfigurationen, in denen eine der beiden Formen fest codiert ist, weiterhin funktionieren. Verdoppelt den Katalog ungefähr. | | `alias` | `cc/claude-sonnet-4-6` | Ein Eintrag pro Modell. Anbieter ohne eindeutigen Alias geben ihren Eintrag weiterhin aus, sodass nichts verloren geht. | | `canonical` | `claude/claude-sonnet-4-6` | Ein Eintrag pro Modell unter dem vollständigen Anbieter-ID-Präfix. Anbieter ohne eindeutigen Alias (z. B. `antigravity/…`, `agy/…`) geben auch hier ihre einzelne ID aus, sodass nichts verloren geht. | Eine Spiegel-ID im `dual`-Modus kann auch ohne den Abfrageparameter erkannt werden: Sie enthält ein `parent`-Feld, das auf die primäre ID verweist. Clients, die eine Modellauswahl darstellen, sollten `?prefix=alias` anfordern — so verfährt auch die [OmniCopilot-VS-Code-Erweiterung](../guides/VSCODE-COPILOT.md). ### Modellvarianten ohne Denkmodus Für denkfähige Claude-Modelle bietet `/v1/models` außerdem eine **No-Thinking-Variante** an, deren ID das Präfix `claude-3-omniroute-no-thinking/` trägt: ``` claude-3-omniroute-no-thinking// ``` Bei Auswahl dieser ID (z. B. in einer Claude-Code-Konfiguration, die immer einen `thinking`-Block anhängt) wird sie wieder zum tatsächlichen `/` aufgelöst, wobei das Reasoning unterdrückt wird — durch `thinking:{type:"disabled"}` für den Pfad `/v1/messages` oder durch Entfernen der Felder `reasoning`/`reasoning_effort` für den Pfad `/v1/chat/completions`. Die Variante wird nur für Modelle der Claude-Familie aufgeführt, die den Denkmodus unterstützen **und** `disabled` berücksichtigen (d. h. beispielsweise Modelle, die nur den adaptiven Modus unterstützen und `disabled` ablehnen, sind ausgeschlossen). Betreiber können die Variante über `ModelSpec.noThinkingAlias` für jedes Modell erzwingen oder deaktivieren. --- ## Anbieter-Plugin-Manifest ```bash GET /api/v1/provider-plugin-manifest ``` Gibt das JSON-sichere Anbieter-Plugin-Manifest zurück, das von Bifrost, CLIProxyAPI und zukünftigen Sidecar-Routern verwendet wird. Die Antwort wird aus der TypeScript-Anbieterregistrierung generiert und schließt OAuth-Client-Geheimnisse, die Auflösung der Laufzeitumgebung, Executor-Funktionen, Anfrage-Header und Kontodaten absichtlich aus. Verwenden Sie diesen Endpunkt, wenn ein Sidecar außerhalb des Prozesses ausgeführt wird und `open-sse/config/providerPluginManifestRegistry.ts` nicht direkt importieren kann. --- ## Kompatibilitätsendpunkte | Methode | Pfad | Format | | ------- | ----------------------------------------- | ------------------------------------- | | POST | `/v1/chat/completions` | OpenAI | | POST | `/v1/messages` | Anthropic | | POST | `/v1/responses` | OpenAI Responses | | POST | `/v1/embeddings` | OpenAI | | POST | `/v1/images/generations` | OpenAI Images | | POST | `/v1/images/edits` | OpenAI Images (Bearbeiten/Inpainting) | | POST | `/v1/videos/generations` | Videoerzeugung im OpenAI-Stil | | POST | `/v1/music/generations` | Musikerzeugung im OpenAI-Stil | | POST | `/v1/audio/transcriptions` | OpenAI Audio (STT) | | POST | `/v1/audio/speech` | OpenAI TTS (gibt Audiodaten zurück) | | POST | `/v1/rerank` | Neusortierung im Cohere-/Voyage-Stil | | POST | `/v1/classify` | Jina-Klassifizierung (`api.jina.ai`) | | POST | `/v1/segment` | Jina-Segmentierer (`segment.jina.ai`) | | POST | `/v1/moderations` | OpenAI Moderations | | GET | `/v1/models` | OpenAI | | POST | `/v1/messages/count_tokens` | Anthropic | | GET | `/v1beta/models` | Gemini | | POST | `/v1beta/models/{...path}` | Gemini generateContent | | POST | `/v1/api/chat` | Ollama | | GET | `/api/v1/vscode/{token}/` | OpenAI-Katalogalias | | GET | `/api/v1/vscode/{token}/models` | OpenAI-Modellalias | | POST | `/api/v1/vscode/{token}/chat/completions` | Tokenisierter OpenAI-Alias | | POST | `/api/v1/vscode/{token}/responses` | Tokenisierter OpenAI-Responses-Alias | | POST | `/api/v1/vscode/{token}/api/chat` | Tokenisierter Ollama-Alias | | GET | `/api/v1/vscode/{token}/api/tags` | Tokenisierter Ollama-Tags-Alias | Alle POST-Routen folgen demselben Schema: `Bearer your-api-key` + ein durch Zod validierter JSON-Body (`v1RerankSchema`, `v1ModerationSchema`, `v1AudioSpeechSchema` usw.; siehe `src/shared/validation/schemas.ts`). Bei einem Schemafehler wird ein 4xx-Statuscode zurückgegeben. Für Clients, die `Authorization: Bearer ...` nicht anhängen können, akzeptiert OmniRoute API-Schlüssel auch in der URL, entweder über kompatible Abfrageparameter (`?token=...`, `?apiKey=...`, `?api_key=...`, `?key=...`) oder über die unten dokumentierten dedizierten `/api/v1/vscode/{token}/...`-Endpunkte. ```bash # Neusortierung POST /v1/rerank { "model": "jina-ai/jina-reranker-v3.5", "query": "...", "documents": ["..."] } # Jina-Klassifizierung (Foundation-API-Anmeldedaten) POST /v1/classify { "model": "jina-embeddings-v5-text-small", "input": ["..."], "labels": ["a", "b"] } # Jina-Segmentierer POST /v1/segment { "content": "...", "return_chunks": true } # Jina-Suche (s.jina.ai; Anbieter-Aliasse: jina-search, jina-ai, jina) POST /v1/search { "query": "...", "provider": "jina-search" } # Moderation POST /v1/moderations { "model": "omni-moderation-latest", "input": "..." } # TTS — gibt einen audio/mpeg-Body (oder das angeforderte Format) zurück POST /v1/audio/speech { "model": "openai/tts-1", "input": "Hello", "voice": "alloy" } # Bildbearbeitung (Multipart) POST /v1/images/edits -F image=@input.png -F prompt="..." -F mask=@mask.png # Video-/Musikerzeugung (Modell-ID mit Anbieterpräfix) POST /v1/videos/generations { "model": "runway/gen-3", "prompt": "..." } POST /v1/music/generations { "model": "suno/v3.5", "prompt": "..." } ``` ### Dedizierte Anbieterrouten ```bash POST /v1/providers/{provider}/chat/completions POST /v1/providers/{provider}/embeddings POST /v1/providers/{provider}/images/generations ``` Das Anbieterpräfix wird automatisch hinzugefügt, wenn es fehlt. Nicht übereinstimmende Modelle geben `400` zurück. --- ## Files API OpenAI-kompatibler Datei-Endpunkt für Batch-Ein-/Ausgaben und Uploads mit Dateiverwendungszweck. | Methode | Pfad | Beschreibung | | ------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------- | | POST | `/v1/files` | Datei hochladen (Multipart: `file`, `purpose`, `expires_after[anchor]`, `expires_after[seconds]`) — max. 512 MiB | | GET | `/v1/files` | Dateien für den authentifizierten API-Schlüssel auflisten | | GET | `/v1/files/[id]` | Metadaten einer Datei abrufen | | DELETE | `/v1/files/[id]` | Datei löschen | | GET | `/v1/files/[id]/content` | Unveränderten Dateiinhalt als Stream zurückgeben | **Authentifizierung:** Bearer-API-Schlüssel — Dateien werden über `getApiKeyRequestScope` nach API-Schlüssel getrennt. Ein Schlüssel kann nur seine eigenen Dateien anzeigen, herunterladen und löschen; eine Dashboard-Sitzung ohne Schlüssel kann die gesamte Instanz lesen; der Zugriff auf eine Datei ohne Besitzer (anonymer Upload oder Upload über eine Dashboard-Sitzung) wird jedem Aufrufer ohne Sitzung verweigert. `GET /v1/files` weist einen anonymen Aufrufer — sowie einen angegebenen Schlüssel, der nicht aufgelöst werden kann — selbst dann mit `401` zurück, wenn `REQUIRE_API_KEY=false` gilt, anstatt die Dateien aller Mandanten aufzulisten (GHSA-m3hp-hq9g-fpmv, GHSA-2jm2-mpx8-6523). --- ## Batches API OpenAI-kompatible Batch-Verarbeitung. | Methode | Pfad | Beschreibung | | ------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | POST | `/v1/batches` | Batch erstellen — Anfragetext wird durch `v1BatchCreateSchema` validiert (`input_file_id`, `endpoint`, `completion_window`) | | GET | `/v1/batches` | Batches auflisten | | GET | `/v1/batches/[id]` | Batch-Status und `request_counts` abrufen | | DELETE | `/v1/batches/[id]` | Abgeschlossenen/fehlgeschlagenen Batch löschen | | POST | `/v1/batches/[id]/cancel` | Laufenden Batch abbrechen | **Authentifizierung:** Bearer-API-Schlüssel. Batches werden nach API-Schlüssel gemäß derselben Drei-Wege-Regel wie Dateien getrennt: nur eigener Schlüssel, Dashboard-Sitzung instanzweit, Datensätze ohne Besitzer werden jedem Aufrufer ohne Sitzung verweigert (Abrufen, Löschen, Abbrechen sowie die Prüfung von `input_file_id` beim Erstellen). `GET /v1/batches` weist einen anonymen Aufrufer selbst dann mit `401` zurück, wenn `REQUIRE_API_KEY=false` gilt. --- ## Search-API Abstraktion für Web-/Suchanbieter (Tavily, Brave, Exa, Serper usw.). | Methode | Pfad | Beschreibung | | ------- | ---------------------- | ---------------------------------------------------------------------------------------------------------- | | GET | `/v1/search` | Konfigurierte Suchanbieter und Funktionen auflisten | | POST | `/v1/search` | Eine Suchanfrage ausführen — Body wird durch `v1SearchSchema` validiert, unterstützt Caching/Koaleszierung | | GET | `/v1/search/analytics` | Treffer-/Latenz-/Cache-Statistiken pro Anbieter | **Authentifizierung:** Bearer-API-Schlüssel (`extractApiKey` + `isValidApiKey`). Die Suchrichtlinie wird über `enforceApiKeyPolicy` durchgesetzt. --- ## Web-Fetch-API Inhalte über einen konfigurierten Web-Fetch-Anbieter (Firecrawl, Jina Reader, Tavily Extract, TinyFish Fetch, Nimble Extract) aus einer URL extrahieren. | Methode | Pfad | Beschreibung | | ------- | --------------- | ----------------------------------------------------------------------- | | POST | `/v1/web/fetch` | Eine URL abrufen/scrapen — Body wird durch `v1WebFetchSchema` validiert | **Authentifizierung:** Bearer-API-Schlüssel (`extractApiKey` + `isValidApiKey`). Die Richtlinie wird über `enforceApiKeyPolicy` durchgesetzt. **Kontingentabhängiger Fallback (#8297):** Wenn kein expliziter `provider` angegeben ist, wird der Pool (`firecrawl` → `jina-reader` → `tavily-search` → `tinyfish` → `nimble-search`) in fester Prioritätsreihenfolge durchlaufen (Fill-first) — ein ratenbegrenzter, aber konfigurierter Anbieter wird übersprungen, anstatt die Anfrage sofort abzubrechen, und ein wiederholbarer Kontingentfehler des Upstreams (HTTP 429 immer; 402/403 bei kontingentbedingten kostenlosen Tarifen von Firecrawl/Tavily/TinyFish — nicht bei Jina Reader und niemals bei einer einfachen fehlerhaften 400-Anfrage) führt zur Laufzeit der Anfrage zum nächsten noch nicht versuchten Anbieter mit hinterlegten Zugangsdaten. Wenn alle Anbieter im Pool ausgeschöpft sind, gibt der Endpunkt statt des bisherigen generischen `400` einen einzelnen `429`-Fehler (mit einem `Retry-After`-Header) zurück. Wenn ein expliziter `provider` angefordert wird, gibt es **keinen** stillen Fallback — ein ratenbegrenzter oder fehlschlagender expliziter Anbieter gibt seinen eigenen Fehler zurück (`429` bei Ratenbegrenzung, andernfalls den Upstream-Status). --- ## WebSocket-Streaming ```bash GET /v1/ws?handshake=1 ``` Validiert einen WebSocket-Upgrade-Handshake und gibt Beispielnachrichten des Wire-Protokolls (`request`, `cancel`) zurück. Die eigentlichen WS-Frames werden vom gebündelten WS-Server außerhalb der Next.js-Routentabelle verarbeitet. **Authentifizierung:** Bearer-API-Schlüssel während des Handshakes. ### Responses-API über WebSocket (nur codex) ```bash # Derselbe Host und Port wie bei der HTTP-API (standardmäßig 20128); Verbindung aktualisieren: wscat -c "ws://localhost:20128/v1/responses?api_key=" # (oder: -H "Authorization: Bearer ") # Der erste Frame MUSS response.create sein: { "type": "response.create", "model": "gpt-5.5", "input": [ { "role": "user", "content": "hi" } ] } ``` Ein Responses-API-over-WebSocket-Proxy ist **ausschließlich mit `codex`** (ChatGPT- Backend) verbunden. Er lauscht am selben Port wie die API/das Dashboard unter den Pfaden `/v1/responses`, `/responses` und `/api/v1/responses`. Beim ersten `response.create`-Frame authentifiziert und initialisiert er die Verbindung über die interne `codex-responses-ws`-Bridge, wählt eine codex-OAuth-Verbindung aus und tunnelt über den `wreq-js`-Transport zu `wss://chatgpt.com/backend-api/codex/responses`. **Nicht-codex-Modelle werden abgelehnt** (`codex_ws_provider_required`). Verwenden Sie für kontingentanteiliges Routing `model: "qtSd//codex/"`. Implementiert in `app/server-ws.mjs` + `scripts/dev/responses-ws-proxy.mjs` + `src/app/api/internal/codex-responses-ws/route.ts`. **Authentifizierung:** Bearer-API-Schlüssel während des Handshakes. Der gebündelte HTTP-Server (`server-ws.mjs`) muss der aktive Einstiegspunkt sein (was standardmäßig der Fall ist, wenn `app/server-ws.mjs` vorhanden ist). #### Modell-ID: die reine ChatGPT-ID verwenden (ohne Präfix `codex/`) Die OpenAI **Codex CLI** validiert den Modellnamen clientseitig, wenn `supports_websockets = true` gilt, und **lehnt Anbieterpräfix-IDs** wie `codex/gpt-5.5` ab (`The 'codex/gpt-5.5' model is not supported when using Codex with a ChatGPT account`). Senden Sie die **reine** ID (z. B. `gpt-5.5`). Die Bridge von OmniRoute unterstützt ausschließlich codex und löst daher eine reine ID vor dem Tunneln zum Upstream erneut als codex-Modell auf (`resolveCodexWsModelInfo`) — obwohl ein reines `gpt-5.5` über HTTP andernfalls an einen anderen Anbieter weitergeleitet würde. #### Konfigurieren der OpenAI Codex CLI Richten Sie die Codex CLI auf OmniRoute aus, indem Sie unter `~/.codex/config.toml` einen benutzerdefinierten Anbieter mit WebSocket- Unterstützung hinzufügen (verwenden Sie ein separates `CODEX_HOME`, um eine bestehende Konfiguration nicht zu verändern): ```toml model = "gpt-5.5" # reine ID — NICHT "codex/gpt-5.5" model_provider = "omniroute" [model_providers.omniroute] name = "OmniRoute (WS)" base_url = "http://localhost:20128/v1" # kein abschließender Schrägstrich; die WS-URL wird daraus abgeleitet (in der Produktion https/wss verwenden) wire_api = "responses" # seit Feb. 2026 der einzige unterstützte Wert supports_websockets = true # aktiviert den Responses-over-WS-Transport env_key = "OMNIROUTE_API_KEY" # enthält den OmniRoute-API-Schlüssel (Bearer) ``` ```bash export OMNIROUTE_API_KEY=sk-... # ein OmniRoute-API-Schlüssel (beliebiger Schlüssel, wenn REQUIRE_API_KEY=false) codex exec "Responda apenas: PONG" ``` Die CLI aktualisiert `base_url + /responses` zu einem WebSocket, und OmniRoute tunnelt ihn zur ausgewählten codex-OAuth-Verbindung. Ende-zu-Ende gegen den lokalen Server validiert: ChatGPT gibt `codex.rate_limits` + `response.created` zurück und streamt die Vervollständigung. --- ## Kontingente und Problemberichte | Methode | Pfad | Beschreibung | | ------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------- | | GET | `/v1/quotas/check` | Vorabprüfung des Kontingents für einen `provider` und eine `accountId`, bevor ein registrierter Schlüssel ausgestellt wird | | POST | `/v1/issues/report` | Meldet einen Fehler bei der Kontingent-/Schlüsselausstellung an GitHub (erfordert `GITHUB_ISSUES_REPO` und Token) | **Authentifizierung:** Bearer-API-Schlüssel (`isAuthenticated`). --- ## Self-Service-Nutzung (`/api/usage/om-usage`) Jeder API-Schlüssel kann seine **eigene** Nutzung und seine Kontingente abrufen — ohne Verwaltungsauthentifizierung. Dies ist der Endpunkt, über den ein Client (CLI, das OmniCopilot-Panel) einem Schlüsselinhaber seine Ausgaben anzeigt. ```bash # Textformat (der bisherige Vertrag — Klartext für ein Terminal) curl -H "Authorization: Bearer " \ http://localhost:20128/api/usage/om-usage # Strukturiertes Format — für die Nutzung durch eine Benutzeroberfläche curl -H "Authorization: Bearer " \ "http://localhost:20128/api/usage/om-usage?format=json" ``` Für den Schlüssel muss **`allowUsageCommand`** aktiviert sein (standardmäßig deaktiviert — der API-Schlüsselmanager des Dashboards schaltet dies für jeden Schlüssel einzeln um). Andernfalls antwortet der Endpunkt mit `403`. `?format=json` gibt eine diskriminierte Struktur zurück, sodass ein Aufrufer niemals ein Datenfeld aus einer Ablehnungsantwort liest. Bei Erfolg: ```jsonc { "allowed": true, // nur vorhanden, wenn für den Schlüssel schlüsselspezifische Nutzungslimits aktiviert wurden (täglich/wöchentlich in USD): "personal": { "dailySpentUsd": 1.25, "dailyLimitUsd": 5, "dailyResetAtIso": "…", "weeklySpentUsd": 8, "weeklyLimitUsd": 20, "weeklyResetAtIso": "…" /* … */, }, // die ausgewählte Momentaufnahme des Anbieterkontingents oder null, wenn noch nichts zwischengespeichert wurde: "provider": { "connectionId": "…", "provider": "claude", "plan": "…", "quotas": {/* … */}, }, // die Momentaufnahme jeder Verbindung, damit eine Benutzeroberfläche mehrere Anbieter nebeneinander darstellen kann: "providers": [ { "connectionId": "…", "provider": "claude" /* … */ }, { "provider": "codex" /* … */ }, ], } ``` Bei Ablehnung (`401` ungültiger Schlüssel / `403` nicht erlaubt) gibt dieselbe Route `{ "allowed": false, "error": { "message": "…" } }` zurück — ein vorhandenes, aber leeres `personal`/`provider` (Schlüssel zulässig, bisher keine Daten ermittelt) ist ein anderer Zustand als eine Ablehnung, und nur das JSON-Format unterscheidet diese Fälle. **Authentifizierung:** Der eigene Bearer-API-Schlüssel des Aufrufers, validiert mit `isValidApiKey` — dies ist _nicht_ die Verwaltungsoberfläche (`/api/keys/…`), die weiterhin durch `requireManagementAuth` geschützt ist. --- ## Semantischer Cache ```bash # Cache-Statistiken abrufen GET /api/cache/stats # Alle Caches leeren DELETE /api/cache/stats ``` Beispielantwort: ```json { "semanticCache": { "memorySize": 42, "memoryMaxSize": 500, "dbSize": 128, "hitRate": 0.65 }, "idempotency": { "activeKeys": 3, "windowMs": 5000 } } ``` ### Auswirkungen auf die Latenz Bei einem Treffer im semantischen Cache wird die Antwort **ohne Upstream-Aufruf** aus dem Cache bereitgestellt, sodass die gemeldete `X-OmniRoute-Response-Latency` nahezu null beträgt (unabhängig von der ursprünglichen Upstream-Latenz). Latenzempfindliche Clients (Benchmarking, p50-/p99-Monitoring) sollten den Antwort-Header `X-OmniRoute-Cache-Latency` prüfen: | Wert | Bedeutung | | ----------- | ------------------------------------------------------------------------------ | | `synthetic` | Antwort aus dem Cache bereitgestellt; die Latenz ist keine echte Upstream-Zeit | | _(fehlend)_ | Antwort aus einem echten Upstream-Aufruf | ### Cache-Umgehung pro Schlüssel API-Schlüssel können Cache-Lesevorgänge des semantischen Caches über `cacheDefaultMode` deaktivieren: | Wert | Verhalten | | -------- | ----------------------------------------------------------------- | | `legacy` | Normales Cache-Verhalten (Standard) | | `bypass` | Cache-Suche vollständig überspringen; immer den Upstream aufrufen | Bei der Schlüsselerstellung (`POST /api/keys`) festlegen oder per Aktualisierung (`PATCH /api/keys/[id]`) ändern: ```json { "cacheDefaultMode": "bypass" } ``` ### Umgehung pro Anfrage Jede Anfrage kann den Cache unabhängig von den Schlüsseleinstellungen umgehen: ``` X-OmniRoute-No-Cache: true ``` --- ## Dashboard & Verwaltung Verwaltungsrouten (`/api/*` außer öffentlicher Authentifizierung/Anmeldung) werden **nicht** durch gewöhnliche Inferenz-API-Schlüssel autorisiert. Anmeldeinformationstypen, Berechtigungsbereiche und curl-Beispiele: [Verwaltungsauthentifizierung](../guides/MANAGEMENT-AUTH.md). ### Authentifizierung | Endpunkt | Methode | Beschreibung | | ----------------------------- | ------- | ------------------------------- | | `/api/auth/login` | POST | Anmelden | | `/api/auth/logout` | POST | Abmelden | | `/api/settings/require-login` | GET/PUT | Anmeldepflicht ein-/ausschalten | ### Anbieterverwaltung | Endpunkt | Methode | Beschreibung | | ---------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `/api/providers` | GET/POST | Anbieter auflisten/erstellen | | `/api/providers/[id]` | GET/PUT/DELETE | Einen Anbieter verwalten | | `/api/providers/[id]/test` | POST | Anbieterverbindung testen | | `/api/providers/[id]/models` | GET | Anbietermodelle auflisten | | `/api/providers/validate` | POST | Anbieterkonfiguration validieren | | `/api/providers/bulk` | POST | API-Schlüssel für EINEN Anbieter gesammelt hinzufügen | | `/api/providers/import` | POST | Eine heterogene Anbieter-LISTE aus einer geparsten CSV-/JSON-Datei importieren (#6836); Teilergebnisse bei Fehlern pro Zeile | | `/api/provider-nodes*` | Verschiedene | Verwaltung von Anbieterknoten | | `/api/provider-models` | GET/POST/PATCH/DELETE | Benutzerdefinierte Modelle (hinzufügen, aktualisieren, ausblenden/einblenden, löschen) | ### OAuth-Abläufe | Endpunkt | Methode | Beschreibung | | -------------------------------- | ------------ | -------------------------- | | `/api/oauth/[provider]/[action]` | Verschiedene | Anbieterspezifisches OAuth | ### Routing & Konfiguration | Endpunkt | Methode | Beschreibung | | --------------------- | ------------ | ---------------------------------- | | `/api/models/alias` | GET/POST | Modellaliase | | `/api/models/catalog` | GET | Alle Modelle nach Anbieter und Typ | | `/api/combos*` | Verschiedene | Combo-Verwaltung | | `/api/keys*` | Verschiedene | API-Schlüsselverwaltung | | `/api/pricing` | GET | Modellpreise | ### Nutzung & Analysen | Endpunkt | Methode | Beschreibung | | -------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `/api/usage/history` | GET | Nutzungsverlauf | | `/api/usage/logs` | GET | Nutzungsprotokolle | | `/api/usage/request-logs` | GET | Protokolle auf Anfrageebene | | `/api/usage/[connectionId]` | GET | Nutzung pro Verbindung | | `/api/usage/token-limits` | GET/POST/DELETE | Tokenlimit-Budgets pro API-Schlüssel | | `/api/usage/model-latency-stats` | GET | Rollierendes Latenzaggregat pro Anbieter/Modell (Durchschnitt/p50/p95/p99, Erfolgsquote); Filter: `windowHours`/`minSamples`/`maxRows`/`provider`/`model` (#6873) | | `/api/usage/cache-health` | GET | Zusammenfassung des Prompt-Cache-Zustands über `call_logs` — Schreib-/Leseverhältnis, p50/p90/p99-Verteilung der Schreibgröße, Konzentration schreibintensiver Vorgänge, Aufschlüsselung pro Modell und eine Bewertung als `healthy`/`degraded`/`thrash`/`no-data`; Abfrageparameter `range` (`1h`\|`24h`\|`7d`\|`30d`, Standardwert `24h`) und optional `model` (#8827) | ### Einstellungen | Endpunkt | Methode | Beschreibung | | ------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `/api/settings` | GET/PUT/PATCH | Allgemeine Einstellungen | | `/api/settings/proxy` | GET/PUT | Netzwerk-Proxy-Konfiguration | | `/api/settings/proxy/test` | POST | Proxy-Verbindung testen | | `/api/settings/ip-filter` | GET/PUT | IP-Zulassungs-/Sperrliste | | `/api/settings/thinking-budget` | GET/PUT | Umschreibmodus für **Anfragen** mit Denk-/Reasoning-Budget (Durchleitung / automatisches Entfernen / benutzerdefiniert / adaptiv). Unabhängig von der Komprimierung. Siehe [THINKING_BUDGET.md](../guides/THINKING_BUDGET.md). | | `/api/settings/system-prompt` | GET/PUT | Globaler System-Prompt | | `/api/settings/compression` | GET/PUT | Globale Komprimierungskonfiguration | | `/api/settings/purge-request-history` | POST | Anfrageprotokollzeilen und lokale Aufrufprotokoll-Artefakte löschen | ### Kontext & Komprimierung | Endpoint | Methode | Beschreibung | | -------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------- | | `/api/compression/preview` | POST | Vorschau der Komprimierung off/lite/standard/aggressive/ultra/RTK/stacked | | `/api/compression/language-packs` | GET | Verfügbare Caveman-Sprachpakete auflisten | | `/api/compression/rules` | GET | Metadaten der Caveman-Regeln auflisten | | `/api/context/caveman/config` | GET/PUT | Alias für Caveman-spezifische Einstellungen | | `/api/context/rtk/config` | GET/PUT | RTK-spezifische Einstellungen einschließlich benutzerdefinierter Filter und Aufbewahrung der Rohausgabe | | `/api/context/rtk/filters` | GET | RTK-Filterkatalog und Diagnoseinformationen für benutzerdefinierte Filter | | `/api/context/rtk/test` | POST | RTK-Vorschau/-Test mit einer Textnutzlast ausführen | | `/api/context/rtk/raw-output/[id]` | GET | Aufbewahrte, bereinigte Rohausgabe anhand der Zeiger-ID lesen | | `/api/context/combos` | GET/POST | Komprimierungskombinationen auflisten/erstellen | | `/api/context/combos/[id]` | GET/PUT/DELETE | Details einer Komprimierungskombination abrufen/aktualisieren/löschen | | `/api/context/combos/[id]/assignments` | GET/PUT | Komprimierungskombinationen Routing-Kombinationen zuweisen | | `/api/context/analytics` | GET | Alias für Komprimierungsanalysen | ### Überwachung | Endpoint | Methode | Beschreibung | | ------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/sessions` | GET | Nachverfolgung aktiver Sitzungen | | `/api/rate-limits` | GET | Ratenbegrenzungen pro Konto | | `/api/monitoring/health` | GET | Integritätsprüfung und Anbieterübersicht (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`). Die Verwaltungsansicht enthält `credentialHealth`: Skalare aus dem Prüfungs-Cache, `failedConnections`, wenn `failed>0`, und `staleDbNonOkCount` (persistenter SQLite-`test_status`, nicht die Messgröße). Siehe [MONITORING_GUIDE.md](../ops/MONITORING_GUIDE.md#credentialhealth-probe-cache-vs-sqlite-test_status). | | `/api/cache/stats` | GET/DELETE | Cache-Statistiken abrufen / Cache leeren | | `/api/modality-bridge/stats` | GET | Im Arbeitsspeicher vorgehaltene `attempts`, Erfolge/`bridged`, Fehler, Cache-Treffer, `totalLatencyMs`, `latencySamples`, das auf Stichproben basierende `averageLatencyMs` und Zeitpunkt der letzten Nutzung (wird bei einem Neustart zurückgesetzt; Verwaltungsauthentifizierung) | | `/api/modality-bridge/video/runtime` | GET | Strikte Prüfung auf vertrauenswürdiges Loopback vor Verwaltungsauthentifizierung/-prüfung; bereinigte Angaben zur Verfügbarkeit und zu den Versionen von FFmpeg/ffprobe (no-store) | | `/api/modality-bridge/video/extract` | POST | Interner, authentifizierter Byte-Broker über vertrauenswürdiges Loopback; 50 MiB Eingabe, begrenzte Warteschlange/32 MiB Ausgabe, `503` bei Kapazitätsüberschreitung, `499` bei Verbindungsabbruch, `504` bei Fristüberschreitung; keine öffentliche Upload-API | ### Sicherung und Export/Import | Endpunkt | Methode | Beschreibung | | --------------------------- | ------- | ------------------------------------------------------- | | `/api/db-backups` | GET | Verfügbare Sicherungen auflisten | | `/api/db-backups` | PUT | Eine manuelle Sicherung erstellen | | `/api/db-backups` | POST | Aus einer bestimmten Sicherung wiederherstellen | | `/api/db-backups/export` | GET | Datenbank als .sqlite-Datei herunterladen | | `/api/db-backups/import` | POST | .sqlite-Datei hochladen, um die Datenbank zu ersetzen | | `/api/db-backups/exportAll` | GET | Vollständige Sicherung als .tar.gz-Archiv herunterladen | ### Cloud-Synchronisierung | Endpunkt | Methode | Beschreibung | | ---------------------- | ------------ | ------------------------------- | | `/api/sync/cloud` | Verschiedene | Cloud-Synchronisierungsvorgänge | | `/api/sync/initialize` | POST | Synchronisierung initialisieren | | `/api/cloud/*` | Verschiedene | Cloud-Verwaltung | ### Tunnel | Endpunkt | Methode | Beschreibung | | -------------------------- | ------- | ----------------------------------------------------------------------------------- | | `/api/tunnels/cloudflared` | GET | Installations-/Laufzeitstatus des Cloudflare Quick Tunnel für das Dashboard abrufen | | `/api/tunnels/cloudflared` | POST | Cloudflare Quick Tunnel aktivieren oder deaktivieren (`action=enable/disable`) | | `/api/tunnels/ngrok` | GET | Laufzeitstatus des ngrok Tunnel für das Dashboard abrufen | | `/api/tunnels/ngrok` | POST | ngrok Tunnel aktivieren oder deaktivieren (`action=enable/disable`) | ### CLI-Tools | Endpunkt | Methode | Beschreibung | | ---------------------------------- | ------- | ----------------------- | | `/api/cli-tools/claude-settings` | GET | Claude-CLI-Status | | `/api/cli-tools/codex-settings` | GET | Codex-CLI-Status | | `/api/cli-tools/droid-settings` | GET | Droid-CLI-Status | | `/api/cli-tools/openclaw-settings` | GET | OpenClaw-CLI-Status | | `/api/cli-tools/runtime/[toolId]` | GET | Generische CLI-Laufzeit | CLI-Antworten enthalten: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. ### ACP-Agenten | Endpunkt | Methode | Beschreibung | | ----------------- | ------- | ---------------------------------------------------------------------------- | | `/api/acp/agents` | GET | Alle erkannten Agenten (integriert + benutzerdefiniert) mit Status auflisten | | `/api/acp/agents` | POST | Benutzerdefinierten Agenten hinzufügen oder Erkennungs-Cache aktualisieren | | `/api/acp/agents` | DELETE | Benutzerdefinierten Agenten anhand des Abfrageparameters `id` entfernen | Die GET-Antwort enthält `agents[]` (id, name, binary, version, installed, protocol, isCustom) und `summary` (total, installed, notFound, builtIn, custom). ### Ausfallsicherheit & Ratenbegrenzungen | Endpunkt | Methode | Beschreibung | | --------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------- | | `/api/resilience` | GET/PATCH | Anfragewarteschlange, Verbindungs-Cooldown, Anbieter-Schutzschalter und Warteeinstellungen abrufen/aktualisieren | | `/api/resilience/reset` | POST | Anbieter-Schutzschalter zurücksetzen | | `/api/resilience/model-cooldowns` | GET | Aktive Sperren pro (Anbieter, Verbindung, Modell), sortiert nach verbleibender Zeit, auflisten | | `/api/resilience/model-cooldowns` | DELETE | Modellsperre aufheben — Body `{provider, model}` oder `{all: true}`, um alles zu löschen | | `/api/rate-limits` | GET | Ratenbegrenzungsstatus pro Konto | | `/api/rate-limit` | GET | Globale Ratenbegrenzungskonfiguration | > Alle vier `/api/resilience/*`-Routen erfordern eine **Verwaltungsauthentifizierung** (`requireManagementAuth`). Eine vollständige Aufschlüsselung von Anbieter-Schutzschalter, Verbindungs-Cooldown und Modellsperre finden Sie unter [Ausfallsicherheit (erweitert)](#resilience-extended). ### Evaluierungen | Endpunkt | Methode | Beschreibung | | ------------ | -------- | -------------------------------------------------------- | | `/api/evals` | GET/POST | Evaluierungssammlungen auflisten / Evaluierung ausführen | ### Richtlinien | Endpunkt | Methode | Beschreibung | | --------------- | --------------- | ----------------------------- | | `/api/policies` | GET/POST/DELETE | Routing-Richtlinien verwalten | ### Compliance | Endpunkt | Methode | Beschreibung | | --------------------------- | ------- | ------------------------------------ | | `/api/compliance/audit-log` | GET | Compliance-Auditprotokoll (letzte N) | ### v1beta (Gemini-kompatibel) | Endpunkt | Methode | Beschreibung | | -------------------------- | ------- | ---------------------------------- | | `/v1beta/models` | GET | Modelle im Gemini-Format auflisten | | `/v1beta/models/{...path}` | POST | Gemini-`generateContent`-Endpunkt | Diese Endpunkte spiegeln das API-Format von Gemini für Clients wider, die native Kompatibilität mit dem Gemini SDK erwarten. ### Interne / System-APIs | Endpunkt | Methode | Beschreibung | | ------------------------ | ------- | ------------------------------------------------------------------------ | | `/api/init` | GET | Prüfung der Anwendungsinitialisierung (wird beim ersten Start verwendet) | | `/api/tags` | GET | Ollama-kompatible Modell-Tags (für Ollama-Clients) | | `/api/restart` | POST | Geordneten Neustart des Servers auslösen | | `/api/shutdown` | POST | Geordnetes Herunterfahren des Servers auslösen | | `/api/system/env/repair` | POST | Umgebungsvariablen des OAuth-Anbieters reparieren | > **Hinweis:** Diese Endpunkte werden intern vom System oder zur Kompatibilität mit Ollama-Clients verwendet. Sie werden üblicherweise nicht von Endbenutzern aufgerufen. ### Reparatur der OAuth-Umgebung _(v3.6.1+)_ ```bash POST /api/system/env/repair Content-Type: application/json { "provider": "claude-code" } ``` Repariert fehlende oder beschädigte OAuth-Umgebungsvariablen für einen bestimmten Anbieter. Gibt Folgendes zurück: ```json { "success": true, "repaired": ["CLAUDE_CODE_OAUTH_CLIENT_ID", "CLAUDE_CODE_OAUTH_CLIENT_SECRET"], "backupPath": "/home/user/.omniroute/backups/env-repair-2026-04-11.bak" } ``` --- ## Audiotranskription ```bash POST /v1/audio/transcriptions Authorization: Bearer your-api-key Content-Type: multipart/form-data ``` Transkribieren Sie Audiodateien mit einem beliebigen konfigurierten STT-Anbieter. Das erste Pfadsegment wählt den nativen Anbieter aus (`openai/…`, `deepgram/…`). Gateways, die das Modell eines anderen Anbieters erneut bereitstellen, verwenden eine qualifizierte ID (`openrouter/deepgram/nova-3`). **Anfrage:** ```bash curl -X POST http://localhost:20128/v1/audio/transcriptions \ -H "Authorization: Bearer your-api-key" \ -F "file=@recording.mp3" \ -F "model=openai/whisper-1" ``` **Antwort:** ```json { "text": "Hallo, dies ist der transkribierte Audioinhalt.", "task": "transcribe", "language": "en", "duration": 12.5 } ``` **Beispiele für Modell-IDs:** `openai/whisper-1` (erfordert einen OpenAI-Schlüssel), `openrouter/deepgram/nova-3` (erfordert einen OpenRouter-Schlüssel), `deepgram/nova-3` (erfordert einen nativen Deepgram-Schlüssel). Eine einfache Anfrage an `deepgram/nova-3` verwendet **nicht** OpenRouter. **Unterstützte Formate:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. --- ## Ollama-Kompatibilität Für Clients, die das API-Format von Ollama verwenden: ```bash # Chat-Endpunkt (Ollama-Format) POST /v1/api/chat # Modellauflistung (Ollama-Format) GET /api/tags ``` Anfragen werden automatisch zwischen dem Ollama-Format und internen Formaten übersetzt. ## Tokenisierte VS-Code-Aliasse/Aliasse ohne Header Verwenden Sie diese Aliasse, wenn eine Integration keinen `Authorization`-Header einfügen kann und der API-Schlüssel in die Basis-URL eingebettet werden muss. ```bash # Katalog-Alias im OpenAI-Stil GET /api/v1/vscode/{token}/ GET /api/v1/vscode/{token}/models # Chat-Aliasse im OpenAI-Stil POST /api/v1/vscode/{token}/chat/completions POST /api/v1/vscode/{token}/responses # Aliasse im Ollama-Stil POST /api/v1/vscode/{token}/api/chat GET /api/v1/vscode/{token}/api/tags ``` Beispiel: ```bash curl https://your-host.example/api/v1/vscode/YOUR_API_KEY/models curl -X POST https://your-host.example/api/v1/vscode/YOUR_API_KEY/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"auto","messages":[{"role":"user","content":"Hallo"}]}' ``` Hinweise: - Die tokenisierten Aliasse verwenden dieselben Handler wie `/v1/*` und `/api/tags`; die Antwortstrukturen bleiben identisch. - Bevorzugen Sie `Authorization: Bearer ...`, wenn der Client benutzerdefinierte Header unterstützt. - URL-basierte Token können in Reverse-Proxy-Protokollen, im Browserverlauf und in Telemetriedaten außerhalb von OmniRoute erscheinen. Behandeln Sie sie als Kompatibilitätsoption und nicht als standardmäßigen Authentifizierungsmodus. --- ## Telemetrie ```bash # Zusammenfassung der Latenztelemetrie abrufen (p50/p95/p99 pro Anbieter) GET /api/telemetry/summary ``` **Antwort:** ```json { "providers": { "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } } } ``` --- ## Budget ```bash # Budgetstatus für alle API-Schlüssel abrufen GET /api/usage/budget # Ein Budget festlegen oder aktualisieren POST /api/usage/budget Content-Type: application/json { "apiKeyId": "key-123", "dailyLimitUsd": 5.00, "weeklyLimitUsd": 30.00, "monthlyLimitUsd": 100.00, "warningThreshold": 0.8, "resetInterval": "monthly" } ``` > **Schemahinweise** (`setBudgetSchema`): `apiKeyId` ist erforderlich; mindestens einer der Werte `dailyLimitUsd`, `weeklyLimitUsd` oder `monthlyLimitUsd` muss größer als null sein. Optionale Felder: `warningThreshold` (0–1), `resetInterval` (`daily` | `weekly` | `monthly`), `resetTime` (`HH:MM`). Das veraltete Format `{keyId, limit, period}` gibt `400 Bad Request` zurück. ## Token-Limits **Token**-Budgets pro API-Schlüssel (unabhängig vom oben genannten USD-basierten Budget). Sie werden direkt bei der Anfrageverarbeitung durchgesetzt: Wenn die Nutzung eines Schlüssels im aktuellen Zeitfenster sein Limit erreicht, werden Anfragen mit `429 Too Many Requests` abgelehnt. Limits können auf ein bestimmtes `model` oder einen bestimmten `provider` beschränkt oder `global` auf den gesamten Schlüssel angewendet werden. Wenn mehrere Limits auf eine Anfrage zutreffen, gilt das restriktivste. ```bash # Token-Limits eines Schlüssels auflisten (einschließlich der aktuellen Nutzung im Zeitfenster) GET /api/usage/token-limits?apiKeyId=key-123 # Ein Token-Limit erstellen oder aktualisieren POST /api/usage/token-limits Content-Type: application/json { "apiKeyId": "key-123", "scopeType": "model", "scopeValue": "openai/gpt-4o", "tokenLimit": 1000000, "resetInterval": "monthly", "enabled": true } # Ein Token-Limit anhand seiner ID löschen DELETE /api/usage/token-limits?id=tl-abc ``` > **Schemahinweise** (`setTokenLimitSchema`): `apiKeyId` und `scopeType` (`model` | `provider` | `global`) sind erforderlich. `scopeValue` ist erforderlich, sofern `scopeType` nicht `global` ist (z. B. eine Modell-ID für den Geltungsbereich `model` oder eine Anbieter-ID für den Geltungsbereich `provider`). `tokenLimit` muss eine positive Ganzzahl sein (wird aus einer Zeichenfolge konvertiert). Optional: `id` (zum Erstellen weglassen, zum Aktualisieren angeben), `resetInterval` (`daily` | `weekly` | `monthly`, Standardwert `monthly`), `resetTime` (`HH:MM`), `enabled` (Standardwert `true`). `GET`-Antworten ergänzen jedes Limit um `tokensUsed`, `remaining`, `windowStart`, `periodStartAt` und `nextResetAt`. Dies ist ein Verwaltungsendpunkt (die Authentifizierung wird zentral durch die AuthZ-Pipeline erzwungen). ## Anfrageverarbeitung 1. Der Client sendet eine Anfrage an `/v1/*` 2. Der Routen-Handler ruft `handleChat`, `handleEmbedding`, `handleAudioTranscription` oder `handleImageGeneration` auf 3. Das Modell wird aufgelöst (direkter Anbieter/direktes Modell oder Alias/Kombination) 4. Die Anmeldedaten werden aus der lokalen Datenbank unter Berücksichtigung der Kontoverfügbarkeit ausgewählt 5. Für Chat: `handleChatCore` prüft den semantischen/Signatur-Cache und löst die Komprimierungseinstellungen der Kombination auf 6. Die proaktive Komprimierung wird vor der Anbieterübersetzung ausgeführt, wenn sie aktiviert ist (`lite`, Caveman, RTK oder gestapelt) 7. Der Anbieter-Executor sendet die Anfrage an den Upstream-Dienst 8. Die Antwort wird zurück in das Clientformat übersetzt (Chat) oder unverändert zurückgegeben (Einbettungen/Bilder/Audio) 9. Nutzungsdaten, Komprimierungsanalysen und Anfrageprotokolle werden aufgezeichnet 10. Bei Fehlern erfolgt gemäß den Kombinationsregeln ein Fallback Vollständige Architekturreferenz: [`ARCHITECTURE.md`](../architecture/ARCHITECTURE.md) --- ## Kombinationsverwaltung Übergeordnete Routing-Kombinationen (bereits unter `/api/combos*` zusammengefasst) können außerdem 1:1 aus einem Modell-ID-Muster zugeordnet werden, wodurch eine OpenAI-kompatible Modell-ID transparent an eine Kombination weitergeleitet werden kann. | Methode | Pfad | Beschreibung | | ------- | -------------------------------- | ----------------------------------------------------------------------------------- | | GET | `/api/model-combo-mappings` | Alle Modell→Kombination-Zuordnungen auflisten | | POST | `/api/model-combo-mappings` | Zuordnung erstellen — Body: `{pattern, comboId, priority?, enabled?, description?}` | | GET | `/api/model-combo-mappings/[id]` | Eine einzelne Zuordnung abrufen | | PUT | `/api/model-combo-mappings/[id]` | Felder einer vorhandenen Zuordnung aktualisieren | | DELETE | `/api/model-combo-mappings/[id]` | Eine Zuordnung entfernen | **Authentifizierung:** Verwaltungssitzung/API-Schlüssel (`requireManagementAuth`). --- ## Webhooks Ausgehende Webhook-Abonnements für OmniRoute-Ereignisse (Abschluss von Anfragen, Ausschöpfung von Kontingenten, Schlüsselrotation usw.). | Methode | Pfad | Beschreibung | | ------- | ------------------------- | ------------------------------------------------------------------------------ | | GET | `/api/webhooks` | Webhooks auflisten (Secrets werden als `...` maskiert) | | POST | `/api/webhooks` | Webhook erstellen — Body: `{url, events?: ["*"], secret?, description?}` | | GET | `/api/webhooks/[id]` | Einen Webhook abrufen | | PUT | `/api/webhooks/[id]` | url/events/secret/description aktualisieren | | DELETE | `/api/webhooks/[id]` | Einen Webhook entfernen | | POST | `/api/webhooks/[id]/test` | Eine Test-Payload an die Webhook-URL senden und den Zustellungsstatus ausgeben | **Authentifizierung:** Verwaltungssitzung/API-Schlüssel (`requireManagementAuth`). --- ## Registrierte Schlüssel (automatische Verwaltung) Wird vom Subsystem zur automatischen Schlüsselverwaltung verwendet, um API-Schlüssel für einen zugrunde liegenden Anbieter bzw. ein zugrunde liegendes Konto auszustellen und zu rotieren, einschließlich täglicher und stündlicher Kontingente. | Methode | Pfad | Beschreibung | | ------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/registered-keys` | Registrierte Schlüssel auflisten (nur maskiertes Präfix) | | POST | `/api/v1/registered-keys` | Einen neuen registrierten Schlüssel ausstellen — Body: `{name, provider?, accountId?, idempotencyKey?, expiresAt?, dailyBudget?, hourlyBudget?}`. Gibt den unmaskierten Schlüssel **einmalig** zurück. Gibt bei Ablehnung aufgrund des Kontingents `429` zurück. | | GET | `/api/v1/registered-keys/[id]` | Metadaten eines registrierten Schlüssels abrufen (kein unmaskiertes Schlüsselmaterial) | | DELETE | `/api/v1/registered-keys/[id]` | Einen registrierten Schlüssel widerrufen | | POST | `/api/v1/registered-keys/[id]/revoke` | Expliziter Endpunkt zum Widerrufen (gleiche Wirkung wie DELETE) | **Authentifizierung:** Bearer-API-Schlüssel (`isAuthenticated`). Siehe auch `/v1/quotas/check` und `/v1/issues/report`. --- ## Agents-Protokoll Cloud-Agent-Aufgaben (Claude Code, Codex Cloud, OpenHands usw.), die im Auftrag von OmniRoute-Benutzern remote ausgeführt werden. | Methode | Pfad | Beschreibung | | ------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/v1/agents/tasks` | Aufgaben auflisten — optional `?provider=`, `?status=`, `?limit=` (1–500, Standardwert 50) | | POST | `/api/v1/agents/tasks` | Aufgabe erstellen — Body wird durch `CreateCloudAgentTaskSchema` validiert (`providerId`, `prompt`, `source`, `options?`). Gibt `201` mit Aufgaben-Envelope zurück | | DELETE | `/api/v1/agents/tasks?id=...` | Eine Aufgabe löschen | | GET | `/api/v1/agents/tasks/[id]` | Aufgabe abrufen — aktualisiert den Status synchron vom vorgelagerten Cloud-Agent, wenn eine `external_id` festgelegt ist | | POST | `/api/v1/agents/tasks/[id]` | Unterscheidbare Aktion: `{action: "approve"}`, `{action: "message", message}` oder `{action: "cancel"}` | | DELETE | `/api/v1/agents/tasks/[id]` | Eine bestimmte Aufgabe anhand ihrer ID löschen | > **Authentifizierung:** Für jede Methode ist eine Verwaltungsauthentifizierung erforderlich (`requireCloudAgentManagementAuth`). Vor v3.8.0 waren diese Methoden nicht authentifiziert — siehe Commit `588a0333` für die inkompatible Änderung. ```bash # Eine Claude-Code-Cloud-Aufgabe erstellen curl -X POST http://localhost:20128/api/v1/agents/tasks \ -H "Authorization: Bearer your-management-key" \ -H "Content-Type: application/json" \ -d '{"providerId":"claude-code-cloud","prompt":"Fix the failing test","source":{"repo":"...","branch":"..."}}' ``` --- ## Verwaltungs-Proxys Ausgehende HTTP(S)-/SOCKS-Proxys, die Anbietern, Konten oder global zugewiesen werden können. | Methode | Pfad | Beschreibung | | ------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/management/proxies` | Proxys auflisten (mit `?id=` wird ein Proxy zurückgegeben; mit `?id=&where_used=1` wird der Zuweisungsgraph zurückgegeben) | | POST | `/api/v1/management/proxies` | Proxy erstellen — Body wird durch `createProxyRegistrySchema` validiert | | PATCH | `/api/v1/management/proxies` | Proxy aktualisieren — Body wird durch `updateProxyRegistrySchema` validiert (`id` erforderlich) | | DELETE | `/api/v1/management/proxies?id=...&force=1` | Proxy löschen (`force=1` verwenden, um Zuweisungen zu lösen) | | GET | `/api/v1/management/proxies/assignments` | Zuweisungen auflisten — filterbar nach `proxy_id`, `scope`, `scope_id`; `resolve_connection_id=` übergeben, um den aktiven Proxy für eine Verbindung zu ermitteln | | PUT | `/api/v1/management/proxies/assignments` | Zuweisen — Body wird durch `proxyAssignmentSchema` validiert (`{scope, scopeId?, proxyId?}`). Leert den Dispatcher-Cache | | PUT | `/api/v1/management/proxies/bulk-assign` | Massenzuweisung — Body wird durch `bulkProxyAssignmentSchema` validiert (`{scope, scopeIds[], proxyId?}`) | | GET | `/api/v1/management/proxies/health?hours=24` | Aggregierter Proxy-Zustand (Anzahl erfolgreicher/fehlgeschlagener Anfragen, Latenz) über ein Zeitfenster | **Authentifizierung:** Verwaltungssitzung/API-Schlüssel für jede Route (`requireManagementAuth`). > Die in der Aufgabenbeschreibung genannten Routen `POST /api/v1/management/proxies/[id]/assignments` und `POST /api/v1/management/proxies/[id]/health` werden über die oben gezeigten flachen Routen `/assignments` und `/health` bereitgestellt — in der Codebasis gibt es keine ID-spezifischen Unterrouten. --- ## Resilienz (erweitert) OmniRoute stellt drei unabhängige Mechanismen für temporäre Fehler bereit; über die folgenden Verwaltungsendpunkte können Betreiber deren Status auslesen und sie überschreiben: | Geltungsbereich | Zustandsspeicher | Auslesen | Zurücksetzen / Löschen | | ----------------------- | ----------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------ | | Provider-Schutzschalter | `domain_circuit_breakers` + im Arbeitsspeicher | `/api/monitoring/health` | `POST /api/resilience/reset` | | Verbindungs-Cooldown | `rateLimitedUntil` für Provider-Verbindungen | `/api/rate-limits`, `/api/providers/[id]` | (wird verzögert wieder aktiviert; Löschen über Provider-PUT) | | Modellsperre | Modellverfügbarkeitsregister im Arbeitsspeicher | `GET /api/resilience/model-cooldowns` | `DELETE /api/resilience/model-cooldowns` | `PATCH /api/resilience` akzeptiert Überschreibungen für Provider-Schutzschalter unter `providerBreaker.oauth` und `providerBreaker.apikey`. Jedes Profil unterstützt `degradationThreshold`, `failureThreshold` und `resetTimeoutMs`; dieselben Felder sind unter Dashboard → Einstellungen → Resilienz verfügbar. ```bash # Eine einzelne Modellsperre löschen curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \ -H "Cookie: auth_token=..." \ -H "Content-Type: application/json" \ -d '{"provider":"openai","model":"gpt-4o-mini"}' # Alle Sperren löschen curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \ -H "Cookie: auth_token=..." \ -d '{"all":true}' ``` Die vollständige konzeptionelle Referenz und die Standardwerte für Schutzschalter finden Sie unter [`CLAUDE.md`](../../CLAUDE.md) → „Resilience Runtime State“. --- ## Skills Skill-Framework zur Erweiterung von OmniRoute um benutzerdefinierte ausführbare Handler sowie Marketplace-Integrationen. | Methode | Pfad | Beschreibung | | ------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/skills` | Installierte Skills auflisten — filterbar nach `?q=`, `?mode=on\|off\|auto`, `?source=skillsmp\|skillssh\|local`, paginiert | | GET | `/api/skills/[id]` | Einen einzelnen Skill abrufen | | PUT | `/api/skills/[id]` | Skill aktualisieren (Name, Beschreibung, Modus, Schema, Handler, Tags) | | DELETE | `/api/skills/[id]` | Einen Skill deinstallieren | | POST | `/api/skills/install` | Einen Skill aus einem Rohmanifest installieren — Body: `{name, version, description, schema:{input, output}, handlerCode, apiKeyId?}` | | GET | `/api/skills/executions` | Letzte Skill-Ausführungen auflisten (Audit-Trail mit Ein-/Ausgaben und Dauer) | | GET | `/api/skills/marketplace?q=...` | Suche/beliebte Liste aus dem SkillsMP-Marketplace (erfordert die Einstellung `skillsmpApiKey`) | | POST | `/api/skills/marketplace/install` | Einen Skill anhand seiner ID aus SkillsMP installieren | | GET | `/api/skills/skillssh?q=&limit=` | Die skills.sh-Registry durchsuchen | | POST | `/api/skills/skillssh/install` | Einen Skill anhand seiner ID aus skills.sh installieren | **Authentifizierung:** Verwaltungssitzung/API-Schlüssel. Marketplace-Suchrouten akzeptieren entweder die Verwaltungsauthentifizierung oder einen Bearer-API-Schlüssel (`isAuthenticated`). --- ## Speicher Persistenter Speicher für Konversationen und Fakten, dessen Gültigkeitsbereich auf API-Schlüssel/Sitzung beschränkt ist. | Methode | Pfad | Beschreibung | | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/memory` | Speicherinhalte auflisten — `?apiKeyId=`, `?type=`, `?sessionId=`, `?q=`, mit Paginierung über `offset/limit` oder `page/limit` | | POST | `/api/memory` | Speicherinhalt erstellen — durch Zod validierter Body: `{content, key, type?, sessionId?, apiKeyId?, metadata?, expiresAt?}` | | GET | `/api/memory/[id]` | Einen Speicherinhalt abrufen | | DELETE | `/api/memory/[id]` | Einen Speicherinhalt löschen | | GET | `/api/memory/health` | Zustand des Speichersubsystems (DB-Konnektivität, Embeddings-Backend, Status des Vektorindex) | **Authentifizierung:** Verwaltungssitzung/API-Schlüssel (`requireManagementAuth`). `type`-Enum: `FACTUAL`, `EPISODIC`, `SEMANTIC`, `PROCEDURAL` (siehe `MemoryType` in `src/lib/memory/types.ts`). --- ## MCP-Server OmniRoute enthält einen eingebetteten Model-Context-Protocol-Server mit 3 Transportarten (stdio, SSE, streamable-http) und Tools mit festgelegten Gültigkeitsbereichen. Die folgenden Dashboard-Endpunkte lesen Status-/Audit-Daten und leiten die HTTP-Transportarten weiter. | Methode | Pfad | Beschreibung | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------- | | GET | `/api/mcp/status` | Heartbeat, Transportart, Online-Status, letzter Aufruf, meistgenutzte Tools, Erfolgsquote der letzten 24 Stunden | | GET | `/api/mcp/tools` | Liste der MCP-Tools mit `name`, `description`, `scopes`, `phase`, `auditLevel`, `sourceEndpoints` | | GET | `/api/mcp/sse` | SSE-Stream für die SSE-Transportart öffnen (gibt `503` zurück, wenn MCP deaktiviert ist oder die Transportart nicht übereinstimmt) | | POST | `/api/mcp/sse` | JSON-RPC-Frame über die SSE-Transportart senden | | GET | `/api/mcp/stream` | SSE-Seite der Streamable-HTTP-Transportart öffnen (serverinitiierte Nachrichten) | | POST | `/api/mcp/stream` | JSON-RPC-Frame über die Streamable-HTTP-Transportart senden | | DELETE | `/api/mcp/stream` | Eine Streamable-HTTP-Sitzung beenden | | GET | `/api/mcp/audit` | Audit-Protokoll abfragen — `?limit=`, `?offset=`, `?tool=`, `?success=true | false`, `?apiKeyId=` | | GET | `/api/mcp/audit/stats` | Aggregierte Audit-Statistiken (Gesamtzahlen, Erfolgsquote, durchschnittliche Dauer, meistgenutzte Tools) | **Authentifizierung:** Die `sse`-/`stream`-Transportarten berücksichtigen die MCP-spezifische Authentifizierungsoberfläche (Bearer-API-Schlüssel mit `mcp`-Gültigkeitsbereich); die Routen `status`/`tools`/`audit*` können über das Dashboard gelesen werden (über den Zugriff auf den Dashboard-Host hinaus ist keine zusätzliche Authentifizierung erforderlich). > Beide HTTP-Transportarten werden durch `settings.mcpEnabled` und `settings.mcpTransport` gesteuert — bei einer nicht übereinstimmenden Transportart wird `400` zurückgegeben, bei deaktiviertem MCP wird `503` zurückgegeben. --- ## A2A-Server OmniRoute stellt einen A2A-Endpunkt (Agent-to-Agent) für JSON-RPC 2.0 sowie einen REST-Wrapper für Inspektions- und Dashboard-Zwecke bereit. ### JSON-RPC ```bash POST /a2a Authorization: Bearer your-api-key # optional, sofern OMNIROUTE_API_KEY nicht festgelegt ist Content-Type: application/json { "jsonrpc": "2.0", "id": 1, "method": "message/send", "params": { "skill": "smart-routing", "messages": [{"role": "user", "content": "Route this coding task"}] } } ``` Unterstützte Methoden (alle abhängig von `settings.a2aEnabled`): | Methode | Beschreibung | | ---------------- | --------------------------------------------------------------------- | | `message/send` | Synchrone Skill-Ausführung; gibt `{task, artifacts, metadata}` zurück | | `message/stream` | Streaming-SSE-Ausführung derselben Skill-Gruppe | | `tasks/get` | Ruft eine Aufgabe anhand der `taskId` ab | | `tasks/cancel` | Bricht eine Aufgabe anhand der `taskId` ab | Integrierte Skills: `smart-routing`, `quota-management`, `provider-discovery`, `cost-analysis`, `health-report`. ### Agent Card ```bash GET /.well-known/agent.json ``` Gibt die öffentliche A2A-Agent-Card zurück (Name, Beschreibung, Funktionen, Skill-Katalog, Authentifizierungsschema) — wird 1 Stunde lang öffentlich zwischengespeichert. Keine Authentifizierung erforderlich. ### REST-Hilfsendpunkte | Methode | Pfad | Beschreibung | | ------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/a2a/status` | A2A-Aktivierungsstatus + Aufgabenstatistiken + Zusammenfassung der zwischengespeicherten Agent-Card | | GET | `/api/a2a/tasks` | Listet Aufgaben auf — `?state=submitted\|working\|completed\|failed\|cancelled`, `?skill=`, `?limit=` (≤200), `?offset=` | | POST | `/api/a2a/tasks` | (Nicht als REST-Hilfsendpunkt implementiert — Erstellung über JSON-RPC `message/send`) | | GET | `/api/a2a/tasks/[id]` | Ruft eine einzelne Aufgabe ab | | POST | `/api/a2a/tasks/[id]/cancel` | Bricht eine Aufgabe ab | **Authentifizierung:** Die REST-Hilfsendpunkte werden ohne Verwaltungs-Authentifizierung ausgeführt (vom Dashboard lesbar); die JSON-RPC-Route `/a2a` verwendet Bearer `OMNIROUTE_API_KEY`, sofern konfiguriert. --- ## Cloud, Evals & Assess | Methode | Pfad | Beschreibung | | ------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------- | ----------------------------------- | | POST | `/api/cloud/auth` | Überprüft einen Bearer-Schlüssel und gibt maskierte Provider-Verbindungen sowie Modell-Aliasse für Cloud-Synchronisierungsclients zurück | | POST | `/api/cloud/credentials/update` | Aktualisiert verschlüsselte Zugangsdaten für einen Cloud-synchronisierten Provider | | POST | `/api/cloud/model/resolve` | Löst eine logische Modell-ID mithilfe der lokalen Routing-Tabelle in einen konkreten Provider/ein konkretes Modell auf | | GET | `/api/cloud/models/alias` | Listet Modell-Aliasse auf, wie sie für die Cloud-Synchronisierung bereitgestellt werden | | GET | `/api/assess` | Liest die neuesten Bewertungskategorisierungen (pro Provider/Modell) | | POST | `/api/assess` | Führt eine Bewertung aus — Body: `{scope: {type:"all"} | {type:"provider", providerId} | {type:"model", modelId}, trigger?}` | | GET | `/api/evals` | Listet integrierte Eval-Suites und die neuesten Ausführungen auf | | POST | `/api/evals` | Startet eine Eval-Ausführung | | POST | `/api/evals/suites` | Erstellt eine benutzerdefinierte Eval-Suite — Body wird durch `evalSuiteSaveSchema` validiert | | GET | `/api/evals/suites/[id]` | Ruft eine benutzerdefinierte Eval-Suite ab | **Authentifizierung:** `/api/cloud/auth` validiert einen Bearer-Schlüssel direkt; die anderen Routen unter `/api/cloud/*`, `/api/evals/*` und `/api/assess` erfordern eine Verwaltungssitzung/einen API-Schlüssel. POST auf `/api/assess` verwendet `validateBody` mit einem Scope-Schema vom Typ „Discriminated Union“. --- ## ACP-Verwaltung (Agent Client Protocol) als untergeordnete Prozesse. Diese Endpunkte verwalten die Erkennung von ACP-Agenten und die Registrierung benutzerdefinierter Agenten. | Methode | Pfad | Beschreibung | | ------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/acp/agents` | Listet alle bekannten CLI-Agenten (integrierte und benutzerdefinierte) mit Installationsstatus, Version und Binärdatei auf | | POST | `/api/acp/agents` | Registriert einen benutzerdefinierten ACP-Agenten oder aktualisiert den Cache — Body: `{id, name, binary, versionCommand, providerAlias, spawnArgs, protocol}` oder `{action: "refresh"}` | | DELETE | `/api/acp/agents` | Entfernt einen benutzerdefinierten ACP-Agenten — Abfrageparameter: `?id=` | **Antwortbeispiel** (`GET /api/acp/agents`): ```json { "agents": [ { "id": "claude", "name": "Claude Code CLI", "binary": "claude", "version": "1.0.45", "installed": true, "protocol": "stdio", "providerAlias": "claude", "isCustom": false }, { "id": "my-custom-cli", "name": "My Custom CLI", "installed": false, "protocol": "stdio", "providerAlias": "my-provider", "isCustom": true } ], "cacheTtlMs": 60000, "cacheAge": 1234 } ``` **Authentifizierung:** Erfordert eine Verwaltungssitzung (`auth_token`-Cookie des Dashboards) oder einen API-Schlüssel mit Verwaltungsberechtigung. Vollständige Details finden Sie unter [ACP-Framework](../frameworks/ACP.md). --- ## Analysen und Beobachtbarkeit Echtzeit-Analyseendpunkte zur Überwachung von Routing, Komprimierung und Anbietervielfalt. Sie bilden die Grundlage für die Seiten unter `/dashboard/analytics/*`. ### Analysen zum automatischen Routing | Methode | Pfad | Beschreibung | | ------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/auto-routing` | Aggregierte Statistiken zum automatischen Routing: Gesamtzahl der Aufrufe, Strategie- und Stufenverteilung sowie führende Anbieter | | GET | `/api/analytics/auto-routing?days=7` | Statistiken für ein Zeitfenster (standardmäßig 24 Stunden) | **Antwortbeispiel**: ```json { "window": "24h", "totalCalls": 1234, "strategyBreakdown": { "rules": 800, "cost": 200, "latency": 150, "sla-aware": 50, "lkgp": 34 }, "tierBreakdown": { "ultra": 100, "pro": 500, "standard": 400, "free": 234 }, "topProviders": [ { "provider": "openai", "calls": 500, "avgLatencyMs": 850 }, { "provider": "anthropic", "calls": 300, "avgLatencyMs": 1200 } ] } ``` ### Komprimierungsanalysen | Methode | Pfad | Beschreibung | | ------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/compression` | Aggregierte Komprimierungsstatistiken: eingesparte Tokens, Einsparungen in %, Modusverteilung und Engine-Nutzung | **Antwortbeispiel**: ```json { "window": "24h", "totalOriginalTokens": 5000000, "totalCompressedTokens": 3500000, "totalSavings": 1500000, "savingsPct": 30.0, "modeBreakdown": { "lite": 400, "standard": 600, "aggressive": 100, "ultra": 50, "rtk": 84 }, "engineBreakdown": { "caveman": 800, "rtk": 434 } } ``` ### Erfassung der Anbietervielfalt | Methode | Pfad | Beschreibung | | ------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/diversity` | Auf Shannon-Entropie basierende Erfassung der Vielfalt: Verhindert einzelne Ausfallpunkte durch Messung der Verteilung auf Anbieter | **Antwortbeispiel**: ```json { "window": "24h", "shannonEntropy": 2.45, "maxEntropy": 3.17, "diversityRatio": 0.77, "providerUsage": { "openai": 0.4, "anthropic": 0.25, "google": 0.2, "kiro": 0.15 }, "warnings": ["OpenAI accounts for 40% of traffic — consider diversifying"] } ``` **Authentifizierung:** Erfordert eine Verwaltungssitzung oder einen API-Schlüssel mit Verwaltungsberechtigung. --- ## Administratorvorgänge Nur Administratoren vorbehaltene Endpunkte für die betriebliche Verwaltung. | Methode | Pfad | Beschreibung | | ------- | ------------------------ | --------------------------------------------------------------------------------------------------- | | GET | `/api/admin/concurrency` | Aktuelle Parallelitätslimits abrufen (global + pro Anbieter) | | POST | `/api/admin/concurrency` | Parallelitätslimits aktualisieren — Body: `{global?: number, perProvider?: Record}` | **Authentifizierung:** Erfordert eine Verwaltungssitzung mit Administratorberechtigung. --- ## Verwaltung von CLI-Tools Verwalten Sie CLI-Tools, die in OmniRoute integriert sind (antigravity, chipotle, commandCode, devin-cli usw.). Die vollständige Liste finden Sie in der [Anbieterreferenz](./PROVIDER_REFERENCE.md). | Methode | Pfad | Beschreibung | | ------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/cli-tools/all-statuses` | Status aller CLI-Tools (installiert, Version, zuletzt gesehen) | | GET | `/api/cli-tools/status` | Statusdetails für ein einzelnes CLI-Tool (`?tool=`-Abfrage) | | POST | `/api/cli-tools/apply` | Generierte Konfiguration eines Tools schreiben (`dryRun` zeigt eine Vorschau an; `422` + `containerEphemeralTarget` bei Containerbetrieb; `migration` weist auf eine veraltete Codex-YAML-Datei hin) | | GET | `/api/cli-tools/backups` | Sicherungen der CLI-Tool-Konfigurationen auflisten | | POST | `/api/cli-tools/backups` | Eine Sicherung aller CLI-Tool-Konfigurationen erstellen | | POST | `/api/cli-tools/backups` | Wiederherstellen: Derselbe Endpunkt stellt mit `{tool, backupId}` im Body diese Sicherung wieder her | | GET | `/api/cli-tools/antigravity-mitm` | Status des Antigravity-MITM-Proxys (das CLI-Tool „antigravity-mitm“) | | POST | `/api/cli-tools/antigravity-mitm/alias` | Aliasse für antigravity-mitm konfigurieren | **Authentifizierung:** Erfordert eine Verwaltungssitzung. --- ## Agentenfähigkeiten Verwalten Sie Fähigkeiten für KI-Agenten (ähnlich den benutzerdefinierten GPTs von OpenAI, jedoch für Agenten). | Methode | Pfad | Beschreibung | | ------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------- | | GET | `/api/agent-skills` | Alle Agentenfähigkeiten auflisten (integrierte + benutzerdefinierte) | | GET | `/api/agent-skills/[id]` | Eine bestimmte Agentenfähigkeit abrufen | | POST | `/api/agent-skills` | Eine benutzerdefinierte Agentenfähigkeit erstellen — Body: `{name, description, prompt, model?, temperature?}` | | PUT | `/api/agent-skills/[id]` | Eine benutzerdefinierte Agentenfähigkeit aktualisieren | | DELETE | `/api/agent-skills/[id]` | Eine benutzerdefinierte Agentenfähigkeit löschen | | GET | `/api/agent-skills/[id]/raw` | Unverarbeitete Eingabeaufforderung + Metadaten abrufen (keine Ausführung) | | POST | `/api/agent-skills/generate` | Mithilfe von KI eine neue Fähigkeit aus einer natürlichsprachlichen Beschreibung generieren | **Authentifizierung:** Erfordert eine Verwaltungssitzung oder einen API-Schlüssel mit Verwaltungsberechtigung. --- ## Cache-Verwaltung Verwalten Sie den semantischen Cache und den Reasoning-Cache. | Methode | Pfad | Beschreibung | | ------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------- | | GET | `/api/cache` | Cache-Übersicht: Gesamtzahl der Einträge, Trefferquote, Größe auf dem Datenträger | | GET | `/api/cache/entries` | Zwischengespeicherte Einträge auflisten (mit Paginierung) | | DELETE | `/api/cache/entries` | Cache-Einträge löschen (Filterung nach Abfrageparametern) | | GET | `/api/cache/stats` | Detaillierte Cache-Statistiken (pro Anbieter, pro Modell) | | GET | `/api/cache/reasoning` | Status des Reasoning-Caches (für die Wiedergabe von Schlussfolgerungen) | | DELETE | `/api/cache/reasoning` | Reasoning-Cache leeren — Abfrageparameter: `?toolCallId=` (einzeln), `?provider=

` oder keine Parameter (alle) | **Authentifizierung:** Erfordert eine Verwaltungssitzung. --- ## Speichersystem Verwalten Sie den persistenten Speicher (FTS5 + Vektoreinbettungen). | Methode | Pfad | Beschreibung | | ------- | ------------------ | -------------------------------------------------------------------------------------- | | GET | `/api/memory` | Speichereinträge auflisten (nach Geltungsbereich, Typ und Suchabfrage filtern) | | POST | `/api/memory` | Neuen Speichereintrag erstellen — Inhalt: `{scope, type, content, metadata?}` | | GET | `/api/memory/[id]` | Einen bestimmten Speichereintrag abrufen | | PUT | `/api/memory/[id]` | Einen Speichereintrag aktualisieren | | DELETE | `/api/memory/[id]` | Einen Speichereintrag löschen | | GET | `/api/memory?q=` | Speicher durchsuchen (FTS5 + Vektor) — Statistiken sind in derselben Antwort enthalten | **Authentifizierung:** Erfordert eine Verwaltungssitzung oder einen API-Schlüssel mit Verwaltungsberechtigung. --- ## Webhooks Verwalten Sie Webhook-Abonnements für Ereignisse. | Methode | Pfad | Beschreibung | | ------- | ------------------------------- | -------------------------------------------------------------------------- | | GET | `/api/webhooks` | Alle Webhook-Abonnements auflisten | | POST | `/api/webhooks` | Webhook-Abonnement erstellen — Inhalt: `{url, events[], secret?, active?}` | | GET | `/api/webhooks/[id]` | Ein bestimmtes Webhook-Abonnement abrufen | | PUT | `/api/webhooks/[id]` | Ein Webhook-Abonnement aktualisieren | | DELETE | `/api/webhooks/[id]` | Ein Webhook-Abonnement löschen | | GET | `/api/webhooks/[id]/deliveries` | Zustellungsverlauf für einen Webhook auflisten (Erfolgs-/Fehlerprotokoll) | | POST | `/api/webhooks/[id]/test` | Ein Testereignis an einen Webhook senden | **Authentifizierung:** Erfordert eine Verwaltungssitzung. Die vollständige Liste der Ereignistypen finden Sie unter [Webhooks-Framework](../frameworks/WEBHOOKS.md). --- ## Skills-Framework Skills (das Framework für agentenbasierte Erweiterungen) verwalten. | Methode | Pfad | Beschreibung | | ------- | ------------------------ | ------------------------------------------------------------------------------------------------------ | | GET | `/api/skills` | Alle installierten Skills auflisten (integriert + benutzerdefiniert) | | POST | `/api/skills/install` | Einen Skill von einem lokalen Pfad oder einer URL installieren | | DELETE | `/api/skills/[id]` | Einen Skill deinstallieren | | PUT | `/api/skills/[id]` | Einen Skill aktivieren oder deaktivieren — Body: `{enabled?: boolean, mode?: "on" \| "off" \| "auto"}` | | POST | `/api/skills/executions` | Einen Skill ausführen — Body: `{skillName, apiKeyId, input?, sessionId?}` | | GET | `/api/skills/executions` | Ausführungsverlauf für alle Skills auflisten (nach `?apiKeyId=` filtern) | **Authentifizierung:** Erfordert eine Verwaltungssitzung oder einen API-Schlüssel mit Verwaltungsberechtigung. Vollständige Details finden Sie unter [Skills-Framework](../frameworks/SKILLS.md). --- ## Plugins OmniRoute-Plugins (Erweiterungen von Drittanbietern) verwalten. | Methode | Pfad | Beschreibung | | ------- | ---------------------------------- | ------------------------------------------- | | GET | `/api/plugins` | Installierte Plugins auflisten | | POST | `/api/plugins/marketplace/install` | Ein Plugin aus dem Marketplace installieren | | DELETE | `/api/plugins/[name]` | Ein Plugin deinstallieren | | POST | `/api/plugins/[name]/activate` | Ein Plugin aktivieren | | POST | `/api/plugins/[name]/deactivate` | Ein Plugin deaktivieren | | GET | `/api/plugins/[name]/config` | Plugin-Konfiguration abrufen | | PUT | `/api/plugins/[name]/config` | Plugin-Konfiguration aktualisieren | **Authentifizierung:** Erfordert eine Verwaltungssitzung. Vollständige Details finden Sie unter [Plugins-Framework](../frameworks/PLUGIN_SDK.md). --- ## Shadow-Routing Der Shadow-/A-B-Vergleich von Anbietern ist **keine eigenständige REST-Schnittstelle** — er wird über Combo-Routing konfiguriert (siehe [Auto-Combo](../routing/AUTO-COMBO.md)). Vergleichsmetriken für einzelne Combos werden über `GET /api/combos/metrics` bereitgestellt. --- ## Guardrails Laufzeit-Guardrails überprüfen (PII-Erkennung, Erkennung von Prompt-Injection, Vision-Bridging). Guardrails werden bei jeder Anfrage ausgeführt; die Deaktivierung pro Aufruf erfolgt über den Anfrage-Header `x-omniroute-disabled-guardrails` — es gibt keine persistente Schnittstelle zum Aktivieren oder Deaktivieren. | Methode | Pfad | Beschreibung | | ------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | | GET | `/api/guardrails` | Registrierte Guardrails und ihren Status auflisten (Name / aktiviert / Priorität) | | POST | `/api/guardrails/test` | Die Pipeline vor dem Aufruf mit einer Beispieleingabe testweise ausführen — Body: `{input, disabledGuardrails?}` | **Authentifizierung:** Erfordert eine Verwaltungssitzung. Vollständige Details finden Sie unter [Sicherheit > Guardrails](../security/GUARDRAILS.md). --- --- ## Authentifizierung Siehe [Management-Authentifizierung](../guides/MANAGEMENT-AUTH.md) für die vier Anmeldedatenfamilien (Dashboard-Sitzung, lokales CLI-Token, `oma_live_…`-Zugriffs-Token, API-Schlüssel mit Management-Berechtigung) und ihre Unterschiede zu Inferenzschlüsseln. - Dashboard-Routen (`/dashboard/*`) verwenden das Cookie `auth_token` - Die Anmeldung verwendet den gespeicherten Passwort-Hash; als Fallback dient `INITIAL_PASSWORD` - `requireLogin` kann über `/api/settings/require-login` umgeschaltet werden - `/v1/*`-Routen erfordern optional einen Bearer-API-Schlüssel, wenn `REQUIRE_API_KEY=true` gilt - „Management-Token“ / „API-Schlüssel mit Management-Berechtigung“ bezeichnet in dieser Referenz eine der Familien aus diesem Leitfaden – keinen nicht definierten zusätzlichen Geheimnistyp > **Inkompatible Änderung (v3.8.0)** — `/api/v1/agents/tasks/*` und die Endpunkte zur Cooldown-Verwaltung erfordern jetzt eine **Management-Authentifizierung** (Dashboard-Cookie `auth_token` oder einen API-Schlüssel mit Management-Berechtigung). Clients, die diese Routen bisher ohne Authentifizierung aufgerufen haben, erhalten `401 Unauthorized`. Siehe Commit `588a0333` (`fix(auth): require management auth for agent and cooldown APIs`).