hubris
Войти
API Reference
API REFERENCE

Management API

Управление аккаунтом по API — ключи, баланс, расход, транзакции. Для скриптов, сервисов поверх Hubris и агентов.

Management API позволяет управлять аккаунтом программно, без захода в личный кабинет: создавать и отзывать API-ключи, ставить лимиты, смотреть баланс, расход и историю операций.

Типовые сценарии:

  • Скрипты и мониторинг — проверить баланс перед ночным батчем, отправить уведомление «пора пополнить», отозвать утёкший ключ одной командой.
  • Свой сервис поверх Hubris — выдавать по отдельному ключу каждому своему клиенту, ставить дневной лимит в рублях, отключать неплательщиков и сверять расход по каждому ключу.
  • Агенты и автоматизации — агент своим же рабочим ключом узнаёт лимит, потраченное и баланс через GET /v1/key и сам решает, хватит ли на задачу.

Два типа ключей

Обычный ключManagement-ключ
Форматsk-gw-…sk-gw-mgmt-…
Вызов моделей (/v1/chat/completions и др.)❌ (403)
Управление ключами, баланс, транзакции❌ (403)
GET /v1/key (самоинтроспекция)
Как создаётсяВ кабинете или через POST /v1/keysТолько в кабинете на /management-keys

Разделение сделано намеренно: обычные ключи живут на серверах и в агентах — если такой ключ утёк, злоумышленник может только тратить (и упирается в дневной лимит), но не может создавать ключи или читать историю платежей. Management-ключ храните как пароль: не передавайте в клиентский код, агентам и третьим лицам.

Если management-ключ скомпрометирован: отзовите его в кабинете на /management-keys, затем проверьте GET /v1/keys — не появились ли созданные без вас ключи (у них в кабинете видно время создания), и отзовите лишние.

Лимиты

ЛимитЗначение
Запросы к management-эндпоинтам60 в минуту на аккаунт
Создание ключей (POST /v1/keys)30 в час
Активных ключей на аккаунт500

Превышение — 429 с кодом rate_limit_exceeded (или key_quota_exceeded для потолка ключей).

Ключи — /v1/keys

Все эндпоинты этого раздела требуют management-ключ: Authorization: Bearer sk-gw-mgmt-…. Обычный ключ получит 403 management_key_required.

Список ключей

GEThttps://api.hubris.pw/v1/keys

Query-параметры: offset (по умолчанию 0), limit (1–100, по умолчанию 100). Возвращаются только активные обычные ключи — management-ключи и отозванные в список не попадают.

{
  "object": "list",
  "data": [
    {
      "id": "3f1c9b2e-…",
      "name": "Клиент А",
      "key_prefix": "sk-gw-ab12...cd34",
      "disabled": false,
      "daily_limit_kopecks": 20000,
      "spent_24h_kopecks": 512,
      "privacy_mask_default": "inherit",
      "last_used_at": "2026-07-16T09:00:00.000Z",
      "created_at": "2026-07-01T12:00:00.000Z"
    }
  ],
  "has_more": false
}

Полное значение ключа не возвращается никогда — только маскированный key_prefix.

Создать ключ

POSThttps://api.hubris.pw/v1/keys
ПолеТипОписание
namestring (1–100)Название ключа — например, имя вашего клиента или сервиса.
daily_limit_kopecksnumber | nullДневной лимит расхода в копейках (скользящие 24 часа), максимум 10 000 000 (100 000 ₽). Не указан или null — без лимита.
privacy_mask_default"inherit" | "off" | "on" | "required"Режим маскирования данных для запросов этим ключом.

Ответ 201 — та же форма, что в списке, плюс поле key с полным значением ключа. Оно показывается один раз — сохраните сразу, повторно получить нельзя.

curl -s https://api.hubris.pw/v1/keys \-H "Authorization: Bearer $HUBRIS_MGMT_KEY" \-H "Content-Type: application/json" \-d '{"name": "Клиент А", "daily_limit_kopecks": 20000}'
import os, requestsr = requests.post(  "https://api.hubris.pw/v1/keys",  headers={"Authorization": f"Bearer {os.environ['HUBRIS_MGMT_KEY']}"},  json={"name": "Клиент А", "daily_limit_kopecks": 20000},  # 200 ₽/день)created = r.json()client_key = created["key"]  # показывается только здесь — сохраните
const r = await fetch("https://api.hubris.pw/v1/keys", {method: "POST",headers: {  Authorization: `Bearer ${process.env.HUBRIS_MGMT_KEY}`,  "Content-Type": "application/json",},body: JSON.stringify({ name: "Клиент А", daily_limit_kopecks: 20000 }),});const created = await r.json();const clientKey = created.key; // показывается только здесь — сохраните

Один ключ

GEThttps://api.hubris.pw/v1/keys/{id}

Та же форма, что элемент списка. Чужой, отозванный или management-ключ — 404 not_found.

Изменить ключ

PATCHhttps://api.hubris.pw/v1/keys/{id}

Частичное обновление — передайте хотя бы одно поле:

ПолеОписание
nameПереименовать.
disabledtrue — временно отключить (ключ получает 401 на любой запрос), false — включить обратно. Обратимо.
daily_limit_kopecksНовый дневной лимит; null — снять лимит.
privacy_mask_defaultРежим маскирования данных.

Ответ — обновлённый ключ. Типовой приём для сервиса поверх Hubris: клиент не оплатил период — {"disabled": true}, оплатил — {"disabled": false}.

Отозвать ключ

DELETEhttps://api.hubris.pw/v1/keys/{id}

Необратимо. Ответ {"id": "…", "deleted": true}; повторный вызов по уже отозванному ключу тоже вернёт 200 (идемпотентно). Для временной блокировки используйте PATCH с disabled: true.

Баланс — GET /v1/credits

GEThttps://api.hubris.pw/v1/credits

Требует management-ключ.

{
  "data": {
    "balance_kopecks": 152030,
    "bonus_balance_kopecks": 5000,
    "currency": "RUB"
  }
}

152030 копеек = 1520,30 ₽. Бонусный баланс — невыводимые кредиты (реферальные начисления и акции).

Текущий ключ — GET /v1/key

GEThttps://api.hubris.pw/v1/key

Самоинтроспекция: работает обычным ключом — management-ключ не нужен. Главная ручка для агентов: один запрос своим же рабочим ключом — и агент знает свой лимит, расход за сутки и баланс аккаунта.

{
  "data": {
    "name": "prod-bot",
    "key_prefix": "sk-gw-ab12...cd34",
    "key_type": "inference",
    "disabled": false,
    "daily_limit_kopecks": 20000,
    "spent_24h_kopecks": 512,
    "balance_kopecks": 152030,
    "created_at": "2026-07-01T12:00:00.000Z"
  }
}
curl -s https://api.hubris.pw/v1/key \-H "Authorization: Bearer $HUBRIS_API_KEY"
import os, requestsr = requests.get(  "https://api.hubris.pw/v1/key",  headers={"Authorization": f"Bearer {os.environ['HUBRIS_API_KEY']}"},)data = r.json()["data"]if data["balance_kopecks"] < 30_000:  # меньше 300 ₽  print("Пора пополнить баланс")
const r = await fetch("https://api.hubris.pw/v1/key", {headers: { Authorization: `Bearer ${process.env.HUBRIS_API_KEY}` },});const { data } = await r.json();if (data.balance_kopecks < 30_000) console.log("Пора пополнить баланс");

Транзакции — GET /v1/transactions

GEThttps://api.hubris.pw/v1/transactions

Требует management-ключ. Пополнения, списания, возвраты и бонусные операции, свежие сверху — удобно для сверки и бухгалтерии.

Query-параметры: offset, limit (1–100, по умолчанию 50), type (например, topup, usage, refund), from/to (ISO 8601).

{
  "object": "list",
  "data": [
    {
      "id": "9d2e4c11-…",
      "type": "topup",
      "status": "succeeded",
      "amount_kopecks": 100000,
      "balance_after_kopecks": 152030,
      "payment_method": "sbp",
      "created_at": "2026-07-15T10:00:00.000Z"
    }
  ],
  "has_more": true
}

Положительный amount_kopecks — зачисление, отрицательный — списание. payment_method (sbp / card / invoice) заполнен только у пополнений.

Расход по всем ключам — GET /v1/usage

Обычный вызов /v1/usage показывает расход только того ключа, которым сделан запрос. Management-ключом тот же эндпоинт видит весь аккаунт и получает два дополнительных параметра:

ПараметрОписание
key_idСузить до одного ключа (UUID из GET /v1/keys).
group_bykey — добавить массив by_key (расход каждого ключа), model — массив by_model.
# кто из клиентов сколько потратил за месяцcurl -s "https://api.hubris.pw/v1/usage?period=30d&group_by=key" \-H "Authorization: Bearer $HUBRIS_MGMT_KEY"
import os, requestsr = requests.get(  "https://api.hubris.pw/v1/usage",  params={"period": "30d", "group_by": "key"},  headers={"Authorization": f"Bearer {os.environ['HUBRIS_MGMT_KEY']}"},)for row in r.json()["by_key"]:  rub = int(row["cost_kopecks"]) / 100  print(f"{row['name']}: {row['requests']} запросов, {rub:.2f} ₽")
const r = await fetch("https://api.hubris.pw/v1/usage?period=30d&group_by=key",{ headers: { Authorization: `Bearer ${process.env.HUBRIS_MGMT_KEY}` } },);const { by_key } = await r.json();for (const row of by_key) {console.log(`${row.name}: ${row.requests} запросов, ${Number(row.cost_kopecks) / 100} ₽`);}

В by_key[]: key_id, key_prefix, name, requests, total_tokens, cost_kopecks (строка, копейки). В by_model[]: model, requests, prompt_tokens, completion_tokens, cost_kopecks.

HTTP-коды

КодКогда
400 invalid_requestНевалидное тело или параметры; key_id/group_by обычным ключом.
401 invalid_api_keyКлюч не передан, неверный, отозван или отключён.
403 management_key_requiredManagement-эндпоинт вызван обычным ключом.
403 inference_key_requiredМодельный эндпоинт вызван management-ключом.
404 not_foundКлюч не найден (или не ваш).
429 rate_limit_exceededПревышен лимит 60/мин или 30 созданий/час.
429 key_quota_exceededДостигнут потолок 500 активных ключей.

Формат ошибок стандартный: {"error": {"message", "type", "code"}} — см. ошибки.

Что дальше

Обновлено: