---
title: "请求与响应头"
description: "pirouter 网关会读的请求头和会写的响应头。本页列出每个头的含义、出现在哪些响应里，以及浏览器里调用时允许带哪些请求头。"
canonical: "https://pirouter.ai/zh/docs/headers"
last-updated: "2026-10-17"
lang: "zh"
source: "content/docs/zh/(start)/headers.mdx"
---

# 请求与响应头

pirouter 网关会读的请求头和会写的响应头。本页列出每个头的含义、出现在哪些响应里，以及浏览器里调用时允许带哪些请求头。

本页列出 pirouter 网关在推理端点上写的响应头和会读的请求头。三种协议的端点相同。

## 响应头

下表由 API 规范生成，说明是规范原文。每个响应头后面列出它会出现在哪些状态码的响应里，`default` 指规范没有单列的其它错误状态（`500`、`503` 等）。

| 响应头                             | 出现于                                                               | 说明                                                                                                                                                       |
| ------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Pi-Trace-Id`                 | `200`, `400`, `401`, `402`, `404`, `413`, `422`, `429`, `default` | 平台请求 id，由网关生成。推理端点的每个响应都带；反馈问题时请附上它。                                                                                                                     |
| `X-Pi-Provider`                 | `200`, `default`                                                  | 处理这次响应的 provider，取值与 `provider.order`、`GET /v1/models/{vendor}/{model}/endpoints` 同一套词表。只有上游 provider 作出应答时才有（一次补全或一次上游错误）；发生 fallback 后是接手的那个 provider。 |
| `X-Pi-Model`                    | `200`, `default`                                                  | 处理这次响应的模型 slug，与响应体里的 `model` 是同一个值。由 fallback 模型接手时就是那个模型。只有上游 provider 作出应答时才有。                                                                        |
| `X-Pi-Upstream-Model`           | `200`, `default`                                                  | 上游 provider 在它自己的响应里报告的完整模型 id，原样透传（流式时取自第一个数据事件）。上游响应没有给出模型时不带这个头；不会用平台自己的记录补上。                                                                         |
| `X-Pi-Upstream-Request-Id`      | `200`, `default`                                                  | 上游 provider 自己的请求 id，原样透传，用于在 provider 一侧查这次调用。provider 没有返回时不带这个头。                                                                                      |
| `Access-Control-Allow-Origin`   | `200`, `400`, `401`, `402`, `404`, `413`, `422`, `429`, `default` | 恒为 `*`。凭证是携带 API key 的请求头，从不是 cookie。                                                                                                                    |
| `Access-Control-Expose-Headers` | `200`, `400`, `401`, `402`, `404`, `413`, `422`, `429`, `default` | 列出每一个 `X-Pi-*` 响应头，外加 `Retry-After` 与 `Content-Encoding`，让浏览器里的代码能读到它们。                                                                                  |

### 哪些响应带 `X-Pi-Provider`

`X-Pi-Provider`、`X-Pi-Model`、`X-Pi-Upstream-Model`、`X-Pi-Upstream-Request-Id` 只出现在 provider 真正答复过的响应上，成功和 provider 返回的错误都算。`X-Pi-Upstream-Model` 和 `X-Pi-Upstream-Request-Id` 还要 provider 自己给出了这个值才有。

下面这些响应四个都不带，只有 `X-Pi-Trace-Id` 和 CORS 头：

- 网关自己的拒绝：鉴权、余额、限流、参数校验、没有可用的 provider。
- 等 provider 开始返回超过 90 秒的请求。响应头在 provider 答复之前就已发出，见[长请求](https://pirouter.ai/zh/docs/errors.md#长请求)。

一个例外：provider 拒绝了 pirouter 自己的凭证（上游 `401` 或 `403`，不是你的 key 的问题），而且没有被别的 provider 接手时，你收到的是 `503` 和错误码 `provider_unavailable`。这个响应带 `X-Pi-Provider` 和 `X-Pi-Model`，指出是哪一家拒绝的；不带两个 `X-Pi-Upstream-*` 头。

### `Retry-After`

被 pirouter 限流时（`429`，错误码 `rate_limited`），响应带 `Retry-After`，值是到下一个整分钟的秒数，在 1 到 60 之间。见[限流](https://pirouter.ai/zh/docs/rate-limits.md)。

### provider 的响应头

provider 自己的响应头不转发，只放行下面五个：`Content-Type`、`Content-Length`、`Content-Encoding`、`Cache-Control`、`Retry-After`。所以 provider 自己给的 `Retry-After` 会随它的 `429` 或 `503` 一起到你手里。流式响应不带 `Content-Length`。网关代替 provider 答复的错误（例如上面的 `503`）这五个也不带。

### 固定的安全头

每个响应都带下面这些头，值不变：

| 响应头                         | 值                                          |
| --------------------------- | ------------------------------------------ |
| `X-Content-Type-Options`    | `nosniff`                                  |
| `X-Frame-Options`           | `DENY`                                     |
| `Referrer-Policy`           | `strict-origin-when-cross-origin`          |
| `Content-Security-Policy`   | `frame-ancestors 'none'`                   |
| `Permissions-Policy`        | `camera=(), microphone=(), geolocation=()` |
| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains`      |

