速率限制
每个套餐设定每分钟请求数:20、40 或 120,按滑动 60 秒窗口统计。每个响应带有 X-RateLimit-Limit、X-RateLimit-Remaining 和 X-RateLimit-Reset。超限返回 HTTP 429,缓存响应也计数。
窗口如何运作
amodb 统计每个密钥在过去 60 秒内的请求。窗口是滑动的:12:00:30 发出的请求在 12:01:30 停止计数。不会在整分钟重置,所以稳定的速率比突发请求更合适。
密钥检查和速率限制先于边缘缓存执行。从缓存返回的响应仍然算作一个请求。
响应头
每次带密钥的调用都会返回这些响应头:
| 响应头 | 含义 |
|---|---|
X-RateLimit-Limit | 此密钥每 60 秒允许的请求数。 |
X-RateLimit-Remaining | 当前窗口中剩余的请求数。 |
X-RateLimit-Reset | 距离最早被计入的请求离开窗口还有多少秒。 |
Retry-After | 仅在 429 时返回:下一次调用前要等待的秒数。 |
达到限制时
响应是 HTTP 429,响应体为 TMDB 的错误格式:
{
"success": false,
"status_code": 25,
"status_message": "Your request count (41) is over the allowed limit of (40)."
}等待 Retry-After 秒,然后重试。不要在紧凑的循环里重试。
async function amodb(path) {
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch(`https://api.amodb.dev${path}`, {
headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (res.status !== 429) return res.json();
const wait = Number(res.headers.get("Retry-After") ?? 1);
await new Promise((r) => setTimeout(r, wait * 1000));
}
throw new Error("amodb: still rate limited after 3 attempts");
}import os
import time
import requests
def amodb(path):
for _ in range(3):
res = requests.get(
f"https://api.amodb.dev{path}",
headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
timeout=10,
)
if res.status_code != 429:
return res.json()
time.sleep(int(res.headers.get("Retry-After", "1")))
raise RuntimeError("amodb: still rate limited after 3 attempts")保持在限制之内
- 在你这一侧缓存响应。详情很少变化,6 小时是安全的默认值。
- 用
append_to_response在一个请求中取得详情、演职员和图片,而不是发三个请求。 - 分散批处理任务:每分钟 40 个请求时,每 1.5 秒发一个请求。
- 读取
X-RateLimit-Remaining,在它降到 0 之前放慢速度。