Model Endpoints
Endpoints for registered models, routing, tiers, quota and audio models.
| Method | Path | Description |
|---|---|---|
GET |
/v1/models |
List registered models (OpenAI {data:[...]} shape, auto included) |
GET |
/v1/models/*id |
Read one registered model |
POST DELETE |
/v1/models · /v1/models/*name |
local — add / remove a model |
GET POST |
/v1/model |
local — model routing in one object: dispatcher, dispatcher_beta, summary, image, stt, tts, plus image_options, image_providers and audio_providers on read. The fields hold two different kinds of value. dispatcher, summary, stt and tts name a registered model (prefix@model) — stt and tts are drawn from GET /v1/model/audio, not from the session model registry. image names an image model as provider@model since v1.0.13 — image_options is now probed from each credentialed provider (cached for 15 minutes since v1.0.18) (openai, grok, grok-oauth, gemini, and openrouter since v1.0.17) with an image-only model filter, so the choice is a model rather than an endpoint. codex is the exception and still appears as the bare provider name, and a bare provider name stored from an earlier version is still accepted. image_providers and audio_providers remain the full provider catalogs (image_providers is openai, codex, grok, grok-oauth, gemini, openrouter; audio_providers is openai, gemini, openrouter). dispatcher_beta is a boolean added in v1.0.18 that routes through the TypeSafe dispatcher instead of dispatcher; setting it to true without a TYPESAFE_API_KEY in the keychain returns 400 with missing_key. The global auto_reasoning toggle was removed in v1.1.0 — set a session's reasoning to auto instead, and the model selector picks the level per request from the kind of work. POST is a partial update — a field left out (or null) is untouched, "" clears it, and off is an alias of "" for image. An unregistered model, an unknown provider, or a provider with no credentials is rejected and nothing is written |
GET |
/v1/model/quota |
local — added in v1.1.0. ?model=<prefix>@<model> returns {quota}: that model's provider quota as a display string ("42%" for codex, grok-oauth, copilot, ollama-cloud, claude-code; "$12.34" for openrouter, deepseek), or "" when the provider reports no quota, has no credential, or the read fails. Read live (15 s ceiling, no cache). The dashboard fetches it after a completion instead, since quota was removed from completion events and channel footers in v1.1.0 |
GET |
/v1/model/audio |
local — stt_options and tts_options: the speech-to-text and text-to-speech models reachable with the credentials stored right now, fetched from OpenAI, Gemini and OpenRouter (added in v1.0.17) and returned as provider@model; since v1.0.18 each provider's answer is cached for 15 minutes, with the same invalidation as /v1/provider/:provider/models. These are the only values POST /v1/model accepts for stt / tts |
GET POST |
/v1/model/priority |
local — fallback order of the registered models: after the selected model fails, the others are tried top to bottom. Since v1.1.0 pass-tier models are skipped (v1.0.20 through v1.0.27 still tried them at their place in the order). GET returns models (names in order), tiers (the model_tag map, model → tier) and tier_options ({tier, detail} rows, "" first for no tier). POST {models} moves the listed names to the front in that order and keeps the rest after them; an unknown name returns 400 |
POST |
/v1/model/tier |
local — {model, tier}. Sets one registered model's tier: S, A, B, C, or pass (since v1.1.0 never picked by auto routing or subagents, even when the request names it, and skipped by fallback; it still runs when set as a session's own model); "" clears it. An unregistered model or unknown tier returns 400 |