Доступ для команды: несколько ключей с разными лимитами

Отдельного понятия "команда" в кабинете нет, но per-key лимиты и список разрешённых моделей закрывают эту задачу почти полностью. Разбираем, как это настроить и на что не рассчитывать.

4 мин · · Обновлено · API-ключи · бизнес

В кабинете zukko.pro нет отдельной сущности "команда" с ролями и правами доступа — то, что закрывает эту задачу, это лимиты на отдельный API-ключ. У каждого ключа можно задать дневной и месячный лимит расхода в долларах и список моделей, которые этим ключом разрешено вызывать. На практике это даёт почти всё, что нужно для контролируемого доступа нескольких человек к одному балансу, без единого общего ключа, который лежит в переменной окружения у всех подряд.

Идея в двух словах

Вместо одного ключа на всю команду создаётся отдельный ключ на каждого участника. У каждого ключа — свой дневной/месячный лимит трат и свой список разрешённых моделей. Общий баланс аккаунта при этом один — лимиты ограничивают, сколько с него может списать конкретный ключ, а не создают отдельные "суб-балансы".

Как настроить

  1. Зайдите в /app/api-keys.
  2. Создайте новый ключ для каждого участника команды — имя ключа стоит сразу делать говорящим (например, по имени человека или по названию сервиса, который будет им пользоваться), потому что после создания ключ показывается один раз, и различать их потом придётся по этому имени.
  3. На странице конкретного ключа задайте дневной и/или месячный лимит расхода в долларах.
  4. Там же ограничьте список разрешённых моделей — например, если джуниору для его задач хватает дешёвых моделей, оставьте ему gpt-5.6-luna и glm-5.3 ($0.10 за 1M токенов) или glm-5.3-flash ($0.04) вместо claude-opus-5-5, claude-sonnet-5 и gpt-5.6-sol ($0.30). Актуальный список моделей — GET https://api.zukko.pro/v1/models.
  5. Передайте каждому участнику только его ключ. Ключ показывается один раз при создании — если он потерян, проще выпустить новый на этого же человека, чем пытаться восстановить старый.

Что произойдёт, если участник превысит лимит

Ключ с исчерпанным дневным или месячным лимитом начнёт получать 429 с кодом key_daily_limit_reached или key_monthly_limit_reached в зависимости от того, какой из двух порогов сработал:

bash
{"error": {"message": "Daily limit reached for this key", "code": "key_daily_limit_reached"}}

Это ограничение именно ключа, а не всего аккаунта — общий баланс компании при этом не трогается, и другие ключи команды продолжают работать как обычно. Человек, упёршийся в лимит, просто ждёт следующего дня (дневной лимит сбрасывается в 00:00 UTC) или месяца, либо к нему приходит запрос на повышение лимита от того, кто администрирует ключи.

Что произойдёт при попытке вызвать запрещённую модель

Если ключу не разрешена конкретная модель, а её всё равно указали в запросе, ответ будет 403 с кодом model_not_allowed_for_key:

bash
{"error": {"message": "This model is not allowed for the given key", "code": "model_not_allowed_for_key"}}

Это удобно как способ технически, а не на словах, ограничить доступ к дорогим моделям — например, если только тимлид должен работать с claude-opus-5-5, остальным ключам эта модель просто не разрешается на уровне настройки ключа.

Как следить за расходами по команде

Отдельно по ключам GET /v1/usage расход не покажет: эндпоинт отдаёт историю списаний по всему аккаунту (все ключи вместе) с курсорной пагинацией, фильтра по ключу в нём нет, и баланс тоже один — у аккаунта, а не у ключа:

bash
curl "https://api.zukko.pro/v1/usage?limit=50" \
  -H "Authorization: Bearer fetch_ключ_участника"

Вызов с ключом конкретного участника вернёт ту же общую историю аккаунта (поля created_at, model, input_tokens, output_tokens, total_tokens, cost_cents, next_cursor), а не только его запросы. Чтобы разделить расход по участникам, логируйте на своей стороне (например, через прокси или мидлварь) заголовок X-Zukko-Cost-Micros — стоимость конкретного запроса в микродолларах — вместе с именем ключа и агрегируйте прямо из логов приложения. Заголовок есть только у обычных (не потоковых) ответов; для потоковых клиентов вроде Cline, Roo, Claude Code, Zed или aider такой разбивки не получится — если нужен строгий раздельный учёт, заведите отдельный аккаунт.

Чего это не заменяет

Это не полноценная организация с ролями, инвайтами по email и общим биллинг-аккаунтом с несколькими логинами — в кабинете нет понятия "участник команды", есть только владелец аккаунта и его ключи. Если нужно, чтобы несколько человек заходили в один и тот же кабинет под разными учётками с разными правами на управление платежами, такой функции сейчас нет — есть только разделение по ключам с лимитами и списком моделей, которое решает практическую задачу "не дать одному человеку случайно или намеренно спустить весь баланс команды", но не задачу управления доступом к самому кабинету.

Idempotency-Key при массовых вызовах от нескольких сервисов

Если несколько сервисов команды используют свои ключи и при этом ретраят запросы при сетевых сбоях, стоит убедиться, что каждый сервис генерирует свой Idempotency-Key на каждый уникальный логический запрос (например, UUID, созданный один раз до цикла ретраев и тот же самый при повторах; передаётся в заголовках конкретного вызова, а не в default_headers клиента, иначе второй же запрос получит 422 idempotency_conflict) — тогда повтор одного и того же запроса в течение 24 часов вернёт закешированный результат без повторного списания, даже если ретрай инициирован автоматически на уровне HTTP-клиента.

Практическая расстановка лимитов

Разумный старт — поставить каждому новому ключу небольшой дневной лимит (скажем, покрывающий обычную дневную нагрузку с запасом в 2-3 раза) и список только тех моделей, которые участнику реально нужны. Дальше лимит можно поднять точечно тому, кому он реально мешает работать, глядя на собственные логи расхода по ключам (в /v1/usage история общая на аккаунт), а не выставлять всем сразу большой лимит "на всякий случай".

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.