Как поставить дневной и месячный лимит на API-ключ
Один скомпрометированный или неправильно настроенный ключ не должен уметь потратить весь баланс за час. Разбираем, как это ограничить в кабинете.
4 мин · · Обновлено · API-ключи
Один аккаунт может держать несколько API-ключей — для разных проектов, разных серверов, разных подрядчиков. Без ограничения любой из этих ключей технически может расходовать весь баланс аккаунта. Лимит на ключ — способ заранее решить, сколько конкретно этот ключ может потратить в день и в месяц.
Где настраивается
Лимит задаётся не глобально на аккаунт, а на странице конкретного ключа в кабинете: https://zukko.pro/app/api-keys. У каждого ключа можно независимо указать:
- дневной лимит расхода в долларах;
- месячный лимит расхода в долларах;
- список моделей, разрешённых именно этому ключу (это отдельная, но соседняя настройка на той же странице).
Ключи создаются в этом же разделе, и напомню: значение ключа показывается один раз, в момент создания, — сохраните его сразу, лимиты потом можно поменять, а сам ключ восстановить нельзя.
Чем это отличается от других 429
Общего лимита частоты запросов на шлюзе нет. 429 от самого Zukko — это ровно два кода, и оба означают исчерпание бюджета конкретного ключа:
{
"error": {
"message": "Daily spend limit reached for this API key",
"code": "key_daily_limit_reached"
}
}{
"error": {
"message": "Monthly spend limit reached for this API key",
"code": "key_monthly_limit_reached"
}
}Любой другой 429 (без этих кодов) приходит от провайдера модели — это его ограничение частоты, оно не про деньги и обычно снимается через секунды-минуты (замедлились — и снова можно отправлять запросы). key_daily_limit_reached держится до 00:00 UTC, key_monthly_limit_reached — до начала следующего месяца. Если код в логах — один из этих двух, повторять запрос раньше времени бессмысленно, лимит сброса не ускорить.
Зачем это нужно на практике
Ключ для подрядчика или стажёра. Выдавая доступ человеку, с которым нет полного доверия к его коду, разумно сразу поставить дневной потолок в $5–10, а не потом разбираться, почему баланс аккаунта обнулился за ночь.
Ключ во фронтенд-приложении или мобильном клиенте. Если ключ теоретически может утечь через декомпиляцию клиента или debug-лог, лимит ограничивает потенциальный ущерб временем до следующего сброса, а не размером всего баланса аккаунта.
Разделение бюджета между проектами на одном аккаунте. Если под one аккаунтом крутится три отдельных сервиса, у каждого свой ключ с собственным месячным лимитом — это позволяет видеть перерасход конкретного сервиса раньше, чем закончится общий баланс.
Ключ для CI/тестов. Тестовые прогоны, которые дергают модель на каждый пуш, иногда неожиданно зацикливаются (например, из-за бага в retry-логике). Дневной лимит превращает потенциальный «слил весь баланс за ночь из-за бага» в «упёрлись в $10 и тесты начали падать с понятной ошибкой».
Как обработать это в коде
import requests
def call_with_limit_check(payload, key):
resp = requests.post(
"https://api.zukko.pro/v1/chat/completions",
headers={"Authorization": f"Bearer {key}"},
json=payload,
)
if resp.status_code == 429:
data = resp.json()
code = data.get("error", {}).get("code")
if code == "key_daily_limit_reached":
raise RuntimeError("Дневной лимит ключа исчерпан, ждать до 00:00 UTC или сменить ключ")
if code == "key_monthly_limit_reached":
raise RuntimeError("Месячный лимит ключа исчерпан")
raise RuntimeError("429 от провайдера модели, стоит подождать и повторить")
resp.raise_for_status()
return resp.json()Разделение веток по коду ошибки, а не по одному статусу 429, важно: реакция на 429 от провайдера — подождать и повторить, реакция на лимит ключа — либо остановиться и разбираться, либо переключиться на резервный ключ с собственным бюджетом, но не ретраить в цикле, надеясь, что лимит сам снимется раньше времени.
Резервный ключ вместо повышения лимита на лету
Если сервис упёрся в дневной лимит в середине рабочего дня, увеличить лимит существующего ключа в кабинете — вариант, но для продакшена практичнее держать заранее заведённый второй ключ с отдельным (более высоким) лимитом на такой случай, чтобы не редактировать настройки в панике посреди инцидента. Мониторить остаток стоит по заголовку X-Fetch-Balance-Cents в каждом обычном (не потоковом) ответе — это остаток баланса всего аккаунта после списания (несмотря на название, в микродолларах), а не остаток лимита конкретного ключа, но резкое падение баланса — тоже полезный сигнал для алертов.
Лимит ключа и баланс аккаунта — разные вещи
Лимит на ключ не связан напрямую с фактическим балансом аккаунта: можно поставить ключу дневной лимит в $20, даже если на счету $500, — это просто потолок для конкретного ключа, а не отражение реальных денег. Общий остаток средств проверяется отдельно через GET /v1/balance (нужен ключ), и его тоже стоит мониторить: лимит ключа защищает от перерасхода одним ключом, а не от того, что баланс всего аккаунта в принципе закончится и все ключи разом получат 402.
Итог
Лимит на ключ — это не защита от исчерпания баланса аккаунта в принципе, а способ заранее ограничить, сколько именно может потратить один конкретный ключ, прежде чем понадобится ручное вмешательство. Настраивается на странице ключа в кабинете, срабатывает как 429 с кодом key_daily_limit_reached или key_monthly_limit_reached, и в коде эти коды стоит обрабатывать отдельно от 429 провайдера.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Ключи OpenAI API в открытом доступе: почему ими нельзя пользоватьсяОткуда берутся «бесплатные» ключи на GitHub, почему пользоваться ими опасно и для вас, и для владельца, и как защитить собственный ключ от такой же утечки.
- Ошибки GLM API: почему не работает запрос и как это исправитьНеверный id модели, переполненный контекст 128K, ключ, баланс, лимиты: типичные причины ошибок GLM API и быстрый способ найти свою.
- xAI Grok API: подключение Grok 4.7, цена и контекст 256KКак вызвать grok-4.7 через OpenAI-совместимый API, что делать с лимитом контекста 256K и сколько стоят типичные запросы. Плюс сравнение с Grok 4.6.
- This organization has been disabled в Claude API: что это и как продолжитьКлюч Anthropic внезапно отвечает «organization has been disabled». Объясняем, что это за ошибка, что проверить и как перенести SDK и Claude Code на другой провайдер.