Ошибки
Коды состояния HTTP и тело ошибки, которые возвращает API javinfo.
Неудачные запросы не тарифицируются. Вы платите только за 200.
Коды состояния
| Статус | Значение |
|---|---|
400 | Неверный запрос. Валидация не прошла (нет параметра, значение вне диапазона, неверный enum), у /query или /idols нет ни q, ни фильтра, или ID провайдера неизвестен. |
401 | API-ключ отсутствует или недействителен. |
402 | Кредитов не хватает. Retry-After — час, подсказка для автоматических клиентов; пополнение снимает блок сразу. См. тарификацию. |
404 | Результата нет. Возвращают /movie, /random, /idols/{id}, /discover/similar, поиски /analytics/idols/*, а также /resolve, /resolve/provenance и /resolve/streams. |
422 | Только /query: комбинацию фильтра и сортировки не поддерживает ни один провайдер, закреплённый не поддерживает, или вы ушли за 50-ю страницу без q. См. Фильтрацию. |
429 | Слишком много запросов: минутный лимит аккаунта или часовой бюджет живых провайдеров. Переждите Retry-After. |
503 | Закреплённый провайдер (providers=) исчерпал часовой бюджет. Снимите закрепление или переждите Retry-After. |
499 | Клиент закрыл запрос до ответа провайдера. |
/query никогда не возвращает 404. Пустой результат — это 200 с count: 0 и пустым
массивом results, без оплаты: проверяйте count. Поиск по имени (/idols/{id},
/discover/similar, resolve) возвращает 404, если кода или исполнителя нет.
Тело ошибки
Ошибки обработчиков используют конверт oRPC: defined, code, status и message.
{
"defined": false,
"code": "NOT_FOUND",
"status": 404,
"message": "no title found for \"ZZZZ-99999\""
}400 добавляет data.issues, по одной записи на непройденное правило:
{
"defined": false,
"code": "BAD_REQUEST",
"status": 400,
"message": "Input validation failed",
"data": {
"issues": [
{
"expected": "string",
"code": "invalid_type",
"path": ["q"],
"message": "Invalid input: expected string, received undefined"
}
]
}
}422: тот же конверт, status: 422, code: "BAD_REQUEST":
{
"defined": false,
"code": "BAD_REQUEST",
"status": 422,
"message": "does not support sort \"rating\""
}Отказы на входном фильтре, до обработчика, короче:
{ "error": "invalid api key" }Без ключа запрос проходит фильтр и отклоняется обработчиком с телом UNAUTHORIZED:
{
"defined": false,
"code": "UNAUTHORIZED",
"status": 401,
"message": "Unauthorized"
}Минутный ограничитель тоже использует короткую форму: { "error": "rate limit exceeded" }.
Не рассчитывайте на code: ветвитесь по статусу и читайте тело.
Пауза перед повтором
429, 402 и 503 несут Retry-After в секундах. Учитывайте его:
if ([429, 402, 503].includes(res.status)) {
const wait = Number(res.headers.get('Retry-After') ?? 1);
await new Promise((r) => setTimeout(r, wait * 1000));
}Для 402 этот час — рекомендация. Если за процессом следит человек, пополните и повторите.