速率限制
按 API 密钥的请求限制、每个响应携带的响应头,以及智能体应如何自行控制节奏。
UnifAPI 只有一层请求限制:每个 API 密钥每 60 秒 60 次请求。限制作用于密钥,而不是工作区或端点——同一工作区的两个密钥不会争抢同一份额度,也没有哪个操作带有更严格的独立限制。
响应头
无论 2xx、4xx 还是 5xx,每个响应都会携带适用于它的额度,因此你无需发送探测请求就能知道当前状态。
| 响应头 | 含义 |
|---|---|
RateLimit-Policy | 以 IETF 结构化字段表示的策略:"api-key";q=60;w=60(q 为请求数,w 为窗口秒数) |
RateLimit | 相同格式的当前状态:"api-key";r=<剩余数>;t=<距离重置的秒数> |
RateLimit-Limit | 一个窗口内允许的请求数 |
RateLimit-Remaining | 当前窗口内剩余的请求数 |
RateLimit-Reset | 距离窗口重置还有多少秒——是相对值,不是 Unix 时间戳 |
X-RateLimit-Limit / -Remaining / -Reset | 上述三个响应头的别名,供只读取 X- 写法的客户端使用 |
Retry-After | 需要等待的秒数,随 UnifAPI 自身产生的 429 一起返回 |
未解析出 API 密钥的响应(例如 401)会返回额度充满的默认策略。它描述的是你完成认证后将面对的额度,而不是已经消耗的用量。
浏览器端调用也能读取全部这些响应头:它们已列入跨源响应的 Access-Control-Expose-Headers。
HTTP/1.1 200 OK
RateLimit-Policy: "api-key";q=60;w=60
RateLimit: "api-key";r=57;t=60
RateLimit-Limit: 60
RateLimit-Remaining: 57
RateLimit-Reset: 60窗口行为
窗口以该密钥最近一次请求为锚点:该密钥在一个完整窗口内没有任何调用后,计数器即被重置。没有突发余量,因此请按稳态速率而不是按攒下的余额来设计。
处理 429
async function call(url: string, init: RequestInit, attempt = 0): Promise<Response> {
const res = await fetch(url, init);
if (res.status !== 429 || attempt >= 5) return res;
const wait = Number(res.headers.get("Retry-After") ?? res.headers.get("RateLimit-Reset") ?? 1);
await new Promise((r) => setTimeout(r, wait * 1000));
return call(url, init, attempt + 1);
}两条应当遵守的规则:
- 在被限流之前就放慢节奏。 读取每个响应中的
RateLimit-Remaining,当它接近0时降低速度。等到收到429才开始调节,会让所有 worker 同时浪费一次往返。 - 遵守
Retry-After。 这是限流器真正需要的等待时间,靠猜通常只会更糟。如果该响应头缺失,就改用RateLimit-Reset。在429之后提高并发从来没有帮助——限制是按密钥计算的。
申请更高的限制
限制按密钥设置,因此提高上限属于配置调整而不是套餐升级。请发送邮件至 support@unifapi.com,附上你的工作区 ID、正在运行的 Skill 或操作,以及大致的 QPS 估算。