GET /v1/models
GET /v1/models 返回 cc-router 对外暴露的固定虚拟模型清单。该清单不反映上游订阅,而是一份硬编码的别名表,用于让 Claude Code / Claude Desktop / Codex CLI / Open WebUI 等任何讲 Anthropic 或 OpenAI 协议的客户端看到一致的虚拟模型列表。三个对话入口(/v1/messages、/v1/responses、/v1/chat/completions)共用这一份清单。
适用版本:cc-router v3.0.0 及以上。
设计变更(v3.0+:Anthropic + OpenAI 字段超集)
为了让同一路径既被 Anthropic SDK 也被 OpenAI SDK / OpenAI Responses 客户端使用,cc-router 把 /v1/models 改成 Anthropic /v1/models schema + OpenAI /v1/models schema 的字段超集:
| 字段 | 来源协议 | 说明 |
|---|---|---|
type: "model" | Anthropic | Anthropic SDK 检查 |
id | 共用 | 两边都用 |
display_name | Anthropic | Anthropic SDK 用作展示名 |
created_at(ISO 字符串) | Anthropic | 硬编码 "2026-01-01T00:00:00Z" |
object: "model" | OpenAI | OpenAI SDK 检查 |
created(Unix 秒) | OpenAI | 硬编码 1767225600(= created_at 同一时刻) |
owned_by: "cc-router" | OpenAI | OpenAI SDK 用作 owner 展示 |
两边 SDK 都按 extra: allow 忽略未知字段,因此同一份 JSON 对两边都合法。
外层 wrapper 也是超集:
| 字段 | 来源协议 |
|---|---|
object: "list" | OpenAI(list wrapper) |
data: [...] | 两边共用 |
has_more: false | Anthropic(page wrapper) |
first_id / last_id | Anthropic |
请求
GET /v1/models
- 无 query 参数、无 body
- 无鉴权(白名单,与
/health、所有OPTIONS同列) - 响应:
200 OK,Content-Type: application/json
响应
数据条目当前共 30 条:16 条 Anthropic 风格 + 14 条 OpenAI 风格。
{
"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 分组
| 分组 | ID | 命中虚拟模型 |
|---|---|---|
| 虚拟模型短名 | model-fable / model-opus / model-sonnet / model-haiku | 各自同名槽位 |
| Anthropic 版本号 | claude-fable-5 / claude-opus-4-7 / claude-sonnet-4-6 / claude-haiku-4-5 | model-fable / model-opus / model-sonnet / model-haiku |
anthropic/ 前缀(版本号) | anthropic/claude-{fable,opus,sonnet,haiku}-* | 同上 |
anthropic/ 前缀(短名) | anthropic/model-{fable,opus,sonnet,haiku} | 同上 |
| OpenAI 版本号别名 | gpt-5.6 / gpt-5.5 / gpt-5.4 / gpt-5.4-mini | model-fable / model-opus / model-sonnet / model-haiku |
| OpenAI 档位别名 | gpt-5.6-sol / gpt-5.6-terra / gpt-5.6-luna | model-fable / model-opus / model-sonnet |
openai/ 前缀 | 上面两组 OpenAI 别名加 openai/ 前缀,共 7 条 | 同上 |
- 清单只是示例名,解析时按规则匹配,不在清单里的写法也能用:比如
claude-opus-4-8、gpt-6-sol都能正确路由。完整规则见 接口总览 → 虚拟模型与别名。- 有些客户端只展示自己协议风格的模型名。比如 Claude Desktop 的模型发现只认 Anthropic 风格,会显示「found 16 models」,这是正常的。
与官方 /v1/models 的差异
| 差异点 | cc-router | 官方 Anthropic / OpenAI |
|---|---|---|
| 数据来源 | 固定 30 个 ID(硬编码在源码) | 动态返回该 API Key 可访问的全部模型 |
created_at / created | 硬编码 2026-01-01T00:00:00Z / 1767225600 | 各模型真实发布时间 |
| 分页 | has_more 永远 false,无 before_id / after_id 支持 | 支持分页 |
model-fallback | 不在列表中(只能隐式触发) | 不适用 |
| 字段 | Anthropic + OpenAI 超集 | 各自只有自己字段 |
返回固定清单是为了让任何 Anthropic / OpenAI 客户端不管 cc-router 接了哪些上游订阅,看到的可用模型清单都一致——它们都是 cc-router 的虚拟模型,真实路由在 POST /v1/messages、POST /v1/responses 或 POST /v1/chat/completions 时按虚拟模型映射决定。
示例
# 列出所有虚拟模型 ID
curl -s http://127.0.0.1:23456/v1/models | jq '.data[].id'
# 用 OpenAI SDK 风格枚举
curl -s http://127.0.0.1:23456/v1/models | jq '.data[] | {id, owned_by}'
# 用 Anthropic SDK 风格枚举
curl -s http://127.0.0.1:23456/v1/models | jq '.data[] | {id, display_name, created_at}'
GET /health
/health 是 cc-router 自定义的诊断口,常和 /v1/models 一起出现在白名单里。
GET /health
- 无参数、无 body、无鉴权
- 响应:
200 OK,Content-Type: text/plain; charset=utf-8,body 为字符串ok
$ curl -i http://127.0.0.1:23456/health
HTTP/1.1 200 OK
content-type: text/plain; charset=utf-8
ok
用途:
- 启动脚本探测 cc-router 是否已就绪
- 反向代理(nginx / caddy)做 upstream health check
- 浏览器手动验证服务存活
/health 不返回 JSON,也不暴露内部状态(版本号、订阅数、上游健康等都没有)。这些信息走 Tauri IPC 给 UI 用,不通过 HTTP 暴露。