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.
Список ключей
https://api.hubris.pw/v1/keysQuery-параметры: 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.
Создать ключ
https://api.hubris.pw/v1/keys| Поле | Тип | Описание |
|---|---|---|
name | string (1–100) | Название ключа — например, имя вашего клиента или сервиса. |
daily_limit_kopecks | number | 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; // показывается только здесь — сохранитеОдин ключ
https://api.hubris.pw/v1/keys/{id}Та же форма, что элемент списка. Чужой, отозванный или management-ключ — 404 not_found.
Изменить ключ
https://api.hubris.pw/v1/keys/{id}Частичное обновление — передайте хотя бы одно поле:
| Поле | Описание |
|---|---|
name | Переименовать. |
disabled | true — временно отключить (ключ получает 401 на любой запрос), false — включить обратно. Обратимо. |
daily_limit_kopecks | Новый дневной лимит; null — снять лимит. |
privacy_mask_default | Режим маскирования данных. |
Ответ — обновлённый ключ. Типовой приём для сервиса поверх Hubris: клиент не оплатил период — {"disabled": true}, оплатил — {"disabled": false}.
Отозвать ключ
https://api.hubris.pw/v1/keys/{id}Необратимо. Ответ {"id": "…", "deleted": true}; повторный вызов по уже отозванному ключу тоже вернёт 200 (идемпотентно). Для временной блокировки используйте PATCH с disabled: true.
Баланс — GET /v1/credits
https://api.hubris.pw/v1/creditsТребует management-ключ.
{
"data": {
"balance_kopecks": 152030,
"bonus_balance_kopecks": 5000,
"currency": "RUB"
}
}152030 копеек = 1520,30 ₽. Бонусный баланс — невыводимые кредиты (реферальные начисления и акции).
Текущий ключ — GET /v1/key
https://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
https://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_by | key — добавить массив 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_required | Management-эндпоинт вызван обычным ключом. |
403 inference_key_required | Модельный эндпоинт вызван management-ключом. |
404 not_found | Ключ не найден (или не ваш). |
429 rate_limit_exceeded | Превышен лимит 60/мин или 30 созданий/час. |
429 key_quota_exceeded | Достигнут потолок 500 активных ключей. |
Формат ошибок стандартный: {"error": {"message", "type", "code"}} — см. ошибки.
Что дальше
- GET /v1/usage — формы ответа расхода, шорткаты периодов.
- Обзор API — авторизация, базовый URL, совместимость с OpenAI SDK.
- Маскирование данных — что такое
privacy_mask_default.
Обновлено: