# API Reference (Bahasa Indonesia) 🌐 **Languages:** 🇺🇸 [English](../../../../reference/API_REFERENCE.md) · 🇪🇹 [am](../../../am/docs/reference/API_REFERENCE.md) · 🇸🇦 [ar](../../../ar/docs/reference/API_REFERENCE.md) · 🇦🇿 [az](../../../az/docs/reference/API_REFERENCE.md) · 🇧🇬 [bg](../../../bg/docs/reference/API_REFERENCE.md) · 🇧🇩 [bn](../../../bn/docs/reference/API_REFERENCE.md) · 🇨🇿 [cs](../../../cs/docs/reference/API_REFERENCE.md) · 🇩🇰 [da](../../../da/docs/reference/API_REFERENCE.md) · 🇩🇪 [de](../../../de/docs/reference/API_REFERENCE.md) · 🇬🇷 [el](../../../el/docs/reference/API_REFERENCE.md) · 🇪🇸 [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) · 🇳🇬 [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) --- 🌐 **Bahasa:** 🇺🇸 [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) Referensi inti untuk API OmniRoute. Dokumen ini mencakup antarmuka publik `/v1` dan endpoint pengelolaan yang paling sering digunakan; [`docs/openapi.yaml`](../openapi.yaml) yang dapat dibaca mesin dan struktur rute di bawah `src/app/api/` merupakan sumber yang lengkap. --- ## Daftar Isi - [Penyelesaian Chat](#chat-completions) - [Lease Sesi Terkelola Eksklusif](#exclusive-managed-session-leases) - [Embedding](#embeddings) - [Pembuatan Gambar](#image-generation) - [OCR Dokumen](#document-ocr) - [Daftar Model](#list-models) - [Manifes Plugin Penyedia](#provider-plugin-manifest) - [Endpoint Kompatibilitas](#compatibility-endpoints) - [API File](#files-api) - [API Batch](#batches-api) - [API Pencarian](#search-api) - [Streaming WebSocket](#websocket-streaming) - [Pelaporan Kuota & Masalah](#quotas--issues-reporting) - [Cache Semantik](#semantic-cache) - [Dasbor & Pengelolaan](#dashboard--management) - [Pengelolaan Combo](#combo-management) - [Webhook](#webhooks) - [Kunci Terdaftar (Pengelolaan Otomatis)](#registered-keys-auto-management) - [Protokol Agen](#agents-protocol) - [Proksi Pengelolaan](#management-proxies) - [Ketahanan (diperluas)](#resilience-extended) - [Keterampilan](#skills) - [Memori](#memory) - [Server MCP](#mcp-server) - [Server A2A](#a2a-server) - [Cloud, Evaluasi & Penilaian](#cloud-evals--assess) - [Pemrosesan Permintaan](#request-processing) - [Autentikasi](#authentication) --- ## Penyelesaian Chat ```bash POST /v1/chat/completions Authorization: Bearer your-api-key Content-Type: application/json { "model": "cc/claude-opus-4-6", "messages": [ {"role": "user", "content": "Write a function to..."} ], "stream": true } ``` ### Header Khusus | Header | Arah | Deskripsi | | ------------------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `X-OmniRoute-No-Cache` | Permintaan | Atur ke `true` untuk melewati cache | | `x-omniroute-no-memory` | Permintaan | Atur ke `true` untuk melewati injeksi memori + keterampilan bagi permintaan ini (mencerminkan no-cache; menghindari overhead token/biaya per panggilan) | | `X-OmniRoute-Progress` | Permintaan | Atur ke `true` untuk mendapatkan peristiwa progres | | `X-Session-Id` | Permintaan | Kunci sesi tetap untuk afinitas sesi eksternal | | `x_session_id` | Permintaan | Varian dengan garis bawah juga diterima (HTTP langsung) | | `X-OmniRoute-Session-Id` | Permintaan | Tag sesi/percakapan yang disediakan pemanggil (juga diteruskan ke memori). Jika ada, disimpan apa adanya ke `call_logs.session_tag` untuk atribusi biaya per sesi (#8249) — tidak pernah dibuat saat tidak ada | | `Idempotency-Key` | Permintaan | Kunci deduplikasi (jendela 5 detik) | | `X-Request-Id` | Permintaan | Kunci deduplikasi alternatif | | `X-OmniRoute-Cache` | Respons | `HIT` atau `MISS` (non-streaming) | | `X-OmniRoute-Idempotent` | Respons | `true` jika dideduplikasi | | `X-OmniRoute-Progress` | Respons | `enabled` jika pelacakan progres aktif | | `X-OmniRoute-Session-Id` | Respons | ID sesi efektif yang digunakan oleh OmniRoute | | `X-OmniRoute-Request-Id` | Respons | ID korelasi permintaan (jika diketahui) | | `X-OmniRoute-Version` | Respons | Versi build OmniRoute (selalu ada) | | `X-OmniRoute-Cost-Saved` | Respons | Jumlah USD yang dihemat cache pada `HIT` (khusus cache hit) | | `X-OmniRoute-Decision` | Respons | Jejak perutean: `strategy=; provider=; latency_ms=` (`` adalah strategi combo, atau `single` untuk permintaan non-combo) — selalu ada pada respons penyelesaian | > Catatan Nginx: jika Anda mengandalkan header dengan garis bawah (misalnya `x_session_id`), aktifkan `underscores_in_headers on;`. > **Header telemetri biaya:** respons berhasil non-streaming juga menyertakan kumpulan telemetri biaya `X-OmniRoute-*` — `X-OmniRoute-Response-Cost` (USD, tetap 10 angka desimal; `0.0000000000` untuk yang gratis/tanpa harga), `X-OmniRoute-Tokens-In` / `X-OmniRoute-Tokens-Out`, `X-OmniRoute-Model`, `X-OmniRoute-Provider`, `X-OmniRoute-Latency-Ms`, `X-OmniRoute-Cache-Hit`, dan `X-OmniRoute-Fallback-Attempts` (hanya ketika > 0), ditambah `X-OmniRoute-Request-Id` dan `X-OmniRoute-Version`. Header-header ini disertakan oleh chat completions, `/v1/responses`, `/v1/messages`, **serta endpoint media** — `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/speech`, `/v1/audio/transcriptions`, `/v1/rerank`, `/v1/videos/generations`, `/v1/music/generations`, dan `/v1/moderations` (biayanya selalu `0`). Biaya media dihitung per modalitas (per gambar, per detik, per karakter, per unit pencarian) ketika informasi harga tersedia; jika tidak, biayanya `0` (fail-open). > **Semantik biaya cache hit:** pada HIT cache semantik (`X-OmniRoute-Cache-Hit: true`), tidak ada panggilan upstream yang dilakukan, sehingga `X-OmniRoute-Response-Cost` adalah `0.0000000000` (biaya **inkremental** untuk menyajikan hit tersebut). Biaya asli/yang seharusnya terjadi dilaporkan secara terpisah dalam `X-OmniRoute-Cost-Saved`. Konsumen data penagihan harus menjumlahkan `X-OmniRoute-Response-Cost` (hit tidak dikenai biaya); analitik cache dapat mengagregasikan `X-OmniRoute-Cost-Saved`. ## Lease Sesi Terkelola Eksklusif Penyewaan sesi terkelola eksklusif adalah kontrak perutean yang bersifat opsional dan netral terhadap klien: satu pemilik aktif memegang satu koneksi OmniRoute yang memenuhi syarat. Kontrak ini tidak menyewakan model, mewajibkan OAuth, mengidentifikasi klien tertentu, atau mewajibkan penyedia tertentu. Kunci API yang digunakan untuk autentikasi harus memiliki cakupan `lease:exclusive` dan daftar `allowedConnections` eksplisit yang tidak kosong. Batas mutasi basis data memberlakukan kedua bidang tersebut secara bersamaan saat pembuatan kunci dan pembaruan parsial. ```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"} ``` Respons perolehan, perpanjangan, dan pelepasan yang berhasil menampilkan stempel waktu, `state`, dan `generation` positif yang tepat, tetapi tidak pernah menampilkan koneksi atau kredensial yang dipilih. Perpanjangan dan pelepasan menyertakan generasi dalam isi JSON: ```json { "action": "renew", "generation": 1 } ``` ```json { "action": "release", "generation": 1, "reason": "OWNER_EXIT" } ``` Pemilik lease aktif dapat secara eksplisit meminta metadata tampilan yang aman bagi privasi untuk pengikatannya saat ini: ```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" } } ``` Tindakan status opsional ini dibatasi oleh pemilik opak, kunci API terkelola yang diautentikasi, dan generasi aktif yang tepat dalam satu transaksi basis data. `displayName` hanya merupakan nama koneksi terkonfigurasi yang telah dipangkas; nilainya `null` ketika tidak ada nama terkonfigurasi yang aman. OmniRoute tidak pernah menggantinya dengan email atau identitas akun yang dihasilkan. Nilai penyedia adalah label tampilan non-sensitif dan tidak pernah berupa pengidentifikasi penyedia kompatibel yang dihasilkan. Kredensial, token, cookie, ID mentah koneksi atau kunci API, hash pemilik, rahasia pembatas, dan data perutean internal tidak disertakan. Pencarian dengan kunci yang salah, pemilik yang salah, generasi kedaluwarsa, data yang hilang, lease yang habis masa berlaku, dilepas, atau dibatalkan semuanya mengembalikan kesalahan `409 LEASE_FENCE_STALE` yang sama tanpa metadata koneksi. Klien yang menerima respons tunggu kapasitas tidak memiliki pengikatan aktif untuk diperiksa. Ketika perutean mengalihkan lease aktif, generasi yang sama tetap valid dan status secara atomik mengembalikan pengikatan baru, bukan yang lama. Klien yang sudah ada tetap tidak berubah karena respons perolehan, perpanjangan, pelepasan, dan penantian mempertahankan bentuk sebelumnya. Kontrak server ini tidak mengubah `/status` OpenAI Codex standar. Codex standar saat ini melaporkan penyedia model serta status autentikasi/akun bawaannya, tetapi tidak merender metadata akun penyedia kustom arbitrer; integrasi klien mendatang harus memanggil tindakan ini dan menentukan cara menampilkan `connection.displayName`. Setiap permintaan inferensi terkelola kemudian menyertakan kedua header kontrol: ```http X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> X-OmniRoute-Lease-Generation: 1 ``` Pemilik, generasi, koneksi aktif, dan kunci API terautentikasi yang tepat dibatasi tepat sebelum setiap upaya upstream yang didukung. Memutar ulang pemilik dan generasi dengan kunci lain akan gagal bahkan ketika kunci tersebut mengizinkan koneksi yang sama. Pemilik mentah tidak dipersistenkan, dicatat dalam log, dipertahankan dalam snapshot permintaan, atau diteruskan ke upstream. Kontensi sementara mengembalikan HTTP `429` dengan `Retry-After` dan: ```json { "state": "WAITING_FOR_CAPACITY", "error": { "type": "lease_error", "code": "LEASE_CAPACITY_UNAVAILABLE" }, "reason": "NO_FREE_ELIGIBLE_CONNECTION", "retryAfter": 30 } ``` Respons ini hanya berarti bahwa himpunan koneksi biasa yang memenuhi syarat tidak kosong dan setiap kandidat bebas sedang dipegang oleh lease aktif milik pihak lain. Model/penyedia yang tidak didukung, ketidakcocokan kebijakan, cooldown, kuota, kesehatan, dan kegagalan kelayakan biasa lainnya tetap menggunakan respons OmniRoute yang sudah ada. ### `x-omniroute-compression` Penggantian paket kompresi per permintaan. Memiliki prioritas tertinggi — mengalahkan penggantian kombo perutean, profil aktif, pemicu otomatis, dan Default panel. Nilai: | Nilai | Efek | | ------------- | ------------------------------------------------------------------------------------------------------------ | | `off` | Tanpa kompresi untuk permintaan ini. | | `default` | Profil Default yang diturunkan dari panel (mengabaikan profil aktif). | | `engine:` | Satu mesin saat diaktifkan, misalnya `engine:rtk`. | | `` | Kombo bernama, pertama-tama dicocokkan berdasarkan nama (tidak peka huruf besar-kecil), lalu berdasarkan ID. | Catatan: - Nilai yang tidak dikenal akan diabaikan (permintaan tidak pernah ditolak); resolusi dilanjutkan ke urutan prioritas operator normal. - Jika beberapa kombo memiliki nama yang sama, berikan **id** kombo agar pencocokan deterministik. - Kombo yang namanya `off` atau `default` tidak dapat dipilih berdasarkan nama (kata kunci tersebut ditafsirkan terlebih dahulu); rujuk kombo tersebut berdasarkan ID-nya. - Sakelar kompresi utama merupakan gerbang mutlak: ketika kompresi dinonaktifkan secara global, header ini tidak dapat mengaktifkannya. Paket yang diterapkan dikembalikan dalam header respons: ``` X-OmniRoute-Compression: ; source= ``` dengan `` adalah salah satu dari `request-header`, `routing-override`, `active-profile`, `auto-trigger`, `default`, atau `off`. --- ## Embedding ```bash POST /v1/embeddings Authorization: Bearer your-api-key Content-Type: application/json { "model": "nebius/Qwen/Qwen3-Embedding-8B", "input": "The food was delicious" } ``` Penyedia yang tersedia: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, Jina AI. ID katalog menggunakan format `provider/model` (contoh: `jina-ai/jina-embeddings-v5-omni-small`). ID model Jina tanpa awalan yang muncul dalam registri (misalnya `jina-embeddings-v5-text-small`, `jina-reranker-v3.5`) juga dapat di-resolve. Operasi embed/rerank/classify/segment Jina terlebih dahulu menggunakan kredensial `jina-ai` dari dasbor; `JINA_AI_API_KEY` hanya digunakan sebagai fallback jika tidak ada kunci dasbor. Kartu `jina-reader` hanya untuk Reader / `r.jina.ai` (`POST /v1/web/fetch`) dan tidak pernah menyediakan embedding atau rerank. Model registri yang menyatakan dukungan multimodal juga menerima hingga 32 item terstruktur yang netral terhadap penyedia. Jenis item media adalah `text`, `image`, `audio`, `video`, dan `document`. `source` media tersebut dapat berupa `{"type":"url","url":"https://..."}` atau `{"type":"base64","data":"...","media_type":"..."}`. Jina v5 Omni (`jina-ai/jina-embeddings-v5-omni-small`, `jina-ai/jina-embeddings-v5-omni-nano`, dan alias keluarga `jina-ai/jina-embeddings-v5-omni` → omni-small) juga menerima dokumen EmbeddingsV5Request native Jina dan **meneruskannya secara utuh** ke `https://api.jina.ai/v1/embeddings`: ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "task": "retrieval.query", "normalized": true, "input": [ { "text": "a red bicycle" }, { "image": "https://example.com/bike.png" }, { "content": [{ "text": "caption" }, { "image": "data:image/png;base64,..." }] } ] } ``` Nilai native `{ image | audio | video | pdf }` dapat berupa URL HTTPS publik, URI `data:`, atau base64 mentah. OmniRoute tidak mengubah objek tersebut menjadi string atau mengambil URL gambar native — Jina mengambil sendiri media publik tersebut. Kolom tambahan Jina (`task`, `normalized`, `truncate`, `embedding_type`) diteruskan. SKU Jina khusus teks tetap menolak dokumen nonteks. Batas keamanan dan transportasi: - URL media jarak jauh harus berupa HTTPS publik. Item kanonis `{type,source:url}` diambil di sisi server (validasi ulang pengalihan, batas waktu, batas ukuran, DNS publik, dan penguncian koneksi), lalu disematkan sebelum pemanggilan penyedia. Item native Jina `{image:"https://..."}` diteruskan apa adanya setelah pemeriksaan HTTPS publik yang sama; Jina mengambil URL tersebut. - Media base64 inline dibatasi hingga 8 MiB setelah didekode per item dan 16 MiB setelah didekode untuk seluruh permintaan. Translasi penyedia (item kanonis tidak pernah diteruskan tanpa perubahan): - Model multimodal Jina: setiap item tingkat teratas menjadi satu objek dengan kunci modalitas (`text` / `image` / `audio` / `video` / `pdf`) yang menggunakan URI data untuk media inline; satu vektor per item tingkat teratas. - Keluarga Gemini Embedding 2: satu array tingkat teratas menjadi satu permintaan native `models/{model}:embedContent` dengan `content.parts` (`text` atau `inline_data`). - Model yang tidak dikenal/dinamis tanpa metadata modalitas eksplisit menolak input terstruktur dengan HTTP 400. ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "input": [ { "type": "text", "text": "A red bicycle" }, { "type": "image", "source": { "type": "url", "url": "https://example.com/bicycle.png" } } ], "dimensions": 512, "encoding_format": "float" } ``` Kombinasi model/modalitas yang tidak didukung mengembalikan HTTP 400 alih-alih mengonversi item secara paksa. Kolom ekstensi non-input pada permintaan string/token lama tetap diteruskan tanpa perubahan. ```bash # Cantumkan semua model embedding GET /v1/embeddings ``` --- ## Pembuatan Gambar ```bash POST /v1/images/generations Authorization: Bearer your-api-key Content-Type: application/json { "model": "openai/gpt-image-2", "prompt": "Matahari terbenam yang indah di atas pegunungan", "size": "1024x1024" } ``` Penyedia yang tersedia: OpenAI (GPT Image 2), xAI (Grok Image), Together AI (FLUX), Fireworks AI, Nebius (FLUX), Hyperbolic, NanoBanana, **OpenRouter**, SD WebUI (lokal), ComfyUI (lokal). ```bash # Cantumkan semua model gambar GET /v1/images/generations ``` --- ## OCR Dokumen ```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` memilih penyedia OCR melalui awalan `provider/model`; id model tanpa awalan (misalnya `mistral-ocr-latest`) akan diarahkan ke penyedia yang terdaftar, dan jika `model` tidak dicantumkan, nilai default-nya adalah Mistral (`mistral-ocr-latest`). Penyedia yang terdaftar (`open-sse/config/ocrRegistry.ts`): | Id penyedia | Id model | Nilai `model` | Catatan | | ----------------------------- | -------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | `mistral` | `mistral-ocr-latest` | `mistral/mistral-ocr-latest` (atau tanpa awalan `mistral-ocr-latest`) | Sinkron — respons dikembalikan langsung dari satu panggilan upstream. | | `azure-document-intelligence` | `prebuilt-read` | `azure-document-intelligence/prebuilt-read` | Upstream asinkron (`analyze` + polling) — lihat di bawah. | | `vertex-deepseek-ocr` | `deepseek-ocr-maas` | `vertex-deepseek-ocr/deepseek-ocr-maas` | Sinkron, melalui endpoint mitra `openapi/chat/completions` milik Vertex AI — lihat di bawah untuk autentikasi/URL. | Ketiga penyedia memberikan respons dengan struktur yang sama seperti Mistral: ```json { "pages": [{ "index": 0, "markdown": "# Teks yang diekstrak..." }], "model": "mistral-ocr-latest", "usage_info": { "pages_processed": 1 } } ``` ### Alur polling Azure Document Intelligence API `analyze` Azure Document Intelligence bersifat asinkron: permintaan awal mengembalikan header `Operation-Location`, bukan isi respons, dan hasilnya harus diperiksa melalui polling. Handler (`open-sse/handlers/ocr.ts`) melakukan polling terhadap URL tersebut setiap detik hingga maksimal 30 percobaan, langsung gagal (tidak melanjutkan polling) jika respons polling bukan `ok` atau statusnya `"failed"`, dan mengembalikan `504` jika operasi masih berjalan setelah jatah percobaan habis. Respons akhir Azure dinormalisasi ke dalam struktur `pages`/`markdown` yang sama dengan yang digunakan Mistral sebelum dikembalikan kepada pemanggil, sehingga kode klien tidak perlu menangani penyedia secara khusus. ### Autentikasi dan resolusi endpoint OCR DeepSeek Vertex AI `vertex-deepseek-ocr` menggunakan kembali autentikasi Vertex AI yang sudah didukung OmniRoute untuk lalu lintas percakapan/gambar (`open-sse/executors/vertex.ts`): kunci API koneksi dapat berupa kredensial JSON Service Account (ditukar dengan token akses OAuth berumur pendek melalui alur JWT-bearer) atau token akses OAuth yang sudah diterbitkan dan digunakan apa adanya. URL endpoint upstream adalah endpoint mitra generik `openapi/chat/completions` milik Vertex, yang dibuat berdasarkan proyek dan wilayah koneksi — `providerSpecificData.project`/`providerSpecificData.region` yang ditentukan secara eksplisit selalu diprioritaskan; jika tidak, proyek diturunkan dari `project_id` dalam JSON Service Account dan wilayah secara default menggunakan `us-central1`. Kedua resolusi berlangsung di `open-sse/handlers/ocr.ts` (`resolveVertexOcrAccessToken`, `resolveVertexOcrBaseUrl`), lalu digunakan oleh `src/app/api/v1/ocr/route.ts` sebelum diteruskan ke `handleOcr`. --- ## Daftar Model ```bash GET /v1/models Authorization: Bearer your-api-key → Mengembalikan semua model chat, embedding, dan gambar + kombinasinya dalam format OpenAI ``` ### Awalan id model (`?prefix=`) Sebagian besar model ditampilkan dengan **awalan penyedia**. Awalan yang Anda dapatkan dikendalikan oleh feature flag `MODELS_CATALOG_PREFIX_MODE`, dan dapat ditimpa **per permintaan** dengan parameter kueri — berguna bagi klien yang menginginkan daftar bersih tanpa mengubah pengaturan tingkat server untuk semua pengguna lainnya: ```bash GET /v1/models?prefix=alias # satu id per model — awalan alias pendek GET /v1/models?prefix=dual # kedua bentuk (default server) GET /v1/models?prefix=canonical # hanya awalan id penyedia lengkap ``` | Mode | Menghasilkan | Catatan | | ----------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `dual` | `cc/claude-sonnet-4-6` **dan** `claude/claude-sonnet-4-6` | **Default.** Kedua id diarahkan ke model yang sama; dipertahankan agar konfigurasi klien yang melakukan hardcode pada salah satu bentuk tetap berfungsi. Katalog menjadi kira-kira dua kali lipat. | | `alias` | `cc/claude-sonnet-4-6` | Satu entri per model. Penyedia tanpa alias tersendiri tetap menghasilkan entrinya, sehingga tidak ada yang hilang. | | `canonical` | `claude/claude-sonnet-4-6` | Satu entri per model dengan awalan id penyedia lengkap. Penyedia tanpa alias tersendiri (mis. `antigravity/…`, `agy/…`) juga menghasilkan satu-satunya id mereka di sini, sehingga tidak ada yang hilang. | Mirror mode `dual` juga dapat dikenali tanpa parameter kueri: mirror tersebut memiliki field `parent` yang menunjuk ke id utama. Klien yang menampilkan pemilih model sebaiknya meminta `?prefix=alias` — inilah yang dilakukan oleh [ekstensi OmniCopilot VS Code](../guides/VSCODE-COPILOT.md). ### Varian model tanpa thinking Untuk model Claude yang mendukung thinking, `/v1/models` juga menampilkan varian **tanpa thinking** dengan id yang diawali `claude-3-omniroute-no-thinking/`: ``` claude-3-omniroute-no-thinking// ``` Memilih id ini (mis. dalam konfigurasi Claude Code yang selalu menyertakan blok `thinking`) akan dipetakan kembali ke `/` yang sebenarnya dengan penalaran dinonaktifkan — `thinking:{type:"disabled"}` pada jalur `/v1/messages`, atau field `reasoning`/`reasoning_effort` dihapus pada jalur `/v1/chat/completions`. Varian ini hanya dicantumkan untuk model keluarga Claude yang mendukung thinking **dan** mematuhi `disabled` (jadi, misalnya, model khusus adaptif yang menolak `disabled` tidak disertakan). Operator dapat memaksa pengaktifan atau penonaktifan varian tersebut per model melalui `ModelSpec.noThinkingAlias`. --- ## Manifes Plugin Penyedia ```bash GET /api/v1/provider-plugin-manifest ``` Mengembalikan manifes plugin penyedia yang aman untuk JSON dan digunakan oleh Bifrost, CLIProxyAPI, serta router sidecar pada masa mendatang. Respons dihasilkan dari registri penyedia TypeScript dan sengaja mengecualikan rahasia klien OAuth, resolusi lingkungan runtime, fungsi eksekutor, header permintaan, dan data akun. Gunakan endpoint ini ketika sidecar berjalan di luar proses dan tidak dapat mengimpor `open-sse/config/providerPluginManifestRegistry.ts` secara langsung. --- ## Endpoint Kompatibilitas | Metode | Jalur | 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 (edit/inpaint) | | POST | `/v1/videos/generations` | Pembuatan video bergaya OpenAI | | POST | `/v1/music/generations` | Pembuatan musik bergaya OpenAI | | POST | `/v1/audio/transcriptions` | OpenAI Audio (STT) | | POST | `/v1/audio/speech` | OpenAI TTS (mengembalikan isi audio) | | POST | `/v1/rerank` | Pemeringkatan ulang bergaya Cohere/Voyage | | POST | `/v1/classify` | Klasifikasi Jina (`api.jina.ai`) | | POST | `/v1/segment` | Segmenter Jina (`segment.jina.ai`) | | POST | `/v1/moderations` | OpenAI Moderations | | GET | `/v1/models` | OpenAI | | POST | `/v1/messages/count_tokens` | Anthropic | | GET | `/v1beta/models` | Gemini | | POST | `/v1beta/models/{...path}` | Gemini generateContent | | POST | `/v1/api/chat` | Ollama | | GET | `/api/v1/vscode/{token}/` | Alias katalog OpenAI | | GET | `/api/v1/vscode/{token}/models` | Alias model OpenAI | | POST | `/api/v1/vscode/{token}/chat/completions` | Alias OpenAI dengan token | | POST | `/api/v1/vscode/{token}/responses` | Alias OpenAI Responses dengan token | | POST | `/api/v1/vscode/{token}/api/chat` | Alias Ollama dengan token | | GET | `/api/v1/vscode/{token}/api/tags` | Alias tag Ollama dengan token | Semua rute POST mengikuti struktur yang sama: `Bearer your-api-key` + isi JSON yang divalidasi Zod (`v1RerankSchema`, `v1ModerationSchema`, `v1AudioSpeechSchema`, dan sebagainya, lihat `src/shared/validation/schemas.ts`). 4xx dikembalikan ketika validasi skema gagal. Untuk klien yang tidak dapat menyertakan `Authorization: Bearer ...`, OmniRoute juga menerima kunci API dalam URL melalui kompatibilitas string kueri (`?token=...`, `?apiKey=...`, `?api_key=...`, `?key=...`) atau endpoint khusus `/api/v1/vscode/{token}/...` yang didokumentasikan di bawah ini. ```bash # Pemeringkatan ulang POST /v1/rerank { "model": "jina-ai/jina-reranker-v3.5", "query": "...", "documents": ["..."] } # Klasifikasi Jina (kredensial Foundation API) POST /v1/classify { "model": "jina-embeddings-v5-text-small", "input": ["..."], "labels": ["a", "b"] } # Segmenter Jina POST /v1/segment { "content": "...", "return_chunks": true } # Pencarian Jina (s.jina.ai; alias penyedia: jina-search, jina-ai, jina) POST /v1/search { "query": "...", "provider": "jina-search" } # Moderasi POST /v1/moderations { "model": "omni-moderation-latest", "input": "..." } # TTS — mengembalikan isi audio/mpeg (atau format yang diminta) POST /v1/audio/speech { "model": "openai/tts-1", "input": "Hello", "voice": "alloy" } # Pengeditan gambar (multipart) POST /v1/images/edits -F image=@input.png -F prompt="..." -F mask=@mask.png # Pembuatan video/musik (ID model dengan prefiks penyedia) POST /v1/videos/generations { "model": "runway/gen-3", "prompt": "..." } POST /v1/music/generations { "model": "suno/v3.5", "prompt": "..." } ``` ### Rute Khusus Penyedia ```bash POST /v1/providers/{provider}/chat/completions POST /v1/providers/{provider}/embeddings POST /v1/providers/{provider}/images/generations ``` Prefiks penyedia ditambahkan secara otomatis jika tidak ada. Model yang tidak cocok mengembalikan `400`. --- ## Files API Endpoint file yang kompatibel dengan OpenAI untuk input/output batch dan unggahan berdasarkan tujuan file. | Metode | Path | Deskripsi | | ------ | ------------------------ | ------------------------------------------------------------------------------------------------------------- | | POST | `/v1/files` | Unggah file (multipart: `file`, `purpose`, `expires_after[anchor]`, `expires_after[seconds]`) — maks. 512 MiB | | GET | `/v1/files` | Cantumkan file untuk kunci API yang terautentikasi | | GET | `/v1/files/[id]` | Ambil metadata file | | DELETE | `/v1/files/[id]` | Hapus file | | GET | `/v1/files/[id]/content` | Streaming isi mentah file kembali | **Autentikasi:** Kunci API Bearer — file dicakup per kunci API melalui `getApiKeyRequestScope`. Sebuah kunci hanya dapat melihat, mengunduh, dan menghapus filenya sendiri; sesi dasbor tanpa kunci dapat membaca seluruh instans; file tanpa pemilik (unggahan anonim atau melalui sesi dasbor) ditolak untuk setiap pemanggil tanpa sesi. `GET /v1/files` menolak pemanggil anonim — serta kunci yang diberikan tetapi tidak dapat diidentifikasi — dengan `401` meskipun `REQUIRE_API_KEY=false`, alih-alih mencantumkan file milik semua tenant (GHSA-m3hp-hq9g-fpmv, GHSA-2jm2-mpx8-6523). --- ## Batches API Pemrosesan batch yang kompatibel dengan OpenAI. | Metode | Path | Deskripsi | | ------ | ------------------------- | --------------------------------------------------------------------------------------------------------- | | POST | `/v1/batches` | Buat batch — isi divalidasi oleh `v1BatchCreateSchema` (`input_file_id`, `endpoint`, `completion_window`) | | GET | `/v1/batches` | Cantumkan batch | | GET | `/v1/batches/[id]` | Ambil status batch + `request_counts` | | DELETE | `/v1/batches/[id]` | Hapus batch yang selesai/gagal | | POST | `/v1/batches/[id]/cancel` | Batalkan batch yang sedang diproses | **Autentikasi:** Kunci API Bearer. Batch dicakup per kunci API berdasarkan aturan tiga arah yang sama seperti file: hanya kunci sendiri, sesi dasbor mencakup seluruh instans, rekaman tanpa pemilik ditolak untuk setiap pemanggil tanpa sesi (pengambilan, penghapusan, pembatalan, dan pemeriksaan `input_file_id` saat pembuatan). `GET /v1/batches` menolak pemanggil anonim dengan `401` meskipun `REQUIRE_API_KEY=false`. --- ## Search API Abstraksi penyedia web/pencarian (Tavily, Brave, Exa, Serper, dll.). | Metode | Jalur | Deskripsi | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------ | | GET | `/v1/search` | Mencantumkan penyedia pencarian yang dikonfigurasi + kapabilitasnya | | POST | `/v1/search` | Menjalankan kueri pencarian — isi divalidasi oleh `v1SearchSchema`, mendukung caching/coalescing | | GET | `/v1/search/analytics` | Statistik hit/latensi/cache per penyedia | **Autentikasi:** Kunci API Bearer (`extractApiKey` + `isValidApiKey`). Kebijakan pencarian diberlakukan melalui `enforceApiKeyPolicy`. --- ## Web Fetch API Mengekstrak konten dari URL melalui penyedia web-fetch yang dikonfigurasi (Firecrawl, Jina Reader, Tavily Extract, TinyFish Fetch, Nimble Extract). | Metode | Jalur | Deskripsi | | ------ | --------------- | ------------------------------------------------------------- | | POST | `/v1/web/fetch` | Mengambil/scrape URL — isi divalidasi oleh `v1WebFetchSchema` | **Autentikasi:** Kunci API Bearer (`extractApiKey` + `isValidApiKey`). Kebijakan diberlakukan melalui `enforceApiKeyPolicy`. **Fallback yang memperhitungkan kuota (#8297):** ketika tidak ada `provider` eksplisit yang diberikan, pool (`firecrawl` → `jina-reader` → `tavily-search` → `tinyfish` → `nimble-search`) ditelusuri dalam urutan prioritas tetap (fill-first) — penyedia yang dikonfigurasi tetapi terkena pembatasan laju dilewati alih-alih langsung menghentikan permintaan, dan kegagalan upstream yang dapat dicoba ulang/terkait kuota (HTTP 429 selalu; 402/403 untuk paket gratis bergaya kuota Firecrawl/Tavily/TinyFish — tidak untuk Jina Reader, dan tidak pernah untuk permintaan buruk 400 biasa) akan beralih ke penyedia berkredensial berikutnya yang belum dicoba saat permintaan berlangsung. Ketika setiap penyedia dalam pool telah habis, endpoint mengembalikan satu `429` (dengan header `Retry-After`) alih-alih `400` generik sebelumnya. Ketika `provider` eksplisit diminta, **tidak ada** fallback diam-diam — penyedia eksplisit yang terkena pembatasan laju atau gagal akan menampilkan error-nya sendiri (`429` jika terkena pembatasan laju, selain itu status upstream). --- ## Streaming WebSocket ```bash GET /v1/ws?handshake=1 ``` Memvalidasi handshake upgrade WebSocket dan mengembalikan pesan contoh protokol wire (`request`, `cancel`). Frame WS aktual ditangani oleh server WS bawaan di luar tabel rute Next.js. **Autentikasi:** Kunci API Bearer selama handshake. ### Responses API melalui WebSocket (khusus codex) ```bash # Host:port yang sama dengan API HTTP (default 20128); upgrade koneksi: wscat -c "ws://localhost:20128/v1/responses?api_key=" # (atau: -H "Authorization: Bearer ") # Frame pertama HARUS berupa response.create: { "type": "response.create", "model": "gpt-5.5", "input": [ { "role": "user", "content": "hi" } ] } ``` Proksi Responses-API-over-WebSocket terhubung **secara eksklusif ke `codex`** (backend ChatGPT). Proksi ini mendengarkan pada port yang sama dengan API/dashboard di jalur `/v1/responses`, `/responses`, dan `/api/v1/responses`. Pada frame `response.create` pertama, proksi melakukan autentikasi + persiapan melalui bridge internal `codex-responses-ws`, memilih koneksi OAuth codex, dan membuat tunnel ke `wss://chatgpt.com/backend-api/codex/responses` melalui transport `wreq-js`. **Model non-codex ditolak** (`codex_ws_provider_required`). Untuk routing quota-share, gunakan `model: "qtSd//codex/"`. Diimplementasikan di `app/server-ws.mjs` + `scripts/dev/responses-ws-proxy.mjs` + `src/app/api/internal/codex-responses-ws/route.ts`. **Autentikasi:** Kunci API Bearer selama handshake. Server HTTP bawaan (`server-ws.mjs`) harus menjadi entrypoint aktif (dan memang demikian secara default ketika `app/server-ws.mjs` tersedia). #### ID model: gunakan ID ChatGPT polos (tanpa prefiks `codex/`) **Codex CLI** OpenAI memvalidasi nama model di sisi klien ketika `supports_websockets = true` dan **menolak ID yang diawali nama penyedia** seperti `codex/gpt-5.5` (`The 'codex/gpt-5.5' model is not supported when using Codex with a ChatGPT account`). Kirim ID **polos** (misalnya `gpt-5.5`). Bridge OmniRoute hanya mendukung codex, sehingga bridge tersebut me-resolve ulang ID polos sebagai model codex (`resolveCodexWsModelInfo`) sebelum membuat tunnel ke upstream — meskipun `gpt-5.5` polos seharusnya dirutekan ke penyedia lain melalui HTTP. #### Mengonfigurasi OpenAI Codex CLI Arahkan Codex CLI ke OmniRoute dengan menambahkan penyedia kustom yang mendukung WebSocket ke `~/.codex/config.toml` (gunakan `CODEX_HOME` terpisah agar tidak mengubah konfigurasi yang sudah ada): ```toml model = "gpt-5.5" # ID polos — BUKAN "codex/gpt-5.5" model_provider = "omniroute" [model_providers.omniroute] name = "OmniRoute (WS)" base_url = "http://localhost:20128/v1" # tanpa garis miring penutup; URL WS diturunkan darinya (gunakan https/wss di produksi) wire_api = "responses" # satu-satunya nilai yang didukung sejak Feb 2026 supports_websockets = true # mengaktifkan transport Responses-over-WS env_key = "OMNIROUTE_API_KEY" # menyimpan kunci API OmniRoute (Bearer) ``` ```bash export OMNIROUTE_API_KEY=sk-... # kunci API OmniRoute (kunci apa pun jika REQUIRE_API_KEY=false) codex exec "Responda apenas: PONG" ``` CLI meng-upgrade `base_url + /responses` menjadi WebSocket dan OmniRoute membuat tunnel ke koneksi OAuth codex yang dipilih. Telah divalidasi secara end-to-end terhadap server lokal: ChatGPT mengembalikan `codex.rate_limits` + `response.created` dan melakukan streaming completion. --- ## Kuota & Pelaporan Masalah | Metode | Jalur | Deskripsi | | ------ | ------------------- | ---------------------------------------------------------------------------------------------------- | | GET | `/v1/quotas/check` | Memvalidasi kuota terlebih dahulu untuk `provider` + `accountId` sebelum menerbitkan kunci terdaftar | | POST | `/v1/issues/report` | Melaporkan kegagalan kuota/penerbitan kunci ke GitHub (memerlukan `GITHUB_ISSUES_REPO` + token) | **Autentikasi:** Kunci API Bearer (`isAuthenticated`). --- ## Penggunaan mandiri (`/api/usage/om-usage`) Kunci API apa pun dapat membaca penggunaan dan kuotanya **sendiri** — tanpa autentikasi pengelolaan. Ini adalah endpoint yang digunakan klien (CLI, panel OmniCopilot) untuk menampilkan pengeluaran pemegang kunci. ```bash # Format teks (kontrak historis — teks biasa untuk terminal) curl -H "Authorization: Bearer " \ http://localhost:20128/api/usage/om-usage # Format terstruktur — yang digunakan oleh UI curl -H "Authorization: Bearer " \ "http://localhost:20128/api/usage/om-usage?format=json" ``` Kunci harus mengaktifkan **`allowUsageCommand`** (dinonaktifkan secara default — pengelola kunci API di dasbor mengaktifkan atau menonaktifkannya per kunci). Tanpa pengaturan tersebut, endpoint akan memberikan respons `403`. `?format=json` mengembalikan struktur terdiskriminasi sehingga pemanggil tidak pernah membaca bidang data dari respons penolakan. Jika berhasil: ```jsonc { "allowed": true, // hanya tersedia jika kunci mengaktifkan batas penggunaan per kunci (USD harian/mingguan): "personal": { "dailySpentUsd": 1.25, "dailyLimitUsd": 5, "dailyResetAtIso": "…", "weeklySpentUsd": 8, "weeklyLimitUsd": 20, "weeklyResetAtIso": "…" /* … */, }, // snapshot kuota penyedia yang dipilih, atau null jika belum ada yang disimpan dalam cache: "provider": { "connectionId": "…", "provider": "claude", "plan": "…", "quotas": {/* … */}, }, // snapshot setiap koneksi, agar UI dapat menampilkan beberapa penyedia secara berdampingan: "providers": [ { "connectionId": "…", "provider": "claude" /* … */ }, { "provider": "codex" /* … */ }, ], } ``` Jika ditolak (`401` kunci tidak valid / `403` tidak diizinkan), rute yang sama mengembalikan `{ "allowed": false, "error": { "message": "…" } }` — `personal`/`provider` yang tersedia tetapi kosong (kunci diizinkan, tetapi belum ada data yang diperoleh) merupakan status yang berbeda dari penolakan, dan hanya format JSON yang membedakannya. **Autentikasi:** kunci API Bearer milik pemanggil sendiri, yang divalidasi dengan `isValidApiKey` — ini _bukan_ antarmuka pengelolaan (`/api/keys/…`), yang tetap dilindungi oleh `requireManagementAuth`. --- ## Cache Semantik ```bash # Mendapatkan statistik cache GET /api/cache/stats # Menghapus semua cache DELETE /api/cache/stats ``` Contoh respons: ```json { "semanticCache": { "memorySize": 42, "memoryMaxSize": 500, "dbSize": 128, "hitRate": 0.65 }, "idempotency": { "activeKeys": 3, "windowMs": 5000 } } ``` ### Dampak latensi HIT cache semantik menyajikan respons dari cache **tanpa panggilan ke upstream**, sehingga `X-OmniRoute-Response-Latency` yang dilaporkan mendekati nol (terlepas dari latensi upstream awal). Klien yang sensitif terhadap latensi (benchmark, pemantauan p50/p99) sebaiknya memeriksa header respons `X-OmniRoute-Cache-Latency`: | Nilai | Arti | | ------------- | --------------------------------------------------------------------- | | `synthetic` | Respons disajikan dari cache; latensi bukan waktu upstream sebenarnya | | _(tidak ada)_ | Respons dari panggilan upstream yang sebenarnya | ### Melewati cache per kunci Kunci API dapat memilih untuk tidak menggunakan pembacaan cache semantik melalui `cacheDefaultMode`: | Nilai | Perilaku | | -------- | -------------------------------------------------------------- | | `legacy` | Perilaku cache normal (default) | | `bypass` | Melewati pencarian cache sepenuhnya; selalu mengakses upstream | Tetapkan saat pembuatan kunci (`POST /api/keys`) atau pembaruan (`PATCH /api/keys/[id]`): ```json { "cacheDefaultMode": "bypass" } ``` ### Melewati cache per permintaan Permintaan apa pun dapat melewati cache tanpa bergantung pada pengaturan kunci: ``` X-OmniRoute-No-Cache: true ``` --- ## Dasbor & Manajemen Rute manajemen (`/api/*` kecuali autentikasi/login publik) **tidak** diotorisasi oleh kunci API inferensi biasa. Jenis kredensial, cakupan, dan contoh curl: [Autentikasi Manajemen](../guides/MANAGEMENT-AUTH.md). ### Autentikasi | Endpoint | Metode | Deskripsi | | ----------------------------- | ------- | ------------------------------------ | | `/api/auth/login` | POST | Masuk | | `/api/auth/logout` | POST | Keluar | | `/api/settings/require-login` | GET/PUT | Aktifkan/nonaktifkan kewajiban masuk | ### Manajemen Penyedia | Endpoint | Metode | Deskripsi | | ---------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------- | | `/api/providers` | GET/POST | Cantumkan / buat penyedia | | `/api/providers/[id]` | GET/PUT/DELETE | Kelola penyedia | | `/api/providers/[id]/test` | POST | Uji koneksi penyedia | | `/api/providers/[id]/models` | GET | Cantumkan model penyedia | | `/api/providers/validate` | POST | Validasi konfigurasi penyedia | | `/api/providers/bulk` | POST | Tambahkan kunci API secara massal untuk SATU penyedia | | `/api/providers/import` | POST | Impor DAFTAR penyedia yang heterogen dari file CSV/JSON yang telah diurai (#6836); hasil kegagalan parsial per baris | | `/api/provider-nodes*` | Beragam | Manajemen node penyedia | | `/api/provider-models` | GET/POST/PATCH/DELETE | Model khusus (tambahkan, perbarui, sembunyikan/tampilkan, hapus) | ### Alur OAuth | Endpoint | Metode | Deskripsi | | -------------------------------- | ------- | --------------------- | | `/api/oauth/[provider]/[action]` | Beragam | OAuth khusus penyedia | ### Perutean & Konfigurasi | Endpoint | Metode | Deskripsi | | --------------------- | -------- | --------------------------------------- | | `/api/models/alias` | GET/POST | Alias model | | `/api/models/catalog` | GET | Semua model berdasarkan penyedia + tipe | | `/api/combos*` | Beragam | Manajemen kombo | | `/api/keys*` | Beragam | Manajemen kunci API | | `/api/pricing` | GET | Harga model | ### Penggunaan & Analitik | Endpoint | Metode | Deskripsi | | -------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `/api/usage/history` | GET | Riwayat penggunaan | | `/api/usage/logs` | GET | Log penggunaan | | `/api/usage/request-logs` | GET | Log tingkat permintaan | | `/api/usage/[connectionId]` | GET | Penggunaan per koneksi | | `/api/usage/token-limits` | GET/POST/DELETE | Anggaran batas token per kunci API | | `/api/usage/model-latency-stats` | GET | Agregat latensi bergulir per penyedia/model (rata-rata/p50/p95/p99, tingkat keberhasilan); filter: `windowHours`/`minSamples`/`maxRows`/`provider`/`model` (#6873) | | `/api/usage/cache-health` | GET | Ringkasan kondisi cache prompt berdasarkan `call_logs` — rasio tulis/baca, distribusi ukuran penulisan p50/p90/p99, konsentrasi penulisan berat, perincian per model, dan status `healthy`/`degraded`/`thrash`/`no-data`; parameter kueri `range` (`1h`\|`24h`\|`7d`\|`30d`, default `24h`) dan `model` opsional (#8827) | ### Pengaturan | Endpoint | Metode | Deskripsi | | ------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `/api/settings` | GET/PUT/PATCH | Pengaturan umum | | `/api/settings/proxy` | GET/PUT | Konfigurasi proksi jaringan | | `/api/settings/proxy/test` | POST | Uji koneksi proksi | | `/api/settings/ip-filter` | GET/PUT | Daftar izin/daftar blokir IP | | `/api/settings/thinking-budget` | GET/PUT | Mode penulisan ulang **permintaan** untuk berpikir/bernalar (diteruskan apa adanya / hapus otomatis / khusus / adaptif). Independen dari kompresi. Lihat [THINKING_BUDGET.md](../guides/THINKING_BUDGET.md). | | `/api/settings/system-prompt` | GET/PUT | Prompt sistem global | | `/api/settings/compression` | GET/PUT | Konfigurasi kompresi global | | `/api/settings/purge-request-history` | POST | Hapus baris log permintaan dan artefak log panggilan lokal | ### Konteks & Kompresi | Endpoint | Metode | Deskripsi | | -------------------------------------- | -------------- | ----------------------------------------------------------------------- | | `/api/compression/preview` | POST | Pratinjau kompresi off/lite/standard/aggressive/ultra/RTK/stacked | | `/api/compression/language-packs` | GET | Daftar paket bahasa Caveman yang tersedia | | `/api/compression/rules` | GET | Daftar metadata aturan Caveman | | `/api/context/caveman/config` | GET/PUT | Alias pengaturan khusus Caveman | | `/api/context/rtk/config` | GET/PUT | Pengaturan khusus RTK, termasuk filter khusus dan retensi output mentah | | `/api/context/rtk/filters` | GET | Katalog filter RTK dan diagnostik filter khusus | | `/api/context/rtk/test` | POST | Jalankan pratinjau/pengujian RTK terhadap payload teks | | `/api/context/rtk/raw-output/[id]` | GET | Baca output mentah tersensor yang disimpan berdasarkan ID penunjuk | | `/api/context/combos` | GET/POST | Daftar/buat kombinasi kompresi | | `/api/context/combos/[id]` | GET/PUT/DELETE | Detail/perbarui/hapus kombinasi kompresi | | `/api/context/combos/[id]/assignments` | GET/PUT | Tetapkan kombinasi kompresi ke kombinasi perutean | | `/api/context/analytics` | GET | Alias analitik kompresi | ### Pemantauan | Endpoint | Metode | Deskripsi | | ------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `/api/sessions` | GET | Pelacakan sesi aktif | | `/api/rate-limits` | GET | Batas laju per akun | | `/api/monitoring/health` | GET | Pemeriksaan kondisi + ringkasan penyedia (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`). Tampilan manajemen mencakup `credentialHealth`: nilai skalar cache probe, `failedConnections` saat `failed>0`, dan `staleDbNonOkCount` (`test_status` tetap SQLite, bukan gauge). Lihat [MONITORING_GUIDE.md](../ops/MONITORING_GUIDE.md#credentialhealth-probe-cache-vs-sqlite-test_status). | | `/api/cache/stats` | GET/DELETE | Statistik cache / hapus cache | | `/api/modality-bridge/stats` | GET | `attempts` dalam memori, keberhasilan/`bridged`, kegagalan, cache hit, `totalLatencyMs`, `latencySamples`, `averageLatencyMs` berbasis jumlah sampel, dan waktu penggunaan terakhir (direset saat dimulai ulang; autentikasi manajemen) | | `/api/modality-bridge/video/runtime` | GET | Pemeriksaan loopback tepercaya yang ketat sebelum autentikasi/probe manajemen; ketersediaan dan versi FFmpeg/ffprobe yang telah disanitasi (no-store) | | `/api/modality-bridge/video/extract` | POST | Broker byte loopback tepercaya internal yang diautentikasi; input 50 MiB, antrean terbatas/output 32 MiB, kapasitas `503`, pemutusan koneksi `499`, tenggat waktu `504`; bukan API unggahan publik | ### Pencadangan & Ekspor/Impor | Endpoint | Metode | Deskripsi | | --------------------------- | ------ | -------------------------------------------------- | | `/api/db-backups` | GET | Mencantumkan cadangan yang tersedia | | `/api/db-backups` | PUT | Membuat cadangan manual | | `/api/db-backups` | POST | Memulihkan dari cadangan tertentu | | `/api/db-backups/export` | GET | Mengunduh basis data sebagai file .sqlite | | `/api/db-backups/import` | POST | Mengunggah file .sqlite untuk mengganti basis data | | `/api/db-backups/exportAll` | GET | Mengunduh cadangan lengkap sebagai arsip .tar.gz | ### Sinkronisasi Cloud | Endpoint | Metode | Deskripsi | | ---------------------- | ------- | ----------------------------- | | `/api/sync/cloud` | Beragam | Operasi sinkronisasi cloud | | `/api/sync/initialize` | POST | Menginisialisasi sinkronisasi | | `/api/cloud/*` | Beragam | Pengelolaan cloud | ### Tunnel | Endpoint | Metode | Deskripsi | | -------------------------- | ------ | --------------------------------------------------------------------------------- | | `/api/tunnels/cloudflared` | GET | Membaca status instalasi/runtime Cloudflare Quick Tunnel untuk dasbor | | `/api/tunnels/cloudflared` | POST | Mengaktifkan atau menonaktifkan Cloudflare Quick Tunnel (`action=enable/disable`) | | `/api/tunnels/ngrok` | GET | Membaca status runtime ngrok Tunnel untuk dasbor | | `/api/tunnels/ngrok` | POST | Mengaktifkan atau menonaktifkan ngrok Tunnel (`action=enable/disable`) | ### Alat CLI | Endpoint | Metode | Deskripsi | | ---------------------------------- | ------ | ------------------- | | `/api/cli-tools/claude-settings` | GET | Status Claude CLI | | `/api/cli-tools/codex-settings` | GET | Status Codex CLI | | `/api/cli-tools/droid-settings` | GET | Status Droid CLI | | `/api/cli-tools/openclaw-settings` | GET | Status OpenClaw CLI | | `/api/cli-tools/runtime/[toolId]` | GET | Runtime CLI generik | Respons CLI mencakup: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. ### Agen ACP | Endpoint | Metode | Deskripsi | | ----------------- | ------ | --------------------------------------------------------------------------- | | `/api/acp/agents` | GET | Mencantumkan semua agen yang terdeteksi (bawaan + kustom) beserta statusnya | | `/api/acp/agents` | POST | Menambahkan agen kustom atau menyegarkan cache deteksi | | `/api/acp/agents` | DELETE | Menghapus agen kustom berdasarkan parameter kueri `id` | Respons GET mencakup `agents[]` (id, name, binary, version, installed, protocol, isCustom) dan `summary` (total, installed, notFound, builtIn, custom). ### Ketahanan & Batas Laju | Endpoint | Metode | Deskripsi | | --------------------------------- | --------- | ----------------------------------------------------------------------------------------------------- | | `/api/resilience` | GET/PATCH | Mendapatkan/memperbarui antrean permintaan, cooldown koneksi, breaker penyedia, dan pengaturan tunggu | | `/api/resilience/reset` | POST | Mereset circuit breaker penyedia | | `/api/resilience/model-cooldowns` | GET | Mencantumkan penguncian aktif per-(penyedia, koneksi, model), diurutkan berdasarkan sisa waktu | | `/api/resilience/model-cooldowns` | DELETE | Menghapus penguncian model — isi `{provider, model}` atau `{all: true}` untuk menghapus semuanya | | `/api/rate-limits` | GET | Status batas laju per akun | | `/api/rate-limit` | GET | Konfigurasi batas laju global | > Keempat rute `/api/resilience/*` memerlukan **autentikasi manajemen** (`requireManagementAuth`). Lihat [Ketahanan (diperluas)](#resilience-extended) untuk perincian lengkap mengenai breaker penyedia vs cooldown koneksi vs penguncian model. ### Evaluasi | Endpoint | Metode | Deskripsi | | ------------ | -------- | ------------------------------------------------------ | | `/api/evals` | GET/POST | Mencantumkan rangkaian evaluasi / menjalankan evaluasi | ### Kebijakan | Endpoint | Metode | Deskripsi | | --------------- | --------------- | ---------------------------- | | `/api/policies` | GET/POST/DELETE | Mengelola kebijakan perutean | ### Kepatuhan | Endpoint | Metode | Deskripsi | | --------------------------- | ------ | -------------------------------- | | `/api/compliance/audit-log` | GET | Log audit kepatuhan (N terakhir) | ### v1beta (Kompatibel dengan Gemini) | Endpoint | Metode | Deskripsi | | -------------------------- | ------ | -------------------------------------- | | `/v1beta/models` | GET | Mencantumkan model dalam format Gemini | | `/v1beta/models/{...path}` | POST | Endpoint `generateContent` Gemini | Endpoint ini mencerminkan format API Gemini untuk klien yang mengharapkan kompatibilitas SDK Gemini native. ### API Internal / Sistem | Endpoint | Metode | Deskripsi | | ------------------------ | ------ | -------------------------------------------------------------------------- | | `/api/init` | GET | Pemeriksaan inisialisasi aplikasi (digunakan saat pertama kali dijalankan) | | `/api/tags` | GET | Tag model yang kompatibel dengan Ollama (untuk klien Ollama) | | `/api/restart` | POST | Memicu mulai ulang server secara aman | | `/api/shutdown` | POST | Memicu pematian server secara aman | | `/api/system/env/repair` | POST | Memperbaiki variabel lingkungan penyedia OAuth | > **Catatan:** Endpoint ini digunakan secara internal oleh sistem atau untuk kompatibilitas klien Ollama. Endpoint ini biasanya tidak dipanggil oleh pengguna akhir. ### Perbaikan Lingkungan OAuth _(v3.6.1+)_ ```bash POST /api/system/env/repair Content-Type: application/json { "provider": "claude-code" } ``` Memperbaiki variabel lingkungan OAuth yang hilang atau rusak untuk penyedia tertentu. Mengembalikan: ```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" } ``` --- ## Transkripsi Audio ```bash POST /v1/audio/transcriptions Authorization: Bearer your-api-key Content-Type: multipart/form-data ``` Transkripsikan file audio menggunakan penyedia STT mana pun yang telah dikonfigurasi. Segmen jalur pertama memilih penyedia asli (`openai/…`, `deepgram/…`). Gateway yang mengekspor ulang model vendor lain menggunakan id yang memenuhi syarat (`openrouter/deepgram/nova-3`). **Permintaan:** ```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" ``` **Respons:** ```json { "text": "Halo, ini adalah konten audio yang telah ditranskripsikan.", "task": "transcribe", "language": "en", "duration": 12.5 } ``` **Contoh id model:** `openai/whisper-1` (memerlukan kunci OpenAI), `openrouter/deepgram/nova-3` (memerlukan kunci OpenRouter), `deepgram/nova-3` (memerlukan kunci asli Deepgram). Permintaan langsung `deepgram/nova-3` **tidak** menggunakan OpenRouter. **Format yang didukung:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. --- ## Kompatibilitas Ollama Untuk klien yang menggunakan format API Ollama: ```bash # Endpoint percakapan (format Ollama) POST /v1/api/chat # Daftar model (format Ollama) GET /api/tags ``` Permintaan secara otomatis diterjemahkan antara format Ollama dan format internal. ## Alias VS Code Bertoken / Tanpa Header Gunakan alias ini jika integrasi tidak dapat menyisipkan header `Authorization` dan memerlukan kunci API yang disematkan dalam URL dasar. ```bash # Alias katalog bergaya OpenAI GET /api/v1/vscode/{token}/ GET /api/v1/vscode/{token}/models # Alias percakapan bergaya OpenAI POST /api/v1/vscode/{token}/chat/completions POST /api/v1/vscode/{token}/responses # Alias bergaya Ollama POST /api/v1/vscode/{token}/api/chat GET /api/v1/vscode/{token}/api/tags ``` Contoh: ```bash curl https://your-host.example/api/v1/vscode/YOUR_API_KEY/models curl -X POST https://your-host.example/api/v1/vscode/YOUR_API_KEY/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"auto","messages":[{"role":"user","content":"hello"}]}' ``` Catatan: - Alias bertoken menggunakan kembali handler yang sama dengan `/v1/*` dan `/api/tags`; struktur respons tetap identik. - Utamakan `Authorization: Bearer ...` jika klien mendukung header khusus. - Token berbasis URL dapat muncul dalam log reverse proxy, riwayat browser, dan telemetri di luar OmniRoute. Perlakukan token tersebut sebagai opsi kompatibilitas, bukan mode autentikasi default. --- ## Telemetri ```bash # Dapatkan ringkasan telemetri latensi (p50/p95/p99 per penyedia) GET /api/telemetry/summary ``` **Respons:** ```json { "providers": { "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } } } ``` --- ## Anggaran ```bash # Dapatkan status anggaran untuk semua kunci API GET /api/usage/budget # Tetapkan atau perbarui anggaran 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" } ``` > **Catatan skema** (`setBudgetSchema`): `apiKeyId` wajib diisi; setidaknya salah satu dari `dailyLimitUsd`, `weeklyLimitUsd`, atau `monthlyLimitUsd` harus lebih besar dari nol. Bidang opsional: `warningThreshold` (0–1), `resetInterval` (`daily` | `weekly` | `monthly`), `resetTime` (`HH:MM`). Format lama `{keyId, limit, period}` mengembalikan `400 Bad Request`. ## Batas Token Anggaran **token** per kunci API (berbeda dari Anggaran berbasis USD di atas). Diberlakukan langsung pada jalur permintaan: ketika penggunaan pada jendela saat ini untuk suatu kunci mencapai batasnya, permintaan akan ditolak dengan `429 Too Many Requests`. Batas dapat dicakup ke `model` tertentu, `provider`, atau diterapkan secara `global` di seluruh kunci; ketika beberapa batas cocok dengan suatu permintaan, batas yang paling ketat akan berlaku. ```bash # Menampilkan batas token suatu kunci (termasuk penggunaan jendela secara langsung) GET /api/usage/token-limits?apiKeyId=key-123 # Membuat atau memperbarui batas token POST /api/usage/token-limits Content-Type: application/json { "apiKeyId": "key-123", "scopeType": "model", "scopeValue": "openai/gpt-4o", "tokenLimit": 1000000, "resetInterval": "monthly", "enabled": true } # Menghapus batas token berdasarkan id DELETE /api/usage/token-limits?id=tl-abc ``` > **Catatan skema** (`setTokenLimitSchema`): `apiKeyId` dan `scopeType` (`model` | `provider` | `global`) wajib diisi. `scopeValue` wajib diisi kecuali jika `scopeType` adalah `global` (misalnya id model untuk cakupan `model`, atau id penyedia untuk cakupan `provider`). `tokenLimit` harus berupa bilangan bulat positif (dikonversi dari string). Opsional: `id` (hilangkan untuk membuat, sertakan untuk memperbarui), `resetInterval` (`daily` | `weekly` | `monthly`, nilai bawaan `monthly`), `resetTime` (`HH:MM`), `enabled` (nilai bawaan `true`). Respons `GET` memperkaya setiap batas dengan `tokensUsed`, `remaining`, `windowStart`, `periodStartAt`, dan `nextResetAt`. Ini adalah endpoint kelas manajemen (autentikasi diberlakukan secara terpusat oleh pipeline otorisasi). ## Pemrosesan Permintaan 1. Klien mengirim permintaan ke `/v1/*` 2. Penangan rute memanggil `handleChat`, `handleEmbedding`, `handleAudioTranscription`, atau `handleImageGeneration` 3. Model ditentukan (penyedia/model langsung atau alias/kombo) 4. Kredensial dipilih dari DB lokal dengan pemfilteran ketersediaan akun 5. Untuk percakapan: `handleChatCore` memeriksa cache semantik/tanda tangan dan menentukan pengaturan kompresi kombo 6. Kompresi proaktif berjalan sebelum penerjemahan penyedia ketika diaktifkan (`lite`, Caveman, RTK, atau bertumpuk) 7. Eksekutor penyedia mengirim permintaan ke hulu 8. Respons diterjemahkan kembali ke format klien (percakapan) atau dikembalikan apa adanya (embedding/gambar/audio) 9. Penggunaan, analitik kompresi, dan log permintaan dicatat 10. Fallback diterapkan saat terjadi kesalahan sesuai dengan aturan kombo Referensi arsitektur lengkap: [`ARCHITECTURE.md`](../architecture/ARCHITECTURE.md) --- ## Manajemen Kombo Kombo perutean tingkat tinggi (yang telah dirangkum di bawah `/api/combos*`) juga dapat dipetakan 1:1 dari pola id model, sehingga memungkinkan pengalihan transparan dari id model bergaya OpenAI ke suatu kombo. | Metode | Jalur | Deskripsi | | ------ | -------------------------------- | ------------------------------------------------------------------------------- | | GET | `/api/model-combo-mappings` | Menampilkan semua pemetaan model→kombo | | POST | `/api/model-combo-mappings` | Membuat pemetaan — isi: `{pattern, comboId, priority?, enabled?, description?}` | | GET | `/api/model-combo-mappings/[id]` | Mengambil satu pemetaan | | PUT | `/api/model-combo-mappings/[id]` | Memperbarui bidang dari pemetaan yang sudah ada | | DELETE | `/api/model-combo-mappings/[id]` | Menghapus pemetaan | **Autentikasi:** sesi/kunci API manajemen (`requireManagementAuth`). --- ## Webhook Langganan webhook keluar untuk peristiwa OmniRoute (penyelesaian permintaan, habisnya kuota, rotasi kunci, dll.). | Metode | Path | Deskripsi | | ------ | ------------------------- | ----------------------------------------------------------------------------- | | GET | `/api/webhooks` | Mencantumkan webhook (rahasia disamarkan menjadi `...`) | | POST | `/api/webhooks` | Membuat webhook — body: `{url, events?: ["*"], secret?, description?}` | | GET | `/api/webhooks/[id]` | Mengambil webhook | | PUT | `/api/webhooks/[id]` | Memperbarui url/events/secret/description | | DELETE | `/api/webhooks/[id]` | Menghapus webhook | | POST | `/api/webhooks/[id]/test` | Mengirim payload pengujian ke URL webhook dan mengembalikan status pengiriman | **Autentikasi:** sesi manajemen/kunci API (`requireManagementAuth`). --- ## Kunci Terdaftar (Pengelolaan Otomatis) Digunakan oleh subsistem pengelolaan kunci otomatis untuk menerbitkan dan merotasi kunci API melalui penyedia/akun pendukung, dengan kuota harian/per jam. | Metode | Path | Deskripsi | | ------ | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/registered-keys` | Mencantumkan kunci terdaftar (hanya prefiks yang disamarkan) | | POST | `/api/v1/registered-keys` | Menerbitkan kunci terdaftar baru — body: `{name, provider?, accountId?, idempotencyKey?, expiresAt?, dailyBudget?, hourlyBudget?}`. Mengembalikan kunci mentah **satu kali**. Mengembalikan `429` jika ditolak karena kuota. | | GET | `/api/v1/registered-keys/[id]` | Mengambil metadata kunci terdaftar (tanpa materi kunci mentah) | | DELETE | `/api/v1/registered-keys/[id]` | Mencabut kunci terdaftar | | POST | `/api/v1/registered-keys/[id]/revoke` | Endpoint pencabutan eksplisit (efeknya sama dengan DELETE) | **Autentikasi:** Kunci API Bearer (`isAuthenticated`). Lihat juga `/v1/quotas/check` dan `/v1/issues/report`. --- ## Protokol Agen Tugas agen cloud (Claude Code, Codex Cloud, OpenHands, dll.) yang dijalankan dari jarak jauh atas nama pengguna OmniRoute. | Metode | Jalur | Deskripsi | | ------ | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/agents/tasks` | Daftar tugas — opsional `?provider=`, `?status=`, `?limit=` (1–500, default 50) | | POST | `/api/v1/agents/tasks` | Buat tugas — isi divalidasi oleh `CreateCloudAgentTaskSchema` (`providerId`, `prompt`, `source`, `options?`). Mengembalikan `201` dengan amplop tugas | | DELETE | `/api/v1/agents/tasks?id=...` | Hapus tugas | | GET | `/api/v1/agents/tasks/[id]` | Baca tugas — menyegarkan status secara sinkron dari agen cloud upstream saat `external_id` ditetapkan | | POST | `/api/v1/agents/tasks/[id]` | Tindakan terdiskriminasi: `{action: "approve"}`, `{action: "message", message}`, atau `{action: "cancel"}` | | DELETE | `/api/v1/agents/tasks/[id]` | Hapus tugas tertentu berdasarkan id | > **Autentikasi:** autentikasi manajemen diwajibkan pada setiap metode (`requireCloudAgentManagementAuth`). Sebelum v3.8.0, metode-metode ini tidak memerlukan autentikasi — lihat commit `588a0333` untuk perubahan yang merusak kompatibilitas tersebut. ```bash # Buat tugas cloud Claude Code 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":"..."}}' ``` --- ## Proksi Manajemen Proksi HTTP(S)/SOCKS keluar yang dapat ditetapkan ke penyedia, akun, atau secara global. | Metode | Jalur | Deskripsi | | ------ | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/management/proxies` | Daftar proksi (dengan `?id=` mengembalikan satu proksi; dengan `?id=&where_used=1` mengembalikan grafik penetapan) | | POST | `/api/v1/management/proxies` | Buat proksi — isi divalidasi oleh `createProxyRegistrySchema` | | PATCH | `/api/v1/management/proxies` | Perbarui proksi — isi divalidasi oleh `updateProxyRegistrySchema` (memerlukan `id`) | | DELETE | `/api/v1/management/proxies?id=...&force=1` | Hapus proksi (gunakan `force=1` untuk melepaskan penetapan) | | GET | `/api/v1/management/proxies/assignments` | Daftar penetapan — dapat difilter berdasarkan `proxy_id`, `scope`, `scope_id`; teruskan `resolve_connection_id=` untuk menentukan proksi aktif bagi suatu koneksi | | PUT | `/api/v1/management/proxies/assignments` | Tetapkan — isi divalidasi oleh `proxyAssignmentSchema` (`{scope, scopeId?, proxyId?}`). Menghapus cache dispatcher | | PUT | `/api/v1/management/proxies/bulk-assign` | Tetapkan secara massal — isi divalidasi oleh `bulkProxyAssignmentSchema` (`{scope, scopeIds[], proxyId?}`) | | GET | `/api/v1/management/proxies/health?hours=24` | Agregat kesehatan proksi (jumlah berhasil/gagal, latensi) selama suatu rentang waktu | **Autentikasi:** sesi manajemen/kunci API pada setiap rute (`requireManagementAuth`). > `POST /api/v1/management/proxies/[id]/assignments` dan `POST /api/v1/management/proxies/[id]/health` dalam deskripsi tugas dilayani oleh rute datar `/assignments` dan `/health` yang ditampilkan di atas — tidak ada subrute per-id dalam basis kode. --- ## Ketahanan (diperluas) OmniRoute menyediakan tiga mekanisme kegagalan sementara yang independen; endpoint pengelolaan di bawah ini memungkinkan operator melihat dan mengganti pengaturannya: | Cakupan | Penyimpanan status | Baca | Atur ulang / hapus | | ------------------------ | ---------------------------------------- | ----------------------------------------- | ------------------------------------------------------------- | | Pemutus sirkuit penyedia | `domain_circuit_breakers` + dalam memori | `/api/monitoring/health` | `POST /api/resilience/reset` | | Masa tunggu koneksi | `rateLimitedUntil` pada koneksi penyedia | `/api/rate-limits`, `/api/providers/[id]` | (diaktifkan kembali secara malas; hapus melalui PUT penyedia) | | Penguncian model | Registri ketersediaan model dalam memori | `GET /api/resilience/model-cooldowns` | `DELETE /api/resilience/model-cooldowns` | `PATCH /api/resilience` menerima penggantian pemutus sirkuit penyedia melalui `providerBreaker.oauth` dan `providerBreaker.apikey`. Setiap profil mendukung `degradationThreshold`, `failureThreshold`, dan `resetTimeoutMs`; kolom yang sama tersedia di Dasbor → Pengaturan → Ketahanan. ```bash # Hapus penguncian satu model 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"}' # Hapus semua penguncian curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \ -H "Cookie: auth_token=..." \ -d '{"all":true}' ``` Untuk referensi konseptual lengkap dan nilai default pemutus sirkuit, lihat [`CLAUDE.md`](../../CLAUDE.md) → "Status Runtime Ketahanan". --- ## Keterampilan Kerangka kerja keterampilan untuk memperluas OmniRoute dengan handler khusus yang dapat dieksekusi, beserta integrasi marketplace. | Metode | Jalur | Deskripsi | | ------ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/skills` | Cantumkan keterampilan yang terinstal — dapat difilter berdasarkan `?q=`, `?mode=on\|off\|auto`, `?source=skillsmp\|skillssh\|local`, dengan paginasi | | GET | `/api/skills/[id]` | Ambil satu keterampilan | | PUT | `/api/skills/[id]` | Perbarui keterampilan (nama, deskripsi, mode, skema, handler, tag) | | DELETE | `/api/skills/[id]` | Hapus instalasi keterampilan | | POST | `/api/skills/install` | Instal keterampilan dari manifes mentah — isi: `{name, version, description, schema:{input, output}, handlerCode, apiKeyId?}` | | GET | `/api/skills/executions` | Cantumkan eksekusi keterampilan terbaru (jejak audit dengan input/output/durasi) | | GET | `/api/skills/marketplace?q=...` | Cari/daftar populer dari marketplace SkillsMP (memerlukan pengaturan `skillsmpApiKey`) | | POST | `/api/skills/marketplace/install` | Instal keterampilan berdasarkan id dari SkillsMP | | GET | `/api/skills/skillssh?q=&limit=` | Cari registri skills.sh | | POST | `/api/skills/skillssh/install` | Instal keterampilan berdasarkan id dari skills.sh | **Autentikasi:** sesi pengelolaan/kunci API. Rute pencarian marketplace menerima autentikasi pengelolaan atau kunci API Bearer (`isAuthenticated`). --- ## Memori Penyimpanan memori percakapan/faktual persisten, dengan cakupan per kunci API / sesi. | Metode | Jalur | Deskripsi | | ------ | -------------------- | -------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/memory` | Mencantumkan memori — `?apiKeyId=`, `?type=`, `?sessionId=`, `?q=`, dengan paginasi `offset/limit` atau `page/limit` | | POST | `/api/memory` | Membuat memori — isi permintaan divalidasi oleh Zod: `{content, key, type?, sessionId?, apiKeyId?, metadata?, expiresAt?}` | | GET | `/api/memory/[id]` | Mengambil satu memori | | DELETE | `/api/memory/[id]` | Menghapus memori | | GET | `/api/memory/health` | Kesehatan subsistem memori (konektivitas DB, backend embedding, status indeks vektor) | **Autentikasi:** sesi manajemen/kunci API (`requireManagementAuth`). Enum `type`: `FACTUAL`, `EPISODIC`, `SEMANTIC`, `PROCEDURAL` (lihat `MemoryType` di `src/lib/memory/types.ts`). --- ## Server MCP OmniRoute menyertakan server Model Context Protocol tersemat dengan 3 transportasi (stdio, SSE, streamable-http) dan alat dengan cakupan tertentu. Endpoint dasbor di bawah ini membaca data status/audit dan mem-proxy transportasi HTTP. | Metode | Jalur | Deskripsi | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------- | | GET | `/api/mcp/status` | Heartbeat, transportasi, status daring, panggilan terakhir, alat teratas, tingkat keberhasilan 24 jam | | GET | `/api/mcp/tools` | Daftar alat MCP dengan `name`, `description`, `scopes`, `phase`, `auditLevel`, `sourceEndpoints` | | GET | `/api/mcp/sse` | Membuka aliran SSE untuk transportasi SSE (mengembalikan `503` jika MCP dinonaktifkan atau transportasi tidak cocok) | | POST | `/api/mcp/sse` | Mengirim frame JSON-RPC melalui transportasi SSE | | GET | `/api/mcp/stream` | Membuka sisi SSE dari transportasi Streamable HTTP (pesan yang dimulai oleh server) | | POST | `/api/mcp/stream` | Mengirim frame JSON-RPC melalui transportasi Streamable HTTP | | DELETE | `/api/mcp/stream` | Mengakhiri sesi Streamable HTTP | | GET | `/api/mcp/audit` | Mengueri log audit — `?limit=`, `?offset=`, `?tool=`, `?success=true | false`, `?apiKeyId=` | | GET | `/api/mcp/audit/stats` | Statistik audit agregat (total, tingkat keberhasilan, durasi rata-rata, alat teratas) | **Autentikasi:** transportasi `sse`/`stream` mengikuti mekanisme autentikasi khusus MCP (kunci API Bearer dengan cakupan `mcp`); rute `status`/`tools`/`audit*` dapat dibaca dari dasbor (tidak diperlukan autentikasi tambahan selain kemampuan mengakses host dasbor). > Kedua transportasi HTTP dikontrol oleh `settings.mcpEnabled` dan `settings.mcpTransport` — ketidakcocokan transportasi mengembalikan `400`, sedangkan status MCP yang dinonaktifkan mengembalikan `503`. --- ## Server A2A OmniRoute menyediakan endpoint A2A (Agent-to-Agent) JSON-RPC 2.0 beserta pembungkus REST untuk keperluan inspeksi/dasbor. ### JSON-RPC ```bash POST /a2a Authorization: Bearer your-api-key # opsional kecuali OMNIROUTE_API_KEY ditetapkan Content-Type: application/json { "jsonrpc": "2.0", "id": 1, "method": "message/send", "params": { "skill": "smart-routing", "messages": [{"role": "user", "content": "Route this coding task"}] } } ``` Metode yang didukung (semuanya bergantung pada `settings.a2aEnabled`): | Metode | Deskripsi | | ---------------- | ------------------------------------------------------------------- | | `message/send` | Eksekusi skill sinkron; mengembalikan `{task, artifacts, metadata}` | | `message/stream` | Eksekusi SSE streaming dari kumpulan skill yang sama | | `tasks/get` | Mengambil tugas berdasarkan `taskId` | | `tasks/cancel` | Membatalkan tugas berdasarkan `taskId` | Skill bawaan: `smart-routing`, `quota-management`, `provider-discovery`, `cost-analysis`, `health-report`. ### Kartu Agen ```bash GET /.well-known/agent.json ``` Mengembalikan kartu agen A2A publik (nama, deskripsi, kapabilitas, katalog skill, skema autentikasi) — disimpan dalam cache publik selama 1 jam. Tidak memerlukan autentikasi. ### Pembantu REST | Metode | Jalur | Deskripsi | | ------ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | GET | `/api/a2a/status` | Status aktif A2A + statistik tugas + ringkasan kartu agen yang di-cache | | GET | `/api/a2a/tasks` | Mencantumkan tugas — `?state=submitted\|working\|completed\|failed\|cancelled`, `?skill=`, `?limit=` (≤200), `?offset=` | | POST | `/api/a2a/tasks` | (Tidak diimplementasikan sebagai pembantu REST — buat melalui JSON-RPC `message/send`) | | GET | `/api/a2a/tasks/[id]` | Mengambil satu tugas | | POST | `/api/a2a/tasks/[id]/cancel` | Membatalkan tugas | **Autentikasi:** pembantu REST berjalan tanpa autentikasi manajemen (dapat dibaca dasbor); rute JSON-RPC `/a2a` menggunakan Bearer `OMNIROUTE_API_KEY` jika dikonfigurasi. --- ## Cloud, Evaluasi & Penilaian | Metode | Jalur | Deskripsi | | ------ | ------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------- | ----------------------------------- | | POST | `/api/cloud/auth` | Memverifikasi kunci Bearer dan mengembalikan koneksi penyedia yang disamarkan + alias model untuk klien sinkronisasi cloud | | POST | `/api/cloud/credentials/update` | Memperbarui kredensial terenkripsi untuk penyedia yang disinkronkan dengan cloud | | POST | `/api/cloud/model/resolve` | Memetakan id model logis ke penyedia/model konkret menggunakan tabel perutean lokal | | GET | `/api/cloud/models/alias` | Mencantumkan alias model sebagaimana diekspos ke sinkronisasi cloud | | GET | `/api/assess` | Membaca kategorisasi penilaian terbaru (per penyedia/model) | | POST | `/api/assess` | Menjalankan penilaian — body: `{scope: {type:"all"} | {type:"provider", providerId} | {type:"model", modelId}, trigger?}` | | GET | `/api/evals` | Mencantumkan rangkaian evaluasi bawaan + proses terbaru | | POST | `/api/evals` | Memicu proses evaluasi | | POST | `/api/evals/suites` | Membuat rangkaian evaluasi khusus — body divalidasi oleh `evalSuiteSaveSchema` | | GET | `/api/evals/suites/[id]` | Mengambil rangkaian evaluasi khusus | **Autentikasi:** `/api/cloud/auth` memvalidasi kunci Bearer secara langsung; rute `/api/cloud/*`, `/api/evals/*`, dan `/api/assess` lainnya memerlukan sesi/kunci API manajemen. POST `/api/assess` menggunakan `validateBody` dengan skema cakupan discriminated-union. --- ## Pengelolaan ACP (Agent Client Protocol) sebagai proses anak. Endpoint ini mengelola deteksi agen ACP dan pendaftaran agen khusus. | Metode | Path | Deskripsi | | ------ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/acp/agents` | Mencantumkan semua agen CLI yang diketahui (bawaan + khusus) beserta status instalasi, versi, dan biner | | POST | `/api/acp/agents` | Mendaftarkan agen ACP khusus atau menyegarkan cache — isi: `{id, name, binary, versionCommand, providerAlias, spawnArgs, protocol}` atau `{action: "refresh"}` | | DELETE | `/api/acp/agents` | Menghapus agen ACP khusus — parameter kueri: `?id=` | **Contoh respons** (`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 } ``` **Autentikasi:** Memerlukan sesi pengelolaan (cookie `auth_token` dasbor) atau kunci API dengan cakupan pengelolaan. Lihat [Kerangka Kerja ACP](../frameworks/ACP.md) untuk detail lengkap. --- ## Analitik & Observabilitas Endpoint analitik real-time untuk memantau perutean, kompresi, dan keragaman penyedia. Endpoint ini mendukung halaman `/dashboard/analytics/*`. ### Analitik perutean otomatis | Metode | Path | Deskripsi | | ------ | ------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/auto-routing` | Statistik agregat perutean otomatis: total panggilan, distribusi strategi, distribusi tingkat, penyedia teratas | | GET | `/api/analytics/auto-routing?days=7` | Statistik berdasarkan rentang waktu (default 24 jam) | **Contoh respons**: ```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 } ] } ``` ### Analitik kompresi | Metode | Path | Deskripsi | | ------ | ---------------------------- | --------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/compression` | Statistik agregat kompresi: token yang dihemat, persentase penghematan, distribusi mode, penggunaan mesin | **Contoh respons**: ```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 } } ``` ### Pelacakan keragaman penyedia | Metode | Path | Deskripsi | | ------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------ | | GET | `/api/analytics/diversity` | Pelacakan keragaman berbasis entropi Shannon: mencegah titik kegagalan tunggal dengan mengukur persebaran penyedia | **Contoh respons**: ```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"] } ``` **Autentikasi:** Memerlukan sesi pengelolaan atau kunci API dengan cakupan pengelolaan. --- ## Operasi Admin Endpoint khusus admin untuk manajemen operasional. | Metode | Jalur | Deskripsi | | ------ | ------------------------ | --------------------------------------------------------------------------------------------- | | GET | `/api/admin/concurrency` | Membaca batas konkurensi saat ini (global + per penyedia) | | POST | `/api/admin/concurrency` | Memperbarui batas konkurensi — isi: `{global?: number, perProvider?: Record}` | **Autentikasi:** Memerlukan sesi manajemen dengan cakupan admin. --- ## Manajemen Alat CLI Kelola alat CLI yang terintegrasi dengan OmniRoute (antigravity, chipotle, commandCode, devin-cli, dll.). Lihat [Referensi Penyedia](./PROVIDER_REFERENCE.md) untuk daftar lengkap. | Metode | Jalur | Deskripsi | | ------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/cli-tools/all-statuses` | Status semua alat CLI (terinstal, versi, terakhir terlihat) | | GET | `/api/cli-tools/status` | Detail status untuk satu alat CLI (kueri `?tool=`) | | POST | `/api/cli-tools/apply` | Menulis konfigurasi yang dihasilkan alat (`dryRun` menampilkan pratinjau; `422` + `containerEphemeralTarget` saat dijalankan dalam kontainer; `migration` mencatat YAML Codex lama) | | GET | `/api/cli-tools/backups` | Mencantumkan cadangan konfigurasi alat CLI | | POST | `/api/cli-tools/backups` | Membuat cadangan semua konfigurasi alat CLI | | POST | `/api/cli-tools/backups` | Memulihkan: endpoint yang sama dengan `{tool, backupId}` dalam isi akan memulihkan cadangan tersebut | | GET | `/api/cli-tools/antigravity-mitm` | Status proksi MITM Antigravity (alat CLI "antigravity-mitm") | | POST | `/api/cli-tools/antigravity-mitm/alias` | Mengonfigurasi alias antigravity-mitm | **Autentikasi:** Memerlukan sesi manajemen. --- ## Keterampilan Agen Kelola keterampilan agen AI (serupa dengan GPT khusus milik OpenAI, tetapi untuk agen). | Metode | Jalur | Deskripsi | | ------ | ---------------------------- | ------------------------------------------------------------------------------------------- | | GET | `/api/agent-skills` | Mencantumkan semua keterampilan agen (bawaan + kustom) | | GET | `/api/agent-skills/[id]` | Mendapatkan keterampilan agen tertentu | | POST | `/api/agent-skills` | Membuat keterampilan agen kustom — isi: `{name, description, prompt, model?, temperature?}` | | PUT | `/api/agent-skills/[id]` | Memperbarui keterampilan agen kustom | | DELETE | `/api/agent-skills/[id]` | Menghapus keterampilan agen kustom | | GET | `/api/agent-skills/[id]/raw` | Mendapatkan prompt mentah + metadata (tanpa eksekusi) | | POST | `/api/agent-skills/generate` | Menghasilkan keterampilan baru dengan AI dari deskripsi bahasa alami | **Autentikasi:** Memerlukan sesi manajemen atau kunci API dengan cakupan manajemen. --- ## Manajemen Cache Kelola cache semantik dan cache penalaran. | Metode | Path | Deskripsi | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/cache` | Ikhtisar cache: jumlah total entri, tingkat hit, ukuran pada disk | | GET | `/api/cache/entries` | Daftar entri yang disimpan dalam cache (dengan paginasi) | | DELETE | `/api/cache/entries` | Hapus entri cache (filter berdasarkan parameter kueri) | | GET | `/api/cache/stats` | Statistik cache terperinci (per penyedia, per model) | | GET | `/api/cache/reasoning` | Status cache penalaran (untuk pemutaran ulang penalaran) | | DELETE | `/api/cache/reasoning` | Bersihkan cache penalaran — parameter kueri: `?toolCallId=` (tunggal), `?provider=

