---
title: "鉴权与 API key"
description: "pirouter 的每个请求都带一个 API key。本页说明 key 放在哪个请求头，怎么创建、到期和吊销，以及 key 目前不能做什么。"
canonical: "https://pirouter.ai/zh/docs/authentication"
last-updated: "2026-10-13"
lang: "zh"
source: "content/docs/zh/(start)/authentication.mdx"
---

# 鉴权与 API key

pirouter 的每个请求都带一个 API key。本页说明 key 放在哪个请求头，怎么创建、到期和吊销，以及 key 目前不能做什么。

每个请求都要带一个 pirouter 的 API key。同一个 key 在 OpenAI、Anthropic、Gemini 三种协议的端点上通用。

## 在请求里带上 key

网关按下面的顺序读 key：

1. 先读 `Authorization` 请求头。标准写法是 `Authorization: Bearer $PIROUTER_API_KEY`，不带 `Bearer ` 前缀、只放 key 本身也接受。
2. `Authorization` 没有值时，改读 `X-Api-Key` 请求头。

读到的值必须以 `sk-pi-` 开头，区分大小写。`Authorization` 里有值但不是 pirouter 的 key 时，请求直接被拒绝，不会再去读 `X-Api-Key`。

三家官方 SDK 默认使用的请求头不同：

| SDK              | 默认请求头                   | 要做的事                                                      |
| ---------------- | ----------------------- | --------------------------------------------------------- |
| OpenAI SDK       | `Authorization: Bearer` | 不用改                                                       |
| Anthropic SDK    | `x-api-key`             | 不用改                                                       |
| Google GenAI SDK | `x-goog-api-key`        | 网关不读这个头。创建客户端时另外加上 `Authorization: Bearer` 请求头，否则返回 `401` |

Anthropic 协议的请求用 `x-api-key`：

cURL:

```bash
curl https://api.pirouter.ai/v1/messages \
  -H "x-api-key: $PIROUTER_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5.5",
    "max_tokens": 1024,
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'
```

Python:

```python
import os
import anthropic

client = anthropic.Anthropic(
    base_url="https://api.pirouter.ai",
    api_key=os.environ["PIROUTER_API_KEY"],
)

message = client.messages.create(
    model="anthropic/claude-sonnet-5.5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(message.content[0].text)
```

TypeScript:

```ts
import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic({
  baseURL: 'https://api.pirouter.ai',
  apiKey: process.env.PIROUTER_API_KEY,
})

const message = await client.messages.create({
  model: 'anthropic/claude-sonnet-5.5',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
})
console.log(message.content[0].text)
```

Gemini 协议的请求把 key 放进 `Authorization`。用 Google GenAI SDK 时，在创建客户端的地方通过 `http_options`（TypeScript 是 `httpOptions`）的 `headers` 加上 `Authorization: Bearer`，SDK 的 `api_key` 参数照常传：

cURL:

```bash
curl "https://api.pirouter.ai/v1beta/models/google/gemini-3.5-flash:generateContent" \
  -H "Authorization: Bearer $PIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [{ "text": "Hello!" }] }]
  }'
```

Python:

```python
import os
from google import genai
from google.genai import types

client = genai.Client(
    api_key=os.environ["PIROUTER_API_KEY"],
    http_options=types.HttpOptions(
        base_url="https://api.pirouter.ai",
        headers={"Authorization": f"Bearer {os.environ['PIROUTER_API_KEY']}"},
    ),
)

response = client.models.generate_content(
    model="google/gemini-3.5-flash",
    contents="Hello!",
)
print(response.text)
```

TypeScript:

```ts
import { GoogleGenAI } from '@google/genai'

const ai = new GoogleGenAI({
  apiKey: process.env.PIROUTER_API_KEY,
  httpOptions: {
    baseUrl: 'https://api.pirouter.ai',
    headers: { Authorization: `Bearer ${process.env.PIROUTER_API_KEY}` },
  },
})

const response = await ai.models.generateContent({
  model: 'google/gemini-3.5-flash',
  contents: 'Hello!',
})
console.log(response.text)
```

只靠 SDK 默认的请求头，请求返回 `401`。

## 创建 key

1. **打开 API Keys**

   登录控制台，打开 **API Keys**，点 **创建密钥**。

   - [打开控制台](https://app.pirouter.ai): app.pirouter.ai

   只有工作区所有者能创建、重命名和吊销 key，其他成员只能查看列表。注册时自动建的个人工作区，所有者就是你自己。

2. **填名称，选有效期**

   名称长度 1 到 100 个字符。有效期有五个选项：永不过期、30 天、60 天、90 天、1 年，默认是永不过期。

3. **保存 key**

   你应该看到一个以 `sk-pi-` 开头的 key。它只显示这一次，复制后存进环境变量或你的密钥管理工具：

   ```bash
   export PIROUTER_API_KEY="sk-pi-..."
   ```

   关闭弹窗后，列表里只显示 key 的最后四位。

## 到期、重命名与吊销

- **到期**：过了有效期，key 自动失效，请求返回 `401` 和错误码 `api_key_expired`。有效期在创建时定下，之后不能修改。
- **重命名**：只改名称，key 本身不变，正在使用它的程序不受影响。
- **吊销**：立即生效，不能恢复。之后用它发的请求返回 `401` 和错误码 `api_key_revoked`。

## key 泄露了怎么办

1. 在 **API Keys** 里吊销这个 key。
2. 创建一个新 key，替换程序里的环境变量。
3. 打开 **日志**，按 API key 筛选，核对泄露期间有没有不是你发出的请求。

## 鉴权失败时的返回

鉴权失败一律返回 `401`。用响应体里的 `error.code` 区分原因：

| `error.code`        | 原因                        | 处理         |
| ------------------- | ------------------------- | ---------- |
| `invalid_api_key`   | 没带 key，或者值不是以 `sk-pi-` 开头 | 检查请求头和环境变量 |
| `api_key_not_found` | 格式正确，但没有这个 key            | 检查是否复制完整   |
| `api_key_revoked`   | key 已被吊销                  | 创建新 key    |
| `api_key_expired`   | key 已过有效期                 | 创建新 key    |

三种协议的端点返回同一种错误结构：

```json
{
  "error": {
    "message": "This API key is no longer active. It was revoked or has expired; create a new key in your pirouter console and use that instead.",
    "type": "authentication_error",
    "code": "api_key_revoked"
  }
}
```

程序里按 `error.code` 判断，不要匹配 `message` 的文字。

## 目前没有的能力

创建 key 时只能设置名称和有效期。下面这些目前没有：

- **按 key 的消费上限**。一个 key 可以用完所在工作区的全部余额。
- **按 key 的权限范围**。不能把一个 key 限定到某些模型或端点。
- **按 key 单独配置限流**。

需要隔离时，给每个环境或服务各建一个 key。这样可以单独吊销，也可以在日志里按 key 查看各自的用量。
