allowed_models: как разрешить ключу только нужные модели
Ключ, который может вызвать любую модель из каталога, — лишняя свобода для интеграции, которой нужна ровно одна модель. Разбираем настройку allowed_models.
3 мин · · Обновлено · API-ключи
По умолчанию ключ fetch_... может вызывать любую модель из каталога — от дешёвого glm-5.3-flash до claude-opus-5-5. Для многих сценариев это лишняя степень свободы: если ключ выдан узкому сервису, ему может быть нужна ровно одна модель, а не весь каталог.
Что это за настройка
На странице конкретного ключа в кабинете (https://zukko.pro/app/api-keys) можно задать список моделей, разрешённых именно этому ключу. Запрос с этим ключом к любой модели вне списка получит отказ ещё до обращения к провайдеру.
Настройка соседствует с дневным/месячным лимитом расхода на той же странице ключа — это две независимые, но дополняющие друг друга формы ограничения одного ключа: лимит контролирует «сколько», список моделей контролирует «чем».
Как выглядит отказ
{
"error": {
"message": "Model 'claude-opus-5-5' is not allowed for this API key",
"code": "model_not_allowed_for_key"
}
}Статус — 403. Это стоит отличать от 404 model_not_found: модель существует в каталоге, запрос синтаксически корректен, но конкретно этому ключу политика запрещает её вызывать.
curl https://api.zukko.pro/v1/chat/completions \
-H "Authorization: Bearer fetch_ограниченный_ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-5-5",
"messages": [{"role": "user", "content": "..."}]
}'
# -> 403 model_not_allowed_for_key, если claude-opus-5-5 не в списке разрешённых для этого ключаЗачем это нужно
Защита от случайного вызова дорогой модели. claude-opus-5-5 стоит $0.30/$0.30 за 1M токенов, а glm-5.3-flash — $0.04/$0.04, то есть в 7,5 раза дешевле. Если сервис по задумке должен работать только с быстрой и дешёвой моделью, а в коде из-за бага или скопированного примера окажется другой model, allowlist остановит вызов до списания, а не после.
Ключ для стороннего сервиса или партнёра. Если вы выдаёте ключ подрядчику для конкретной интеграции — скажем, только для чат-бота поддержки на glm-5.3-flash — нет причин, чтобы тот же ключ мог вызывать другие модели или менять модель на более дорогую без вашего ведома.
Раздельные ключи под разные компоненты одного продукта. У бэкенд-сервиса, которому нужен claude-sonnet-5 для основной логики, и у отдельного модуля классификации обращений, которому нужен только glm-5.3-flash, могут быть два ключа с непересекающимися списками разрешённых моделей — так утечка одного ключа не открывает доступ ко всему каталогу.
Явная документация того, что сервис действительно использует. Список разрешённых моделей в кабинете — это по факту декларация: этот ключ предназначен ровно для этих моделей. Если через полгода кто-то видит в логах model_not_allowed_for_key, это подсказка, что либо в код закралась не та модель, либо список пора расширить осознанно, а не молча.
Как обрабатывать в коде
import requests
ALLOWED_FALLBACK = "glm-5.3-flash"
def call_model(model_id, messages, key):
resp = requests.post(
"https://api.zukko.pro/v1/chat/completions",
headers={"Authorization": f"Bearer {key}"},
json={"model": model_id, "messages": messages},
)
if resp.status_code == 403:
data = resp.json()
if data.get("error", {}).get("code") == "model_not_allowed_for_key":
# Не пытаемся угадать замену сами — здесь это не входит в ответ сервера,
# в отличие от model_retired. Логируем и решаем осознанно.
raise PermissionError(
f"Модель '{model_id}' не разрешена для этого ключа. "
f"Проверьте allowed_models в кабинете или используйте другой ключ."
)
resp.raise_for_status()
return resp.json()Важное отличие от ошибки model_retired: там сервер сам называет замену в тексте сообщения, потому что замена объективна — модель снята с обслуживания для всех. Здесь же ограничение специфично для конкретного ключа и отражает вашу же политику, поэтому сервер не подсказывает альтернативную модель — решение, что делать (расширить список или использовать другой ключ), остаётся за вами.
Частая ошибка при настройке
Если сервис использует несколько моделей поочерёдно — например, основной claude-sonnet-5 и запасной gpt-5.6-sol на случай 503 provider_unavailable у первого — обе модели должны быть в allowlist заранее. Иначе логика фолбэка при недоступности провайдера сама упрётся в 403, и вместо переключения на резервную модель сервис получит вторую ошибку поверх первой.
Пример: ключ только под дешёвые модели
Допустим, отдельный модуль вызывает исключительно glm-5.3-flash и gpt-5.6-luna — для классификации обращений и коротких пересказов. Разумно выпустить под него ключ, в allowlist которого нет ни одной другой модели. Тогда даже если в код этого модуля по ошибке попадёт вызов claude-opus-5-5 (например, при копировании чужого примера с другой моделью), запрос упадёт с 403 model_not_allowed_for_key вместо того, чтобы тихо списать деньги за вызов модели, которая этому модулю в принципе не нужна.
Итог
allowed_models — это позиционирование ключа под конкретную задачу, а не защита от лишних трат сама по себе (для этого есть отдельный лимит расхода). Настраивается на странице ключа в кабинете, срабатывает как 403 model_not_allowed_for_key, и, в отличие от model_retired, не предлагает замену — потому что ограничение ваше собственное, а не следствие изменений в каталоге.
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 на другой провайдер.