Лимиты запросов
Каждый тариф задает лимит в запросах в минуту: 20, 40 или 120. amodb считает запросы в скользящем окне 60 секунд. Каждый ответ содержит X-RateLimit-Limit, X-RateLimit-Remaining и X-RateLimit-Reset. При превышении лимита приходит HTTP 429 со status_code 25 и заголовком Retry-After в секундах. Ответы из кэша тоже учитываются.
Лимиты по тарифам
| Запросов в минуту | Запросов в день на полной скорости |
|---|---|
| 20 | 28,800 |
| 40 | 57,600 |
| 120 | 172,800 |
Все тарифы включают одни и те же эндпоинты и данные. Названия и цены тарифов смотрите на странице цены.
Как работает окно
amodb считает запросы каждого ключа за последние 60 секунд. Окно скользит: запрос, сделанный в 12:00:30, перестает учитываться в 12:01:30. В начале минуты сброса нет, поэтому ровный поток запросов работает лучше, чем всплески.
Проверка ключа и лимит запросов выполняются раньше кэша edge. Ответ, отданный из кэша, все равно считается за один запрос.
Заголовки ответа
Каждый вызов с ключом возвращает эти заголовки:
| Заголовок | Значение |
|---|---|
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.