# AI Gateway API 文档 ## Base URL ``` https://你的域名 ``` ## 认证方式 ### 管理后台认证 (Session Cookie) 登录成功后通过 `Set-Cookie` 写入 `session_id`(HttpOnly、Secure、SameSite=Lax,有效期 7 天)。后续所有 `/admin/*` 请求需携带该 Cookie。 | 端点 | 方法 | 说明 | |------|------|------| | `/admin/login` | GET | 登录页面 | | `/admin/login` | POST | 登录提交 | | `/admin/logout` | GET | 退出登录 | #### POST /admin/login 提交 JSON 进行登录校验(用户名明文比对,密码 SHA-256 哈希比对)。 **请求体**: ```json { "username": "admin", "password": "your_password" } ``` **成功响应** (`200`): ```json { "success": true, "message": "登录成功" } ``` **失败响应**: | 状态码 | 场景 | 响应 | |--------|------|------| | 400 | 用户名/密码为空 | `{ "success": false, "message": "请输入用户名和密码" }` | | 401 | 用户名或密码错误 | `{ "success": false, "message": "用户名或密码错误" }` | | 500 | 未配置管理员账号 | `{ "success": false, "message": "未配置管理员账号,请在 Cloudflare 环境变量中设置 ADMIN_USERNAME 和 ADMIN_PASSWORD" }` | #### GET /admin/logout 删除当前 Session 并清除 Cookie,重定向到首页 (`/`)。 --- ### API 转发认证 (Bearer Token) 所有 `/v1/*` 请求需在 Header 中携带转发 API Key(即管理后台生成的 `sk_cf_*`): ``` Authorization: Bearer sk_cf_xxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` **失败响应** (`401`): ```json { "error": { "message": "缺少或无效的 Authorization 头,格式: Bearer sk_cf_*", "type": "authentication_error" } } ``` 或 ```json { "error": { "message": "API Key 无效或已禁用", "type": "authentication_error" } } ``` ## API 端点 ### 公开端点 #### GET / 首页,返回站点信息与所有已启用提供商/模型列表(无需认证)。 --- ### API 转发端点(需 Bearer Token) #### GET /v1/models 返回所有已启用的模型列表(提供商与模型均需处于启用状态)。 **响应**: ```json { "object": "list", "data": [ { "id": "deepseek/deepseek-chat", "provider": "deepseek", "provider_name": "DeepSeek", "object": "model", "created": 1712345678, "owned_by": "deepseek" } ] } ``` --- #### POST /v1/chat/completions 转发 OpenAI 兼容的聊天补全请求。 **请求体**: ```json { "model": "deepseek/deepseek-chat", "messages": [{"role": "user", "content": "Hello!"}] } ``` 模型格式: `提供商ID/模型ID` **响应**: 透传 AI 提供商的原始响应(含流式响应)。 --- #### POST /v1/messages 转发 Anthropic 兼容的 Messages 请求。需将模型指定为 `anthropic/<模型ID>`。 **请求体**: ```json { "model": "anthropic/claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "Hello!"}], "max_tokens": 1024 } ``` **响应**: 透传 Anthropic 的原始响应。 --- #### ALL /v1/* 其他 `/v1/*` 子路径请求会原样透传到对应提供商。转发逻辑: 1. 解析 `model` 字段中的 `提供商ID/模型ID`,定位提供商与模型配置 2. 校验提供商/模型是否启用、是否配置了可用 API Key 3. 将请求体中的 `model` 改写为纯 `模型ID`,路径去除 `/v1/` 前缀拼接到提供商 `baseUrl` 4. **Key 排序与健康检查**: - 读取该提供商下每个 Key 的历史健康状态(基于 KV 持久化) - **健康 Key**(无失败记录):Fisher-Yates 洗牌后优先使用 - **不健康 Key**(有失败记录,< 3 次):追加到队列末尾 - **降权 Key**(连续失败 >= 3 次):进入冷却排除,**1 小时后自动恢复试用** - **试用 Key**(冷却到期):追加到不健康 Key 之后,限试一次 - 仅有 1 个 Key 时跳过所有健康检查 5. 按排序后的顺序依次尝试;遇 `401/403/429/5xx` 或网络错误时标记该 Key 失败(`failures++`、`demotedAt` 刷新)并切换下一个,成功时重置该 Key 的健康状态 **Key 健康状态**存储在 KV 中(`key:health:{providerId}`),每次请求后更新,仅保留有失败记录的 Key。 > Anthropic 协议的提供商请求会使用 `x-api-key` + `anthropic-version: 2023-06-01` 头;OpenAI 协议使用 `Authorization: Bearer ` 头。请求超时为 60 秒。 --- ### 管理 API 端点(需 Session 认证) 所有 `/admin/api/*` 端点需先登录并携带 Session Cookie,未登录返回 `401`: ```json { "success": false, "message": "未登录" } ``` Session 过期返回 `401`: ```json { "success": false, "message": "Session 已过期" } ``` #### GET /admin/api/status 获取系统状态总览。 **响应**: ```json { "success": true, "data": { "providersCount": 4, "enabledProvidersCount": 4, "modelsCount": 12, "enabledModelsCount": 12, "proxyKeysCount": 2, "adminConfigured": true, "baseUrl": "https://your-domain.com" } } ``` | 字段 | 说明 | |------|------| | `providersCount` | 提供商总数 | | `enabledProvidersCount` | 已启用提供商数 | | `modelsCount` | 模型总数 | | `enabledModelsCount` | 已启用模型数 | | `proxyKeysCount` | 已启用的转发 Key 数 | | `adminConfigured` | 是否已配置 `ADMIN_USERNAME` / `ADMIN_PASSWORD` | | `baseUrl` | 当前部署的根域名 | --- #### GET /admin/api/providers 获取所有提供商列表(含完整 API Key)。 **响应**: ```json { "success": true, "data": [ { "id": "deepseek", "name": "DeepSeek", "baseUrl": "https://api.deepseek.com", "apiType": "openai", "apiKeys": [ { "key": "sk-xxx1", "enabled": true }, { "key": "sk-xxx2", "enabled": false } ], "models": [ { "id": "deepseek-chat", "enabled": true }, { "id": "deepseek-reasoner", "enabled": false } ], "enabled": true, "createdAt": "2024-01-01T00:00:00.000Z", "updatedAt": "2024-01-01T00:00:00.000Z" } ] } ``` --- #### POST /admin/api/providers 添加新提供商。 **请求体**: ```json { "id": "my-provider", "name": "我的提供商", "baseUrl": "https://api.example.com", "apiType": "openai", "apiKeys": ["sk-xxx"], "models": ["model-1", "model-2"], "enabled": true } ``` | 字段 | 必填 | 说明 | |------|------|------| | `id` | ✅ | 提供商唯一标识,需全局唯一 | | `name` | ✅ | 显示名称 | | `baseUrl` | ✅ | 提供商 API 基础地址,尾部 `/` 会被自动去除 | | `apiType` | ❌ | `openai`(默认)或 `anthropic` | | `apiKeys` | ❌ | 字符串数组或 `{key, enabled}` 对象数组 | | `models` | ❌ | 字符串数组或 `{id, enabled}` 对象数组 | | `enabled` | ❌ | 默认 `true` | **成功响应** (`201`): 返回新建的 Provider 对象。 **冲突响应** (`409`): `提供商 id "my-provider" 已存在`。 --- #### PUT /admin/api/providers/:id 更新提供商配置。`id`、`baseUrl`、`apiType` 等字段均可更新,`updatedAt` 自动刷新。 **请求体**(所有字段可选): ```json { "name": "新名称", "baseUrl": "https://new-api.example.com", "apiType": "anthropic", "apiKeys": [{"key": "sk-new-key", "enabled": true}], "models": [{"id": "new-model", "enabled": true}], "enabled": false } ``` > `apiKeys` / `models` 传数组时为**整体替换**,支持字符串数组或 `{key/id, enabled}` 对象数组。 **成功响应**: 返回更新后的 Provider 对象。 **未找到** (`404`): `提供商不存在`。 --- #### DELETE /admin/api/providers/:id 删除提供商。 **成功响应**: ```json { "success": true, "message": "提供商已删除" } ``` --- #### POST /admin/api/providers/:id/test-model 测试指定提供商下某个模型的连接是否可用。发送最小请求(`max_tokens: 1`,超时 15 秒)。 **请求体**: ```json { "modelId": "deepseek-chat" } ``` **响应**: ```json { "success": true, "data": { "success": true, "message": "连接成功", "statusCode": 200 } } ``` > `data.success` 表示实际连接是否成功;外层 `success` 固定为 `true` 表示测试流程本身执行完成。 --- #### POST /admin/api/test-key 测试指定 API Key 的连接是否可用(用于"添加新提供商"表单,无需提供商已保存)。通过服务端代理请求上游 `/models` 端点,避免浏览器跨域限制。 **请求体**: ```json { "url": "https://api.deepseek.com", "apiKey": "sk-xxx", "apiType": "openai" } ``` | 字段 | 必填 | 说明 | |------|------|------| | `url` | ✅ | API 基础地址,尾部 `/` 会被自动去除 | | `apiKey` | ✅ | 待测试的 API Key | | `apiType` | ❌ | `openai`(默认)或 `anthropic` | **成功响应**: ```json { "success": true, "data": { "success": true, "statusCode": 200, "data": { "object": "list", "data": [...] } } } ``` > 连接成功时 `data.data` 包含上游返回的模型列表;连接失败时 `data.success` 为 `false`,`statusCode` 为 `0`(网络错误)或具体 HTTP 状态码。 --- #### POST /admin/api/test-model 测试指定模型的连接是否可用(用于"添加新提供商"表单)。通过服务端代理请求上游 `/chat/completions` 或 `/messages` 端点,避免浏览器跨域限制。 **请求体**: ```json { "url": "https://api.deepseek.com", "apiKey": "sk-xxx", "apiType": "openai", "model": "deepseek-chat" } ``` | 字段 | 必填 | 说明 | |------|------|------| | `url` | ✅ | API 基础地址 | | `apiKey` | ✅ | 待测试的 API Key | | `apiType` | ❌ | 决定使用 `/chat/completions`(openai)或 `/messages`(anthropic) | | `model` | ✅ | 模型 ID | **成功响应**: ```json { "success": true, "data": { "success": true, "statusCode": 200 } } ``` --- #### GET /admin/api/proxy-keys 获取所有转发 API Key 列表。返回的 `key` 字段会做脱敏处理(仅显示前 8 位 + `****` + 后 4 位)。 **响应**: ```json { "success": true, "data": [ { "id": "uuid", "key": "sk_cf_xxxxxx****xxxx", "name": "测试 Key", "enabled": true, "createdAt": "2024-01-01T00:00:00.000Z", "expiresAt": null } ] } ``` --- #### POST /admin/api/proxy-keys 生成新的转发 API Key。Key 格式为 `sk_cf_` + 32 位随机 hex,**仅在此响应中返回完整明文,之后不再可见**。 **请求体**(全部可选): ```json { "name": "我的Key名称", "expiresIn": "90d" } ``` `expiresIn` 可选值: | 值 | 有效期 | |----|--------| | `30d` | 30 天 | | `90d` | 90 天 | | `180d` | 180 天 | | `1y` | 1 年(365 天) | | `forever` | 永久(默认) | **成功响应** (`201`): ```json { "success": true, "data": { "id": "uuid", "key": "sk_cf_abcdef0123456789abcdef0123456789", "name": "我的Key名称", "enabled": true, "createdAt": "2024-01-01T00:00:00.000Z", "expiresAt": "2024-04-01T00:00:00.000Z" }, "message": "请立即保存此 Key,关闭后将不再显示" } ``` --- #### PATCH /admin/api/proxy-keys/:id 更新转发 Key 的启用状态。 **请求体**: ```json { "enabled": false } ``` **成功响应**: 返回更新后的 ProxyKey 对象(key 仍为完整值)。 **未找到** (`404`): `转发 Key 不存在`。 --- #### DELETE /admin/api/proxy-keys/:id 删除转发 API Key。 **成功响应**: ```json { "success": true, "message": "转发 Key 已删除" } ``` --- ## 错误响应格式 所有 API 错误返回以下格式: ```json { "error": { "message": "错误描述", "type": "error_type" } } ``` 部分错误(如所有 Key 耗尽)会附带 `detail` 字段: ```json { "error": { "message": "所有 API Key 已用完,最后一次错误: HTTP 429", "type": "key_exhausted", "detail": "..." } } ``` 常见错误类型: | 类型 | 说明 | |------|------| | `authentication_error` | 认证失败(缺少/无效 Token 或 Session) | | `invalid_request_error` | 请求参数错误(如缺少 model、模型格式错误、提供商/模型不存在) | | `provider_disabled` | 提供商已禁用 | | `model_disabled` | 模型已禁用 | | `configuration_error` | 配置错误(如提供商未配置可用 API Key) | | `key_exhausted` | 所有 API Key 均失败 | | `proxy_error` | 转发过程出错(如网络异常) | | `server_error` | 服务器内部错误 | | `not_found` | 接口不存在(404) | 管理 API 的错误响应使用 `success: false` + `message` 的格式: ```json { "success": false, "message": "错误描述" } ```