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,
"limit_kopecks": 20000,
"limit_period": "month",
"spent_period_kopecks": 512,
"period_reset_at": "2026-08-31T21:00:00.000Z",
"daily_limit_kopecks": null,
"spent_24h_kopecks": 512,
"read_only": false,
"allowed_ips": null,
"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.
Защита от всплеска: spike_limit_kopecks, spike_window_minutes, spike_cooldown_minutes (см. описание); состояние — disabled_reason (manual — отключён вручную, spike — заморожен, null — включён) и disabled_until (когда включится сам). Замороженный ключ на любой запрос отвечает 401 key_frozen_spike.
Привязка к адресу: allowed_ips — адреса и подсети (CIDR), с которых ключ принимает запросы; null — с любого адреса. Запрос с чужого адреса получает 403 key_ip_not_allowed до обращения к модели (см. описание).
Поля лимита: limit_kopecks — лимит расхода в копейках (null — без лимита), limit_period — период сброса (day — календарные сутки по Москве, week — с понедельника, month — с 1-го числа, none — без сброса, лимит на весь расход ключа), spent_period_kopecks — потрачено в текущем периоде, period_reset_at — момент следующего сброса (null при none). Поля daily_limit_kopecks и spent_24h_kopecks устарели: первое равно limit_kopecks только при limit_period: "day" (иначе null), второе всегда равно spent_period_kopecks.
Создать ключ
https://api.hubris.pw/v1/keys| Поле | Тип | Описание |
|---|---|---|
name | string (1–100) | Название ключа — например, имя вашего клиента или сервиса. |
limit_kopecks | number | null | Лимит расхода в копейках за период limit_period, максимум 10 000 000 (100 000 ₽). Не указан или null — без лимита. |
limit_period | "day" | "week" | "month" | "none" | Период сброса лимита; по умолчанию day. none — без сброса, лимит на весь расход ключа. |
daily_limit_kopecks | number | null | Устаревшее: то же, что limit_kopecks с limit_period: "day". Вместе с limit_kopecks не передавать — 400. |
read_only | boolean | Ключ только для чтения: каталог моделей, баланс и статистика доступны, а всё, что тратит баланс, отвечает 403 key_read_only. По умолчанию false. Удобен для дашбордов и мониторинга — утечка такого ключа ничего не стоит. |
allowed_ips | string[] | null | Привязка к адресу: до 32 записей — IPv4/IPv6-адрес или подсеть (CIDR), например ["203.0.113.5", "198.51.100.0/24"]. Не указано, null или [] — с любого адреса. Невалидная запись — 400 invalid_allowed_ips с перечнем в сообщении, больше 32 — 400 too_many_allowed_ips. |
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": "Клиент А", "limit_kopecks": 20000, "limit_period": "month"}'import os, requestsr = requests.post( "https://api.hubris.pw/v1/keys", headers={"Authorization": f"Bearer {os.environ['HUBRIS_MGMT_KEY']}"}, json={"name": "Клиент А", "limit_kopecks": 20000, "limit_period": "month"}, # 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: "Клиент А", limit_kopecks: 20000, limit_period: "month" }),});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 — включить обратно. Обратимо. |
limit_kopecks | Новый лимит расхода; null — снять лимит. |
limit_period | Новый период сброса: day, week, month, none. Можно менять отдельно от суммы. |
daily_limit_kopecks | Устаревшее: то же, что limit_kopecks + limit_period: "day". |
read_only | true — ключ только для чтения (запросы к моделям — 403 key_read_only), false — обычный. Обратимо. |
allowed_ips | Привязка к адресу: новый список целиком (адреса и подсети CIDR); null или [] — снять привязку. Невалидный список — 400, остальные поля того же запроса не применяются. |
spike_limit_kopecks | Защита от всплеска: порог расхода в копейках за окно; null — выключить. |
spike_window_minutes | Окно защиты: 1, 5, 15, 30 или 60. По умолчанию 15. |
spike_cooldown_minutes | Период охлаждения: 15, 60, 360, 1440 — ключ включится сам через столько минут; 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,
"limit_kopecks": 20000,
"limit_period": "day",
"spent_period_kopecks": 512,
"period_reset_at": "2026-07-16T21:00:00.000Z",
"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.
Обновлено: