Переезд с OpenRouter на Zukko: что поменять в коде и конфигах

Переезд с OpenRouter на OpenAI-совместимый API Zukko — это адрес, ключ и названия моделей. Разбираем каждую замену, специфичные параметры OpenRouter и план выката.

5 мин · · разработка · сравнение

Если ваш код работает через OpenRouter и вы ищете альтернативу, переезд на Zukko обычно сводится к трём заменам: адрес API, ключ и названия моделей. Оба сервиса поддерживают OpenAI-совместимый формат, поэтому SDK и структура запросов остаются прежними. Ниже — что именно поменять, что делать со специфичными для OpenRouter заголовками и параметрами и как безопасно выкатить изменения.

Зачем переезжать

Решение зависит от ваших задач, поэтому только факты о Zukko:

  • один ключ fetch_... для моделей Claude, GPT и GLM, единый баланс в долларах, оплата за токены без подписки;
  • оплата из России доступна: СБП, карта РФ, крипта; пополнение от $1;
  • два формата API: OpenAI-совместимый и Anthropic-совместимый;
  • у ключей есть дневной и месячный лимит в $ и список разрешённых моделей.

Сравнить стоимость лучше на своём объёме: возьмите месячное число входных и выходных токенов из статистики OpenRouter и посчитайте по ценам Zukko — например, для Claude Sonnet 5: вход_млн × $0.30 + выход_млн × $0.30. Для агентов с большим повторяющимся контекстом учтите: в Zukko кэшированные токены оплачиваются по обычной входной цене.

Три точки переезда

1. Base URL. У OpenRouter — https://openrouter.ai/api/v1, у Zukko для OpenAI-совместимых клиентов — https://api.zukko.pro/v1.

2. Ключ. Создайте ключ в разделе API-ключи. Он начинается с fetch_ и показывается полностью один раз — сохраните его сразу.

3. ID моделей. OpenRouter использует идентификаторы с префиксом вендора (anthropic/claude-sonnet-5, openai/gpt-5.6-sol). В Zukko префикса нет: claude-sonnet-5, gpt-5.6-sol.

Пример: Python и OpenAI SDK

Было (OpenRouter):

bash
from openai import OpenAI

client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="sk-or-v1-...",
    default_headers={
        "HTTP-Referer": "https://example.com",
        "X-OpenRouter-Title": "My App",
    },
)

response = client.chat.completions.create(
    model="anthropic/claude-sonnet-5",
    messages=[{"role": "user", "content": "Привет"}],
)

Стало (Zukko):

bash
from openai import OpenAI

client = OpenAI(
    base_url="https://api.zukko.pro/v1",
    api_key="fetch_ваш_ключ",
)

response = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "Привет"}],
)
print(response.choices[0].message.content)

Заголовки HTTP-Referer и X-OpenRouter-Title (в старом коде может встречаться X-Title) по документации OpenRouter необязательны и нужны для атрибуции приложения в рейтингах OpenRouter. Zukko они не нужны — удалите их, чтобы не тащить лишнее.

То же на JavaScript/TypeScript:

bash
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.zukko.pro/v1",
  apiKey: process.env.ZUKKO_API_KEY,
});

const response = await client.chat.completions.create({
  model: "claude-sonnet-5",
  messages: [{ role: "user", content: "Привет" }],
});
console.log(response.choices[0].message.content);

Таблица замен

Найти (OpenRouter)Заменить (Zukko)
https://openrouter.ai/api/v1https://api.zukko.pro/v1
sk-or-v1-...fetch_...
anthropic/claude-sonnet-5claude-sonnet-5
Opus 5.5 (у OpenRouter номер версии записан через точку)claude-opus-5-5 (через дефис)
openai/gpt-5.6-solgpt-5.6-sol
openai/gpt-5.6-lunagpt-5.6-luna
z-ai/glm-5.3glm-5.3
z-ai/glm-5.3-flashglm-5.3-flash
алиасы вида ~anthropic/claude-sonnet-latestконкретный id из /v1/models
заголовки HTTP-Referer, X-OpenRouter-Title, X-Titleудалить

Идентификаторы OpenRouter сверены с его публичным списком моделей https://openrouter.ai/api/v1/models. Набор моделей Zukko меняется: актуальный список — GET https://api.zukko.pro/v1/models или страница «Модели» в кабинете.

Параметры, специфичные для OpenRouter

В теле запроса OpenRouter принимает собственные поля, которых нет в стандартном OpenAI API. Самые частые — models (массив запасных моделей) и provider (настройки маршрутизации между провайдерами); оба описаны в документации OpenRouter по маршрутизации. В документации Zukko таких полей нет, поэтому:

  • удалите provider и models из запросов;
  • если вам нужен fallback на другую модель, реализуйте его в своём коде: перехватите ошибку и повторите запрос с другим model;
  • найдите в коде все места, где эти поля передаются через extra_body, — их легко пропустить при поиске.

Стандартные параметры OpenAI API (messages, max_tokens, stream, tools и другие) переносятся без изменений. Справка — в разделе Chat Completions.

Стриминг

Код стриминга менять не нужно, но проверьте одну деталь: последний чанк может прийти с данными об использовании токенов и пустым списком choices. Перед обращением к chunk.choices[0] добавьте проверку:

bash
stream = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "Расскажи про HTTP/2"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

LangChain, Open WebUI, Dify и другие инструменты

LangChain: ChatOpenAI(model="claude-sonnet-5", base_url="https://api.zukko.pro/v1", api_key="fetch_...").

Open WebUI, Dify, LibreChat и похожие: в настройках добавьте OpenAI-совместимого провайдера, укажите Base URL https://api.zukko.pro/v1 и ключ fetch_..., затем выберите модели. Названия полей в разных версиях отличаются — сверьтесь с документацией самого инструмента.

Код на Anthropic SDK: укажите base_url="https://api.zukko.pro" без /v1 — SDK добавляет путь сам. Подробнее — в разделе Anthropic или OpenAI формат.

План переезда в продакшене

  1. Создайте отдельный ключ для теста с небольшим дневным лимитом и списком разрешённых моделей.
  2. Вынесите base URL, ключ и модель в переменные окружения, если они ещё зашиты в код.
  3. На staging замените значения и прогоните свои тесты, включая стриминг и вызов инструментов.
  4. Проверьте расход в кабинете и сверьте его с расчётом по формуле.
  5. Переключите продакшен. Откат — вернуть старые значения переменных и перезапустить приложение.

Коды ошибок Zukko, которые стоит обработать: 401 — неверный ключ, 402 — не хватает баланса, 403 — модель не разрешена для ключа, 413 — слишком большой запрос, 429 — слишком часто, 503 — провайдер недоступен.

Чек-лист

  • Ключ fetch_... создан и сохранён
  • Base URL — https://api.zukko.pro/v1 (для Anthropic SDK — https://api.zukko.pro)
  • У ID моделей убран префикс вендора, Opus 5.5 записан как claude-opus-5-5
  • Удалены заголовки HTTP-Referer, X-OpenRouter-Title, X-Title
  • Удалены поля provider и models
  • В стриминге есть проверка if chunk.choices
  • Тестовый запрос возвращает ответ, расход виден в кабинете

Частые вопросы

Нужно ли переписывать промпты?

Нет: модели те же, меняется только шлюз. После переезда всё равно прогоните свой тестовый набор — так вы убедитесь, что ID моделей и параметры заменены правильно.

Что делать с fallback-моделями из OpenRouter?

Перенесите логику в код: при ошибке повторите запрос с другим model. Если модель отключена, Zukko отвечает 503 с кодом model_disabled — по нему можно переключаться на запасную.

Как быстро проверить, что всё работает?

Отправьте короткий запрос к недорогой модели:

bash
r = client.chat.completions.create(
    model="glm-5.3-flash",
    messages=[{"role": "user", "content": "ping"}],
)
assert r.choices[0].message.content
print("OK")

Где почитать подробнее?

Быстрый старт и авторизация в документации Zukko.

zukko

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

за Claude Code & ChatGPT

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