Hubris
Скачать из Google PlayСкачайте из RuStore
hubris
Базовые концепции
БАЗОВЫЕ КОНЦЕПЦИИ

Rate limits

Что ограничивает запросы в Hubris — баланс, лимиты провайдеров, дневные лимиты на служебных ключах.

Hubris не применяет искусственных rate-limit-ов на пользовательские API-ключи. Стандартный тариф даёт неограниченное число запросов в секунду — расход ограничен только балансом.

Что реально ограничивает запросы

1. Баланс

Каждый запрос списывает с баланса фактическую стоимость. При недостаточном балансе (< 100 копеек) запрос отклоняется с 402 insufficient_balance ДО обращения к модели. Подробнее — на странице «Баланс и оплата».

2. Лимиты провайдера

Каждая модель имеет собственные ограничения от провайдера: requests-per-minute, tokens-per-minute, concurrent connections. При превышении провайдер возвращает 429, мы транслируем это как 502 upstream_error.

Что делать: добавить retry с экспоненциальным backoff. Hubris агрегирует трафик многих клиентов через свой сервисный ключ — вероятность упереться в лимит провайдера ниже, чем при работе напрямую.

3. Лимит расхода ключа с периодом сброса

У любого ключа можно задать лимит расхода в копейках и период его сброса:

ПериодОкноСброс
day (по умолчанию)текущие календарные сутки по Москве00:00 МСК
weekтекущая неделяпонедельник, 00:00 МСК
monthтекущий месяц1-е число, 00:00 МСК
noneвесь расход ключа с момента созданияникогда — лимит на весь срок ключа

Например, limit_kopecks: 5000 с периодом day — 50 ₽ в сутки; с периодом none — 50 ₽ на всю жизнь ключа. Превышение возвращает 429: код daily_limit_exceeded для суточного лимита и key_limit_exceeded для остальных периодов:

{
  "error": {
    "message": "Превышен лимит расхода этого API-ключа за месяц",
    "type": "rate_limit_error",
    "code": "key_limit_exceeded"
  }
}

Заголовок Retry-After — секунды до сброса окна; у лимита без сброса заголовка нет: повторять запрос бессмысленно, надо поднять лимит.

Это используется для:

  • CI-runner-ов, чтобы утечка ключа не разорила баланс.
  • Внутренних скриптов с ограниченным бюджетом — например, месячным.
  • Ключей подрядчиков и демо с лимитом на весь срок.

Окна календарные, а не скользящие: суточный лимит сбрасывается в московскую полночь целиком. В счётчик входят успешно оплаченные запросы и резервы роликов /v1/videos, которые ещё в работе. Лимит проверяется перед каждым запросом к модели: пока остаток больше нуля, запрос начинается и списывается целиком, поэтому итог может превысить лимит на стоимость последних запросов, в том числе одновременных.

Исчерпанный ключ отказывает только в том, что тратит: в запросах к моделям. Остальное работает: GET /v1/key, /v1/usage, /v1/metrics, /v1/models, скачивание готовых роликов, повтор POST /v1/videos с тем же Idempotency-Key. Подключениями Битрикс24 ключ с лимитом не управляет вовсе: это может только ключ без ограничений.

Потолок лимита: 100 000 ₽ за сутки, неделю или месяц и 100 000 000 ₽ без сброса.

Задать или поменять лимит — на странице API-ключи: поле «Лимит расхода, ₽» с выбором сброса в форме создания и на странице ключа. Очистите поле, чтобы снять лимит. По API — поля limit_kopecks и limit_period в Management API.

Генерация изображений (modalities: ["image"] / ["image","text"]) учитывается в расходе ключа на общих основаниях: одна сгенерированная картинка добавляется к расходу по итоговой стоимости (см. Генерация изображений).

Заголовки квоты

Там, где у запросов есть квота по числу, ответ несёт заголовки по черновику IETF RateLimit Fields for HTTP (версия 11): по ним клиент или AI-агент притормаживает сам, не дожидаясь 429.

RateLimit-Policy: "management";q=60;w=60
RateLimit: "management";r=57;t=41
  • RateLimit-Policy — сама квота: q запросов за окно w секунд.
  • RateLimit — сколько запросов осталось (r) и через сколько секунд окно сбросится (t).
  • На ответе 429 добавляется Retry-After — секунды до сброса.

Сейчас числовая квота есть у Management API: 60 запросов в минуту на аккаунт, у создания ключей ещё и 30 в час — тогда политик в заголовках две, через запятую. Запросы к моделям по обычному ключу квоты по числу не имеют, поэтому и заголовков RateLimit в их ответах нет: ограничивают их баланс и лимит расхода ключа (см. выше, Retry-After там тоже есть). Заголовки доступны и браузерным клиентам: они перечислены в Access-Control-Expose-Headers.

Стратегия retry

Если получили 429 от Hubris (daily_limit_exceeded / key_limit_exceeded) или 502 (от провайдера):

import time

def with_retry(fn, max_attempts=3):
    delay = 1
    for attempt in range(max_attempts):
        try:
            return fn()
        except APIError as e:
            if e.code in ("upstream_error", "upstream_timeout"):
                if attempt < max_attempts - 1:
                    time.sleep(delay)
                    delay *= 2
                    continue
            raise

Не делайте retry на:

  • invalid_api_key (401) — ключ не починится сам.
  • insufficient_balance (402) — пополните баланс сначала.
  • model_not_found (404) — название не изменится.
  • invalid_request (400) — баг в коде.

Concurrent requests

Параллельные запросы на одном ключе — без ограничений. Если ваш сервис делает 100 запросов одновременно, они все пойдут к моделям параллельно. Узкое горлышко — провайдер модели, не Hubris.

Что дальше

Обновлено: