Коды ошибок
Единый envelope:
{
"error": "insufficient_balance",
"message": "Not enough credits",
"required": 12,
"available": 5,
"recovery": { "action": "topup", "url": "/billing/topup", "minAmountRub": 100 },
"docs": "/llms-full.txt#billing"
}Ветвите по error (стабильный machine-readable). message — для человека (может меняться). Дополнительные поля (required, available, recovery, docs) зависят от ошибки.
Сводная таблица
| Статус | Код | Когда | Что делать |
|---|---|---|---|
| 400 | invalid_body | Не прошёл zod | См. details.issues |
| 400 | invalid_query | Query-параметр невалиден | См. details.issues |
| 400 | invalid_params | Path-параметр невалиден | |
| 400 | invalid_json | Тело не парсится | Проверьте Content-Type |
| 400 | minimum_topup | < MIN_TOPUP_RUB | Увеличьте amountRub |
| 401 | unauthorized | Нет валидного auth | Создайте новый ключ |
| 401 | invalid_signature | Подпись YooKassa webhook невалидна | (внутренний server-to-server callback) |
| 402 | insufficient_balance | Средств на балансе меньше | Пополните баланс; поля required и available |
| 403 | forbidden | Нет прав | |
| 403 | forbidden | Действие доступно только в дашборде | Сделайте действие в дашборде |
| 404 | not_found | Ресурс не существует или не ваш | (IDOR-guard, не различаются) |
| 404 | unknown_model | Опечатка в modelId | GET /models |
| 409 | conflict | Уникальный ключ занят | |
| 413 | asset_too_large | Файл > MAX_UPLOAD_BYTES | Сожмите |
| 413 | payload_too_large | Тело > MAX_BODY_BYTES | |
| 415 | unsupported_media_type | Content-Type не allowlist | |
| 415 | unsupported_media_type | (Uploads) MIME не allowlist | См. allowed list в /build/upload-inputs |
| 429 | rate_limited | IP/user/key лимит | Retry-After |
| 429 | key_limit_exceeded | Месячный лимит ключа | Поднимите через PATCH /me/keys/{id} |
| 500 | internal_error | Непредвиденно | Передайте X-Request-ID команде |
| 500 | generation_failed | Внутренняя фатальная ошибка | Refund автоматический |
| 502 | provider_error | Внутренняя ошибка обработки | Повторите |
| 502 | payment_provider | YooKassa | Повторите |
| 503 | provider_error (с Retry-After) | Circuit breaker открыт | Подождите и повторите |
| 503 | asset_storage_disabled | (Uploads) S3 не настроен | Только в local-dev |
| 504 | timeout | Sync /run истёк за 5 мин | См. 202 ответ — requestId для /queue |
Формат ошибки валидации
{
"error": "invalid_body",
"message": "Validation failed",
"issues": [
{ "path": ["prompt"], "message": "Required" },
{ "path": ["num_inference_steps"], "message": "Must be ≤ 50" }
]
}Недостаток средств
{
"error": "insufficient_balance",
"message": "Not enough credits",
"required": 12,
"available": 5
}Используйте required - available для UI-сообщения “не хватает 7 ₽”.
Превышение лимита
HTTP/1.1 429 Too Many Requests
Retry-After: 47
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1714050300
{"error":"rate_limited","message":"Too many requests"}X-Request-ID
В каждом ответе:
X-Request-ID: 01HXYZ…Передайте этот ID в support — по нему достанем полный лог.
Дальше
- Лимиты запросов —
Retry-Afterи backoff. - Биллинг — восстановление после
insufficient_balance. - Шпаргалка по API — стандартные заголовки ответа.