GET /v1/models

GET /v1/models returns cc-router’s fixed list of virtual models. The list does not reflect upstream subscriptions — it is a hard-coded alias table so that Claude Code, Claude Desktop, Codex CLI, Open WebUI, and any other client speaking the Anthropic or OpenAI protocol all see the same virtual model catalog. The three chat endpoints (/v1/messages, /v1/responses, /v1/chat/completions) share this one list.

Applies to cc-router v3.0.0 and later.

Design change (v3.0+: Anthropic + OpenAI field superset)

To let one URL satisfy both Anthropic SDKs and OpenAI SDKs / OpenAI Responses clients, cc-router treats /v1/models as the superset of Anthropic /v1/models and OpenAI /v1/models schemas:

FieldSource protocolNotes
type: "model"AnthropicAnthropic SDK checks for it
idBothConsumed by both
display_nameAnthropicAnthropic SDK uses it for display
created_at (ISO string)AnthropicHard-coded "2026-01-01T00:00:00Z"
object: "model"OpenAIOpenAI SDK checks for it
created (Unix seconds)OpenAIHard-coded 1767225600 (same moment as created_at)
owned_by: "cc-router"OpenAIOpenAI SDK uses it as the owner label

Both SDKs use extra: allow and ignore unknown fields, so the same JSON is valid for both sides.

The outer wrapper is also a superset:

FieldSource protocol
object: "list"OpenAI (list wrapper)
data: [...]Both
has_more: falseAnthropic (page wrapper)
first_id / last_idAnthropic

Request

GET /v1/models
  • No query parameters, no body
  • No authentication (allowlisted alongside /health and all OPTIONS preflights)
  • Response: 200 OK, Content-Type: application/json

Response

The catalog currently has 30 entries: 16 Anthropic-style + 14 OpenAI-style.

