Как узнать список доступных моделей через API и не сломаться при их смене
Каталог моделей меняется: появляются новые, старые отключаются. Показываем, как запросить актуальный список и написать код, который переживёт смену модели.
3 мин · · модели · API-ключи
Каталог моделей в Zukko меняется: добавляются новые модели, старые отключаются. Если название модели жёстко зашито в код, однажды запрос начнёт возвращать ошибку. Разбираемся, как узнать список доступных моделей через API, как обработать отключение модели и как вынести выбор модели в конфиг.
Список моделей: GET /v1/models
Эндпоинт публичный — ключ для него не нужен:
curl https://api.zukko.pro/v1/modelsОтвет в OpenAI-совместимом формате — объект со списком в поле data:
{
"object": "list",
"data": [
{"id": "claude-sonnet-5", "object": "model", "created": 1700000000, "owned_by": "zukko"},
{"id": "gpt-5.6-sol", "object": "model", "created": 1700000000, "owned_by": "zukko"},
{"id": "gpt-5.6-luna", "object": "model", "created": 1700000000, "owned_by": "zukko"},
{"id": "glm-5.3", "object": "model", "created": 1700000000, "owned_by": "zukko"},
{"id": "glm-5.3-flash", "object": "model", "created": 1700000000, "owned_by": "zukko"},
{"id": "claude-opus-5-5", "object": "model", "created": 1700000000, "owned_by": "zukko"}
]
}Это пример на момент написания: состав и порядок могут измениться. Для запросов нужно только поле id — его и передавайте в параметр model. Тот же список есть на странице «Модели» в кабинете, а описание эндпоинта — в документации.
Обратите внимание: список общий для всех. Если на вашем ключе настроен список разрешённых моделей (allowed_models), запрос к модели вне этого списка вернёт 403 model_not_allowed_for_key, даже если модель есть в /v1/models.
Python: получить список
Через requests:
import requests
def get_available_models(timeout: float = 5.0) -> list[str]:
r = requests.get("https://api.zukko.pro/v1/models", timeout=timeout)
r.raise_for_status()
return [m["id"] for m in r.json()["data"]]
print(get_available_models())Через OpenAI SDK, если он уже есть в проекте:
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_ваш_ключ")
models = [m.id for m in client.models.list()]
print(models)Что происходит при обращении к отключённой модели
Если модель выключена, шлюз отвечает HTTP 503 с кодом ошибки model_disabled в теле ответа. Важно: код 503 используется и тогда, когда временно недоступен провайдер. Поэтому смотрите не только на статус, но и на код в теле:
503+model_disabled— модель отключена, повторять запрос бессмысленно, нужно выбрать другую;503безmodel_disabled— временный сбой провайдера, имеет смысл повторить с паузой.
import openai
def is_model_disabled(err: openai.APIStatusError) -> bool:
return err.status_code == 503 and "model_disabled" in err.response.texterr.response — объект ответа httpx, поэтому проверка работает и с OpenAI SDK, и с Anthropic SDK (у anthropic.APIStatusError есть те же поля status_code и response).
Устойчивый вызов: цепочка запасных моделей
Задайте предпочитаемую модель и запасные. При model_disabled код переходит к следующей, при временном 503 — делает паузу и повторяет.
import time
import openai
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_ваш_ключ")
MODEL_CHAIN = ["claude-opus-5-5", "claude-sonnet-5", "gpt-5.6-sol"]
def chat(messages: list, chain: list[str] = MODEL_CHAIN, retries: int = 2):
for model in chain:
for attempt in range(retries + 1):
try:
return client.chat.completions.create(model=model, messages=messages)
except openai.APIStatusError as e:Если при старте приложения хочется сразу отсеять отключённые модели, отфильтруйте цепочку по списку из /v1/models:
def usable_chain(chain: list[str]) -> list[str]:
try:
available = set(get_available_models())
except requests.RequestException:
return chain
return [m for m in chain if m in available] or chainПри сетевой ошибке функция возвращает исходную цепочку: лучше попробовать модель и обработать ошибку, чем остановить приложение из-за недоступного списка.
Модель — в конфиг, а не в код
Вынесите название модели в переменную окружения — тогда замена модели не требует релиза:
FETCH_KEY=fetch_...
LLM_MODEL=claude-sonnet-5
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.zukko.pro",
api_key=os.environ["FETCH_KEY"],
)
MODEL = os.getenv("LLM_MODEL", "claude-sonnet-5")
response = client.messages.create(
model=MODEL,
max_tokens=1024,
messages=[{"role": "user", "content": "Привет"}],
)
print("".join(b.text for b in response.content if b.type == "text"))Здесь Anthropic SDK, поэтому адрес указан без /v1 — SDK добавляет его сам. Для OpenAI SDK адрес — https://api.zukko.pro/v1.
Кэширование списка
Запрашивать /v1/models перед каждым вызовом незачем. Достаточно обновлять список при старте и затем раз в какое-то время, например раз в час:
import time
_cache = {"models": None, "ts": 0.0}
def get_models_cached(ttl: int = 3600) -> list[str]:
now = time.time()
if _cache["models"] is None or now - _cache["ts"] > ttl:
_cache["models"] = get_available_models()
_cache["ts"] = now
return _cache["models"]Даже с кэшем держите обработку model_disabled в коде вызова: модель могут отключить между обновлениями списка.
Почему список меняется
- Вендоры выпускают новые версии, и они появляются в каталоге.
- Старые версии отключаются — у вендора или в шлюзе.
- Модель может быть отключена временно.
Новости о каталоге публикуются в Telegram-канале Zukko. Но код не должен зависеть от того, успели ли вы прочитать новость: опирайтесь на /v1/models и обработку model_disabled. Если ещё нет ключа для запросов к моделям, создайте его в разделе API-ключи.
Частые вопросы
Нужен ли ключ для GET /v1/models?
Нет, эндпоинт публичный. Ключ нужен для запросов к самим моделям — /v1/chat/completions, /v1/messages и другим.
Показывает ли список только модели, разрешённые моему ключу?
Нет, список общий. Ограничения ключа (allowed_models) проверяются при запросе к модели: если модели нет среди разрешённых, вернётся 403 model_not_allowed_for_key.
Что вернёт запрос к отключённой модели?
HTTP 503 с кодом model_disabled в теле ответа. Не повторяйте такой запрос — переключитесь на другую модель из цепочки или из актуального списка.
Как часто меняется список?
Регулярного графика нет. Поэтому код должен проверять список при старте и корректно обрабатывать model_disabled в любой момент.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- xAI Grok API: подключение Grok 4.7, цена и контекст 256KКак вызвать grok-4.7 через OpenAI-совместимый API, что делать с лимитом контекста 256K и сколько стоят типичные запросы. Плюс сравнение с Grok 4.6.
- Grok API из России: как подключить без зарубежной картыПошагово подключаем Grok 4.7, 4.6 и 4.5 через шлюз: ключ, адрес, первый запрос на curl и Python, стриминг, картинки и оплата по СБП или в крипте.
- Claude Sonnet 5.5 через API: подключение, цены и кэш на 18 октября 2026Как вызвать claude-sonnet-5-5 из Python и curl, сколько стоит типичный запрос с кэшем и без и чем модель отличается от Sonnet 5 и Sonnet 4.6.
- Claude на Android в России: что делать, если приложение не ставитсяЕсли официальное приложение Claude не ставится на Android в России, пользоваться моделью с телефона всё равно можно: через веб-чат шлюза или клиент на своём ключе.