`, atau tanpa parameter (semua) | **Autentikasi:** Memerlukan sesi manajemen. --- ## Sistem Memori Kelola memori persisten (FTS5 + embedding vektor). | Metode | Path | Deskripsi | | ------ | ------------------ | ---------------------------------------------------------------------------- | | GET | `/api/memory` | Daftar entri memori (filter berdasarkan cakupan, jenis, dan kueri pencarian) | | POST | `/api/memory` | Buat entri memori baru — isi: `{scope, type, content, metadata?}` | | GET | `/api/memory/[id]` | Dapatkan entri memori tertentu | | PUT | `/api/memory/[id]` | Perbarui entri memori | | DELETE | `/api/memory/[id]` | Hapus entri memori | | GET | `/api/memory?q=` | Cari memori (FTS5 + vektor) — statistik disertakan dalam respons yang sama | **Autentikasi:** Memerlukan sesi manajemen atau kunci API dengan cakupan manajemen. --- ## Webhook Kelola langganan webhook untuk berbagai peristiwa. | Metode | Path | Deskripsi | | ------ | ------------------------------- | ----------------------------------------------------------------- | | GET | `/api/webhooks` | Daftar semua langganan webhook | | POST | `/api/webhooks` | Buat langganan webhook — isi: `{url, events[], secret?, active?}` | | GET | `/api/webhooks/[id]` | Dapatkan langganan webhook tertentu | | PUT | `/api/webhooks/[id]` | Perbarui langganan webhook | | DELETE | `/api/webhooks/[id]` | Hapus langganan webhook | | GET | `/api/webhooks/[id]/deliveries` | Daftar riwayat pengiriman webhook (log keberhasilan/kegagalan) | | POST | `/api/webhooks/[id]/test` | Kirim peristiwa pengujian ke webhook | **Autentikasi:** Memerlukan sesi manajemen. Lihat [Kerangka Kerja Webhook](../frameworks/WEBHOOKS.md) untuk daftar lengkap jenis peristiwa. --- ## Kerangka Kerja Skills Kelola Skills (kerangka kerja ekstensi agentik). | Metode | Jalur | Deskripsi | | ------ | ------------------------ | --------------------------------------------------------------------------------------------- | | GET | `/api/skills` | Cantumkan semua skill yang terinstal (bawaan + kustom) | | POST | `/api/skills/install` | Instal skill dari jalur lokal atau URL | | DELETE | `/api/skills/[id]` | Hapus instalasi skill | | PUT | `/api/skills/[id]` | Aktifkan atau nonaktifkan skill — body: `{enabled?: boolean, mode?: "on" \| "off" \| "auto"}` | | POST | `/api/skills/executions` | Jalankan skill — body: `{skillName, apiKeyId, input?, sessionId?}` | | GET | `/api/skills/executions` | Cantumkan riwayat eksekusi untuk semua skill (filter berdasarkan `?apiKeyId=`) | **Autentikasi:** Memerlukan sesi manajemen atau kunci API dengan cakupan manajemen. Lihat [Kerangka Kerja Skills](../frameworks/SKILLS.md) untuk detail lengkap. --- ## Plugin Kelola plugin OmniRoute (ekstensi pihak ketiga). | Metode | Jalur | Deskripsi | | ------ | ---------------------------------- | ------------------------------- | | GET | `/api/plugins` | Cantumkan plugin yang terinstal | | POST | `/api/plugins/marketplace/install` | Instal plugin dari marketplace | | DELETE | `/api/plugins/[name]` | Hapus instalasi plugin | | POST | `/api/plugins/[name]/activate` | Aktifkan plugin | | POST | `/api/plugins/[name]/deactivate` | Nonaktifkan plugin | | GET | `/api/plugins/[name]/config` | Dapatkan konfigurasi plugin | | PUT | `/api/plugins/[name]/config` | Perbarui konfigurasi plugin | **Autentikasi:** Memerlukan sesi manajemen. Lihat [Kerangka Kerja Plugin](../frameworks/PLUGIN_SDK.md) untuk detail lengkap. --- ## Shadow Routing Perbandingan shadow/A-B antarpenyedia **bukan antarmuka REST mandiri** — ini dikonfigurasi melalui combo routing (lihat [Auto-Combo](../routing/AUTO-COMBO.md)). Metrik perbandingan per combo disediakan oleh `GET /api/combos/metrics`. --- ## Guardrail Periksa guardrail runtime (deteksi PII, deteksi prompt injection, vision bridging). Guardrail dijalankan pada setiap permintaan; penonaktifan per panggilan dilakukan melalui header permintaan `x-omniroute-disabled-guardrails` — tidak tersedia antarmuka pengaktifan/penonaktifan yang persisten. | Metode | Jalur | Deskripsi | | ------ | ---------------------- | ----------------------------------------------------------------------------------------------- | | GET | `/api/guardrails` | Cantumkan guardrail yang terdaftar beserta statusnya (nama/diaktifkan/prioritas) | | POST | `/api/guardrails/test` | Lakukan uji coba pipeline prapanggilan pada input sampel — body: `{input, disabledGuardrails?}` | **Autentikasi:** Memerlukan sesi manajemen. Lihat [Keamanan > Guardrail](../security/GUARDRAILS.md) untuk detail lengkap. --- --- ## Autentikasi Lihat [Autentikasi Manajemen](../guides/MANAGEMENT-AUTH.md) untuk empat kelompok kredensial (sesi dashboard, token CLI lokal, Token Akses `oma_live_…`, kunci API dengan cakupan manajemen) dan perbedaannya dengan kunci inferensi. - Rute dashboard (`/dashboard/*`) menggunakan cookie `auth_token` - Login menggunakan hash kata sandi yang tersimpan; dengan fallback ke `INITIAL_PASSWORD` - `requireLogin` dapat diaktifkan atau dinonaktifkan melalui `/api/settings/require-login` - Rute `/v1/*` secara opsional memerlukan kunci API Bearer ketika `REQUIRE_API_KEY=true` - "token manajemen" / "kunci API dengan cakupan manajemen" dalam referensi ini berarti salah satu kelompok dalam panduan tersebut — bukan jenis rahasia tambahan yang tidak didefinisikan > **Perubahan yang merusak kompatibilitas (v3.8.0)** — `/api/v1/agents/tasks/*` dan endpoint manajemen cooldown kini memerlukan **autentikasi manajemen** (cookie `auth_token` dashboard atau kunci API dengan cakupan manajemen). Klien yang sebelumnya memanggil rute-rute ini tanpa autentikasi akan menerima `401 Unauthorized`. Lihat commit `588a0333` (`fix(auth): require management auth for agent and cooldown APIs`).