## 请求头

### `Authorization` 与 `X-Api-Key`

key 放在 `Authorization: Bearer` 或 `X-Api-Key` 里，两个都有时以 `Authorization` 为准。`x-goog-api-key` 不读。读取顺序和三家 SDK 的写法见[在请求里带上 key](https://pirouter.ai/zh/docs/authentication.md#在请求里带上-key)。

### 可选的请求头

下面三个请求头都可以不带，带了也不影响回答的内容。

| 请求头               | pirouter 怎么用                                                                                                       |
| ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| `X-Pi-Session-Id` | 会话 ID，最多 256 个字符，更长的视为没带。同一工作区、同一 key、同一模型、同一会话 ID 的请求，优先发到这个会话上次被选中的那个上游部署，前提是它仍然满足路由条件。记忆保留 1 小时，每次请求被放行后重新计时    |
| `X-Title`         | 你的应用名。pirouter 去掉控制字符和不可见字符，最多保留 128 个字符后记下。控制台 **用量** 页的「工具」排行用它和 `HTTP-Referer` 识别常见的应用与客户端，没有识别出来的归入「其它应用（未识别）」 |
| `HTTP-Referer`    | 你的应用的网址。只记 origin（协议、主机和端口），只接受 `http` 和 `https`；没有这个头时读标准的 `Referer`。值不合规只是不记，请求照常处理                              |

这三个请求头会随请求一起转发给 provider，不要在里面放敏感信息。

控制台的 **日志** 目前不显示这三个值。

## 在浏览器里调用

浏览器发出的 `OPTIONS` 预检请求不需要 key，网关直接回 `204`，并带上允许的方法（`POST, GET, OPTIONS`）、允许的请求头和 `Access-Control-Max-Age: 86400`。

允许的请求头是一份固定的清单：三种协议的鉴权头（`Authorization`、`X-Api-Key`、`x-goog-api-key`），`Content-Type`，`anthropic-version`、`anthropic-beta`、`anthropic-dangerous-direct-browser-access`，上面的 `X-Title`、`HTTP-Referer`、`X-Pi-Session-Id`，以及官方 SDK 在浏览器里自动带上的 `OpenAI-Organization`、`OpenAI-Project` 和 `X-Stainless-*`。清单外的请求头会让浏览器的预检失败；在服务器上调用不受这份清单限制。

`Access-Control-Allow-Origin` 是 `*`，凭证在请求头里，不用 cookie。`Access-Control-Expose-Headers` 列出全部 `X-Pi-*` 响应头和 `Retry-After`、`Content-Encoding`，所以浏览器里的代码能读到它们。

## 下一步

- [限流](https://pirouter.ai/zh/docs/rate-limits.md): 429 什么时候出现，要等多久再重试。
- [错误码](https://pirouter.ai/zh/docs/errors.md): 每个错误码的含义和处理办法。