{
  "object": "list",
  "data": [
    { "type": "model", "id": "model-fable",                 "display_name": "model-fable",                 "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "model-opus",                  "display_name": "model-opus",                  "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "model-sonnet",                "display_name": "model-sonnet",                "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "model-haiku",                 "display_name": "model-haiku",                 "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "claude-fable-5",              "display_name": "claude-fable-5",              "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "claude-opus-4-7",             "display_name": "claude-opus-4-7",             "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "claude-sonnet-4-6",           "display_name": "claude-sonnet-4-6",           "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "claude-haiku-4-5",            "display_name": "claude-haiku-4-5",            "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/claude-fable-5",    "display_name": "anthropic/claude-fable-5",    "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/claude-opus-4-7",   "display_name": "anthropic/claude-opus-4-7",   "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/claude-sonnet-4-6", "display_name": "anthropic/claude-sonnet-4-6", "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/claude-haiku-4-5",  "display_name": "anthropic/claude-haiku-4-5",  "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/model-fable",       "display_name": "anthropic/model-fable",       "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/model-opus",        "display_name": "anthropic/model-opus",        "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/model-sonnet",      "display_name": "anthropic/model-sonnet",      "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "anthropic/model-haiku",       "display_name": "anthropic/model-haiku",       "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "gpt-5.6",                     "display_name": "gpt-5.6",                     "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "gpt-5.5",                     "display_name": "gpt-5.5",                     "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "gpt-5.4",                     "display_name": "gpt-5.4",                     "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "gpt-5.4-mini",                "display_name": "gpt-5.4-mini",                "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "gpt-5.6-sol",                 "display_name": "gpt-5.6-sol",                 "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "gpt-5.6-terra",               "display_name": "gpt-5.6-terra",               "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "gpt-5.6-luna",                "display_name": "gpt-5.6-luna",                "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "openai/gpt-5.6",              "display_name": "openai/gpt-5.6",              "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "openai/gpt-5.5",              "display_name": "openai/gpt-5.5",              "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "openai/gpt-5.4",              "display_name": "openai/gpt-5.4",              "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "openai/gpt-5.4-mini",         "display_name": "openai/gpt-5.4-mini",         "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "openai/gpt-5.6-sol",          "display_name": "openai/gpt-5.6-sol",          "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "openai/gpt-5.6-terra",        "display_name": "openai/gpt-5.6-terra",        "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" },
    { "type": "model", "id": "openai/gpt-5.6-luna",         "display_name": "openai/gpt-5.6-luna",         "created_at": "2026-01-01T00:00:00Z", "object": "model", "created": 1767225600, "owned_by": "cc-router" }
  ],
  "has_more": false,
  "first_id": "model-fable",
  "last_id": "openai/gpt-5.6-luna"
}

ID groups

GroupIDsResolves to
Virtual model short namesmodel-fable / model-opus / model-sonnet / model-haikuThe slot of the same name
Anthropic versionedclaude-fable-5 / claude-opus-4-7 / claude-sonnet-4-6 / claude-haiku-4-5model-fable / model-opus / model-sonnet / model-haiku
anthropic/ prefix (versioned)anthropic/claude-{fable,opus,sonnet,haiku}-*Same as above
anthropic/ prefix (short)anthropic/model-{fable,opus,sonnet,haiku}Same as above
OpenAI versioned aliasesgpt-5.6 / gpt-5.5 / gpt-5.4 / gpt-5.4-minimodel-fable / model-opus / model-sonnet / model-haiku
OpenAI tier aliasesgpt-5.6-sol / gpt-5.6-terra / gpt-5.6-lunamodel-fable / model-opus / model-sonnet
openai/ prefixThe two OpenAI alias groups above with an openai/ prefix, 7 entriesSame as above
  • The list contains example names only; resolution is rule-based, so names not in the list work too — e.g. claude-opus-4-8 and gpt-6-sol both route correctly. See API Overview → Virtual models and aliases for the full rules.
  • Some clients only display model names in their own protocol’s style. For example, Claude Desktop’s model discovery only recognizes Anthropic-style names and reports “found 16 models” — this is expected.

Differences from the official /v1/models

Aspectcc-routerOfficial Anthropic / OpenAI
Data source30 fixed IDs (hard-coded)Dynamically returns models accessible to that API key
created_at / createdHard-coded 2026-01-01T00:00:00Z / 1767225600Each model’s real release timestamp
Paginationhas_more is always false; no before_id / after_idPaginated
model-fallbackNot in the list (only triggered implicitly)N/A
FieldsAnthropic + OpenAI supersetEach side only its own fields

A fixed list is returned so that any Anthropic or OpenAI client sees the same available models regardless of which upstream subscriptions cc-router is connected to — they are cc-router’s virtual models. The real routing is decided at POST /v1/messages, POST /v1/responses, or POST /v1/chat/completions time per the virtual-model mapping.


Examples

# List every virtual model ID
curl -s http://127.0.0.1:23456/v1/models | jq '.data[].id'

# Enumerate in OpenAI SDK style
curl -s http://127.0.0.1:23456/v1/models | jq '.data[] | {id, owned_by}'

# Enumerate in Anthropic SDK style
curl -s http://127.0.0.1:23456/v1/models | jq '.data[] | {id, display_name, created_at}'

GET /health

/health is cc-router’s own diagnostic endpoint, usually paired with /v1/models in the allowlist.

GET /health
  • No parameters, no body, no auth
  • Response: 200 OK, Content-Type: text/plain; charset=utf-8, body is the literal string ok
$ curl -i http://127.0.0.1:23456/health
HTTP/1.1 200 OK
content-type: text/plain; charset=utf-8

ok

Use cases:

  • Startup scripts checking whether cc-router is listening
  • Reverse proxy (nginx / caddy) upstream health checks
  • Quick browser-based liveness check

/health does not return JSON and does not expose any internal state (version, subscription count, upstream health, etc.). Those flow over Tauri IPC to the UI and are not surfaced via HTTP.