限流
每个响应带 3 个头:X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset。超了立刻返回 429,不扣费。
三个响应头
X-RateLimit-Limit
这个账户在一个周期里可以发多少个请求。
X-RateLimit-Remaining
现在还剩多少。
X-RateLimit-Reset
额度什么时候回满,Unix 秒。
没有带有效凭证的请求,回答里不带这三个头。
限的是什么
- 限的是账户:它名下所有 Key 共用一个额度。
- 有两个限制:一段时间里的请求数,和同时进行中的调用数。
- 现在的额度以响应头和
GET /v1/account(里面的rate)说的为准。账户第一次充值后额度会提高。 - 带 Key 的不收费地址(
/v1/account、/v1/usage、/v1/calls/…)用的是另一份额度,所以查一次调用不会占收费调用的额度。这些回答里的三个头说的是那一份。
bash
curl "https://api.dataxapi.com/v1/account" \ -H "Authorization: Bearer $DATAXAPI_API_KEY"
超限时
超限的请求立刻收到 429 rate_limited,没有执行,不扣费。reason 写明撞的是哪一个限制。
reason发生了什么等多久rate一段时间里请求太多。响应头 Retry-After(秒);报错体里的 retry_after_seconds 是同一个数。concurrency你同时进行中的调用太多。给不出时间:等你自己的一个调用结束。数据来源那边在限我们的时候,回的是 503 upstream_busy:不扣费,说得出要等多久时带 Retry-After。
重试
SDK 会自己重试:默认两次(maxRetries,Python 里是 max_retries),只重试服务说可以重试的,服务说等多久就等多久。要等超过一分钟的不等,直接把错误抛出来,上面带着要等的时间。
直接发 HTTP 请求时,几行就能做到同样的事:
ts
// One key for the call and every retry of it: a retry is then never charged twice. const key = crypto.randomUUID(); async function call(url: string): Promise<unknown> { for (let attempt = 0; ; attempt += 1) { const response = await fetch(url, { headers: { Authorization: `Bearer ${process.env.DATAXAPI_API_KEY}`, "Idempotency-Key": key }, }); const body = await response.json(); if (response.ok) return body; if (body.retry !== "yes" || attempt >= 2) throw new Error(body.code); // The wait the service names, or 1, 2, 4 seconds when it names none. const seconds = body.retry_after_seconds ?? 2 ** attempt; await new Promise((done) => setTimeout(done, seconds * 1000)); } }