# 认证与 API Key

> API Key 的携带方式、可设置的限制、调用前的检查顺序与预扣规则，以及泄露后的吊销。

来源：https://www.scirouter.cn/docs/authentication · 更新于 2026-10-24

所有 `/v1` 接口使用 API Key 认证，Key 放在 `Authorization` 请求头中：

```http
Authorization: Bearer YOUR_API_KEY
```

## 请求头

| 请求头 | 取值 | 说明 |
|---|---|---|
| `Authorization` | `Bearer <API Key>` | 对所有 `/v1` 接口有效。`Bearer` 后为空时视为未携带该请求头 |
| `x-api-key` | API Key | Anthropic SDK 的默认写法（见 [Messages（Anthropic 格式）](https://www.scirouter.cn/docs/messages)），对所有 `/v1` 接口有效 |

- 两个请求头同时携带时须为同一个 Key，否则返回 401 `unauthenticated`。
- 只接受以上两种方式。Cookie、查询参数与 `api-key` 请求头均不作为凭据。
- 网关收到 `/v1` 请求时丢弃 `Cookie` 请求头。浏览器中的 SciRouter 登录会话不作为调用凭据，其他网页无法借用登录会话调用模型、消耗配额。

## Key 格式

Key 的明文以 `sk-sr-` 开头，后接 40 位字母数字，共 46 位。格式错误或 Key 不存在时返回 401 `unauthenticated`。格式错误最常见的原因是填入了 OpenAI、Anthropic 等厂商的 Key，此时 `message` 提示改用 SciRouter 的 Key。

## 平台 Key 与厂商 Key

对话补全、Messages（Anthropic 格式）与 Responses（OpenAI Responses 格式）三种格式只接受 SciRouter 控制台创建的 Key。

每次调用由平台使用该 Key 鉴权、检查白名单与配额、按平台的价格计费并选择线路；调用厂商时使用平台在该厂商的账号与凭据。请求携带 OpenAI、Anthropic 等厂商的 Key 时返回 401。SciRouter 的 Key 不会发送给任何厂商。

文档中的「原样转发」指请求体的格式与字段原样到达厂商，鉴权与计费仍由平台完成。

各 SDK 与工具读取的环境变量名由其自身定义（`OPENAI_API_KEY`、`ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN`、Codex 的 `env_key`），取值均填 SciRouter 的 Key。本机已设置厂商官方 Key 的，替换为 SciRouter 的 Key，或确认指向 SciRouter 的工具读取的是另一个变量。

## Key 的设置

在控制台的 [API Keys 页面](https://www.scirouter.cn/console/keys)新建 Key。以下设置均只约束该 Key：

| 设置 | 作用 | 超出限制时 |
|---|---|---|
| 名称 | 用于识别 | — |
| 限定模型 | 模型白名单，留空表示不限。控制台一次选择一个模型 | 403 `model_not_allowed`，`details.scope` 为 `key`；`GET /models` 只列出白名单内的模型 |
| 月度配额上限 | 该 Key 每个自然月（北京时间）可消耗的配额。不填表示不限，填 0 表示不能产生任何消费 | 429 `key_quota_exceeded`，次月恢复 |
| 有效期 | 到期后自动失效，不设置表示不过期 | 401 `key_expired` |
| 归属项目 | 将 Key 归入一个项目：项目有独立的模型白名单与月预算，用量按项目归账。个人工作区可选；团队工作区必须选择一个团队项目，调用扣除团队的配额 | 项目白名单外：403 `model_not_allowed`，`details.scope` 为 `project`；超出预算：429 `project_budget_exceeded`，`Retry-After` 到次月 1 日；项目已归档：422 `project_archived` |

- 除归属项目外，其他设置创建后不能修改；需要变更时新建 Key 并吊销旧 Key。
- 归属项目可以修改，只能在同一工作区内移动。
- 每个账户最多保留 50 个有效的 Key。
- 明文只在创建时显示一次，平台只保存其哈希，关闭创建窗口后无法再次获取。创建后立即复制，存入密钥管理工具或环境变量。

## 环境变量

Key 存入环境变量，不写入代码：

```bash
export SCIROUTER_API_KEY="YOUR_API_KEY"
```

官方 OpenAI SDK（Python 与 Node）读取 `OPENAI_API_KEY` 与 `OPENAI_BASE_URL` 两个环境变量。不修改现有代码时，将这两个变量指向 SciRouter（`model` 仍需换成平台的模型 id）：

```bash
export OPENAI_API_KEY="$SCIROUTER_API_KEY"
export OPENAI_BASE_URL="https://api.scirouter.cn/v1"
```

## 浏览器端调用

`/v1` 的 CORS 对所有来源开放（不带凭证），浏览器可以直接调用。直接调用会将 Key 暴露给每个打开网页的用户，任何人都可从开发者工具中获取。浏览器、App 与小程序中的调用经调用方自己的后端转发。

[Playground](https://www.scirouter.cn/playground) 与站内 Chat 使用登录会话，不经过 API Key 明文。

## 按用途划分 Key

按服务、环境或实验分别创建 Key：

- 泄露时只需吊销对应的 Key，其他服务不受影响；
- 用量与日志按 Key 分开统计；
- 白名单与月度配额上限可按用途设置。例如为批量评测所用的 Key 设置月度上限，失控时消耗不超过该上限。

同一个 Key 下需要进一步区分（如十个实验共用一个 Key）时，在请求体的 `metadata` 中添加标签，见[可观测性](https://www.scirouter.cn/docs/observability)。

## 泄露与吊销

Key 泄露时，在控制台吊销该 Key，然后新建 Key 替换。吊销立即生效（极少数情况下最迟 1 分钟），不可撤销；此后使用该 Key 的请求返回 401 `key_revoked`。

Key 不支持暂停，只能吊销。

| 情况 | 结果 |
|---|---|
| 成员被移出团队 | 该成员在团队项目下创建的 Key 一并吊销 |
| 团队被停用 | 团队项目下的 Key 调用返回 403 `team_suspended` |

## 调用前的检查

每次调用按以下顺序检查，任一步未通过即返回错误，不调用上游：

| 顺序 | 检查项 | 未通过时 |
|---|---|---|
| 1 | 认证：Key 格式正确、存在、未吊销、未过期，账户未停用 | 401 `unauthenticated` / `key_revoked` / `key_expired` / `account_suspended` |
| 2 | 请求与模型：模型存在；模型不在维护或停用状态；`max_tokens` 不超过模型与套餐的单次上限 | 404 `model_not_found`；503 `model_unavailable`；400，`details.limit` 为上限 |
| 3 | 授权：模型在 Key 的白名单、Key 所属项目的白名单与套餐内；受限模型还要求调用所在的团队已获授权 | 403 `model_not_allowed`，`details.scope` 指明未通过的一层；403 `model_restricted` |
| 4 | 配额：依次检查 Key 的月度上限、项目的月预算、套餐的日上限，本次花费按输入估算加输出上限全额估计 | 429 `key_quota_exceeded`；429 `project_budget_exceeded`；429 `rate_limited`，`Retry-After` 到次日零点 |
| 5 | 限频：每分钟请求数、每分钟 token 数（按估算）与并发请求数，Key 与账户各计一份。账户指个人账户；团队项目下的 Key 计入团队 | 429 `rate_limited`，`details.scope` 为 `key` / `personal` / `team`；模型的全站并发已满时返回 503 `model_unavailable`，`details.reason` 为 `model_busy`，带 `Retry-After` |
| 6 | 预扣：按估算成本冻结一笔配额（有下限），调用结束后按实际用量结算，多退少补 | 402 `insufficient_quota`，见[预扣](#预扣) |

- 第 4 步比较的是「已用量 + 本次全额估算」，接近上限时估算值大的请求先被拒绝。充值余额大于 0 的账户，第 6 步的预扣只按输出预留估，两者不是同一个数。
- 每分钟请求数在第 4 步之前先预检一次，命中响应缓存的请求也计入。因此限频的 429 可能先于配额的 429 出现。

## 预扣

估算值 = 输入估算 + 输出上限。输出上限即 `max_tokens`，未传时为平台为该请求确定的上限（模型与套餐上限中较小的值，见[对话补全](https://www.scirouter.cn/docs/chat-completions)「max_tokens」）。

账户的充值余额大于 0 时，对话请求的输出只按输出预留估算：输出预留是输出上限与平台设定值中的较小者，因此 `max_tokens` 写得大不会多冻结配额。充值余额为 0 或为负（只有赠送额度、或已透支）的账户按输出上限全额估算。

调用结束后按实际用量结算：实际花费超过预扣的部分照扣，配额可能因此变为负数，之后的请求返回 402 `insufficient_quota`，充值后恢复。余额不足以冻结估算值时返回 402：`details.required_quota` 为本次需冻结的配额，团队账户另带 `details.account_kind: "team"`。

Key 月度上限、项目月预算与套餐每日上限仍按输入估算加输出上限全额判断。

命中响应缓存的请求只计一次请求数，不检查配额、不预扣、不扣费，见[缓存与幂等](https://www.scirouter.cn/docs/caching)。

## 余量查询

- 限频余量在响应头 `x-ratelimit-{limit,remaining,reset}-{requests,tokens}` 中，取 Key 与账户两份中更紧的一份。套餐不限的项不返回，并发数没有对应的响应头。
- 配额与预算在控制台查看，见[可观测性](https://www.scirouter.cn/docs/observability)。
