Skip to content

Ошибки и лимиты

Формат ошибок

Все ошибки возвращают JSON с полем detail. Обычно это строка с описанием:

json
{
  "detail": "Описание ошибки"
}

Для ошибок с машиночитаемым кодом detail может быть объектом. Например, конфликт Idempotency-Key возвращается так:

json
{
  "detail": {
    "code": "idempotency_key_conflict",
    "message": "Idempotency-Key was already used with a different ASR request"
  }
}

Ошибки валидации FastAPI также могут содержать массив элементов в detail. Клиенту не следует предполагать, что detail всегда имеет строковый тип: сначала проверьте строку, объект или массив, а для программной обработки объекта используйте поле detail.code.

HTTP-коды ответов

КодЗначениеКогда возникает
400Bad RequestНекорректный запрос: текст слишком длинный, не указан голос, неверный формат
401UnauthorizedОтсутствует, невалидный, истёкший или отозванный API-ключ
402Payment RequiredНедостаточный баланс для синтеза
403ForbiddenМодель недоступна на вашем тарифе
408Request TimeoutСинтез занял более 5 минут
413Content Too LargeРазмер тела запроса превышает лимит edge
429Too Many RequestsПревышен лимит запросов или параллельных подключений
500Internal Server ErrorВнутренняя ошибка сервера
502Bad GatewayTTS-воркер не смог обработать запрос

Лимиты запросов

Лимиты применяются на пользователя (не на API-ключ). Все API-ключи одного аккаунта используют общие окна.

TTS: запросы в минуту и параллельная обработка

Для TTS контролируются два ограничения:

  • запросы в минуту (RPM) в скользящем окне длительностью 1 минута;
  • количество TTS-запросов, обрабатываемых одновременно.
ТарифRPMПараллельных
Бесплатный51
Старт81
Базовый102
Продвинутый305

ASR: категории запросов

Попытки создать новые синхронные и асинхронные ASR-задачи относятся к категории TARIFF_ASR. Они используют одно общее окно asr_rpm:

ТарифПопыток создания ASR-задач в минуту
Бесплатный20
Старт20
Базовый20
Продвинутый20
Бизнес / Постоплата40

Авторизованный POST без уже известного Idempotency-Key расходует попытку до чтения файла. Поэтому невалидный запрос или отказ из-за баланса тоже учитывается в этом окне.

Повтор POST по уже известному Idempotency-Key не создаёт новую задачу и не расходует TARIFF_ASR. Такой повтор и GET статуса относятся к общей категории WEB_DEFAULT — 60 запросов в минуту на пользователя. Они используют одно общее окно, поэтому частый polling уменьшает доступную частоту idempotent-повторов и наоборот.

Количество активных ASR-задач отдельно не ограничивается. Валидные задачи принимаются, пока хватает доступного баланса; стоимость уже принятых активных задач учитывается при проверке следующей задачи. Этот лимит регулирует только скорость приёма в асинхронную очередь и не является обещанием realtime-обработки.

Обработка ошибки 429

При превышении лимита ответ выглядит так:

json
{
  "detail": "Rate limit exceeded (5/5 requests per minute)"
}

Ответ 429 содержит заголовок Retry-After с числом секунд до следующей попытки. Используйте его как минимальную задержку; при повторных 429 увеличивайте паузу.

python
import time
import requests

def synthesize_with_retry(url, headers, payload, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(url, headers=headers, json=payload)
        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", "1"))
            delay = max(retry_after, 2 ** attempt)
            time.sleep(delay)
            continue
        return response
    raise Exception("Превышено количество попыток")