OpenRouter: один API ко всем моделям. Гайд 2026
Что такое OpenRouter?
OpenRouter - облачный шлюз к языковым моделям: один OpenAI-совместимый API и один баланс кредитов открывают сотни моделей разных лабораторий. Запрос к модели OpenRouter направляет одному из нескольких провайдеров, которые её обслуживают. Наценки на цены инференса нет, комиссия берётся при пополнении баланса.
TL;DR
- -Подключение - смена base_url на https://openrouter.ai/api/v1 и ключ OpenRouter. Модель задаётся строкой vendor/model, например anthropic/claude-haiku-5.5. Есть Anthropic-совместимый /api/v1/messages для клиентов формата Anthropic.
- -Цены моделей OpenRouter передаёт от провайдеров без наценки. Комиссию берут при пополнении: на тарифе Standard 5,5% с минимумом $0,80, криптовалютой 5%, на Business 8%. Пополнение на $5 обходится в $0,80 комиссии, то есть 16%.
- -За одной моделью стоят несколько провайдеров с разной квантизацией, ценой и поддержкой параметров. В проверке 7 ноября фильтр quantizations: ["fp8"] перевёл qwen/qwen3-coder с DeepInfra (fp4) на Venice, и запрос стал на 28% дороже.
- -Fallback по списку models списывает цену той модели, которая ответила. В проверке цепочка из :free-модели и Haiku 5.5 дважды ответила платной Haiku: бесплатный пул в этот момент был занят у провайдера.
- -Промпты по умолчанию OpenRouter не хранит, но политику хранения и обучения задаёт каждый провайдер. Для чувствительных данных включают provider.zdr: true или режим ZDR only в настройках аккаунта.
OpenRouter - облачный шлюз к языковым моделям: один OpenAI-совместимый API и один баланс кредитов открывают сотни моделей разных лабораторий, от Claude и GPT до открытых Qwen, DeepSeek и Gemma. Модель задаётся строкой вида anthropic/claude-haiku-5.5, а запрос OpenRouter направляет одному из провайдеров, которые эту модель обслуживают. На цены инференса наценки нет, комиссию берут при пополнении баланса. Сам OpenRouter в объявлении от 19 августа 2026 года писал о 400+ моделях и 10+ млн разработчиков.
Первый запрос делается сменой base_url. Сложности начинаются с денег и маршрутизации. Пополнение на $5 стоит $0,80 комиссии. Цепочка fallback «сначала бесплатная модель, потом платная» по факту оказывается платной. Одна и та же открытая модель у разных провайдеров работает в разной квантизации и с разным набором параметров, а запрос с tool_choice может попасть к провайдеру, который этот параметр молча проигнорирует.
Статья о том, как устроены каталог и провайдеры OpenRouter, сколько реально стоит пополнение, как управлять выбором провайдера и fallback, что происходит с данными и кэшем и как подключить Claude Code, OpenCode и Codex CLI. Поведение API проверено 7 ноября 2026 года на ключе с лимитом $5: скрипт на стандартной библиотеке Python, POST /api/v1/chat/completions, короткий промпт и max_tokens: 30. Все проверки вместе стоили $0,0018. Комиссию пополнения, BYOK, ZDR и Claude Code через OpenRouter в проверке не трогали, они описаны по документации.
Что такое OpenRouter и когда он нужен
OpenRouter закрывает четыре задачи. Даёт один API-формат ко многим лабораториям: код на OpenAI SDK переключается между Claude, GPT и Qwen сменой строки модели. Держит один баланс и один счёт вместо аккаунтов у каждого вендора. Переключается между провайдерами одной модели и, если попросить, между разными моделями. И показывает расход по ключам, моделям и провайдерам в одном месте.
| OpenRouter | Прямой API провайдера | LiteLLM Proxy | |
|---|---|---|---|
| Где работает | Облако OpenRouter | Облако провайдера | Ваш сервер |
| Ключи | Один ключ OpenRouter (или свои через BYOK) | Ключ на каждого вендора | Ключи провайдеров у вас, виртуальные ключи для команды |
| Оплата | Кредиты, комиссия при пополнении | Счёт у каждого вендора | Счета провайдеров, софт бесплатный |
| Fallback между лабораториями | Да, параметр models | Нет | Да, в config.yaml |
| Данные | Через OpenRouter и выбранного провайдера | Только провайдер | Через ваш хост и провайдера |
| Что обслуживать | Ничего | Ничего | Сервер, базу, обновления |
Прямой API выгоднее, когда работаете с одним вендором и вам нужны его функции в день выхода, без комиссии и без лишнего хопа: как устроен API Anthropic напрямую, разобрано в гайде по Claude API. Self-hosted шлюз нужен, когда ключи провайдеров не должны покидать ваш контур или нужны бюджеты на каждого сотрудника, об этом гайд по LiteLLM. Где шлюз стоит в архитектуре с несколькими провайдерами, описано в статье о провайдерах LLM в production.
Модели и провайдеры: как устроен каталог
Каталог доступен без ключа: GET https://openrouter.ai/api/v1/models. На 7 ноября 2026 года в нём 460 записей, включая варианты :free и :batch и служебные роутеры. Больше всего моделей у openai (98), google (43), qwen (43) и anthropic (30). Число меняется почти каждый день.
Идентификатор модели - vendor/model. Кроме конкретных версий есть алиасы с тильдой: ~anthropic/claude-sonnet-latest всегда указывает на новейшую модель семейства (latest resolution). Алиас удобен для прототипа, для production версию лучше закрепить, чтобы поведение не поменялось без вашего релиза.
К идентификатору добавляют суффиксы. По FAQ они бывают двух видов:
| Суффикс | Вид | Что делает |
|---|---|---|
:free | Каталожный | Бесплатная версия модели, отдельная запись со своими лимитами |
:batch | Каталожный | Пакетная обработка, у Claude 5.5 вдвое дешевле |
:nitro | Маршрутный | Провайдеры по скорости (throughput) плюс priority-эндпоинты |
:floor | Маршрутный | Провайдеры по цене плюс flex-эндпоинты |
:exacto | Маршрутный | Порядок провайдеров по надёжности tool calling |
:online | Маршрутный, устарел | Веб-поиск в промпте; вместо него серверный инструмент openrouter:web_search |
Каталожные варианты есть только у моделей, где они перечислены в /models. Маршрутные работают на любой модели.
Одна модель, разные провайдеры
Большинство моделей обслуживают несколько провайдеров, и у каждого свой эндпоинт. Список виден без ключа: GET /api/v1/models/<vendor>/<model>/endpoints. Для открытых моделей разница между провайдерами бывает существенной.
Снимок для qwen/qwen3-coder на 7 ноября 2026 года:
| Провайдер | Квантизация | Цена за 1M (вход / выход) | Параметров | tool_choice | Контекст |
|---|---|---|---|---|---|
| DeepInfra | fp4 | $0,30 / $1,00 | 15 | none, auto, required, function | 262 144 |
| Venice | fp8 | $0,35 / $1,50 | 11 | только none и auto | 256 000 |
logit_bias, min_p, repetition_penalty и seed из этих двух провайдеров есть только у DeepInfra. Если запрос с tool_choice: "required" попадёт к Venice, ошибки не будет: по документации без специальных настроек неподдерживаемый параметр просто игнорируется.
У закрытых моделей разброс меньше, но он есть. Haiku 5.5 на ту же дату обслуживали Anthropic, Amazon Bedrock, Google Vertex, Azure и Claude Platform on AWS. Глобальные эндпоинты стоили $0,10 за 1M входных токенов, региональные (google-vertex/europe, amazon-bedrock/eu-west-1 и другие) - $0,11.
Быстрый старт: первый запрос
Нужны аккаунт и ключ на openrouter.ai/settings/keys, ключ имеет вид sk-or-v1-.... Базовый адрес API - https://openrouter.ai/api/v1. OpenRouter реализует OpenAI-совместимые /chat/completions, /completions и /responses (FAQ); примеры в Quickstart теперь написаны на /responses, но /chat/completions работает так же.
curl
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-H "HTTP-Referer: https://example.com" \
-H "X-OpenRouter-Title: My App" \
-d '{
"model": "anthropic/claude-haiku-5.5",
"max_tokens": 30,
"messages": [{"role": "user", "content": "Reply with exactly: ok"}]
}'
Заголовки HTTP-Referer и X-OpenRouter-Title необязательны: они нужны для атрибуции приложения в рейтингах openrouter.ai. Старое имя X-Title по документации тоже принимается.
OpenAI SDK
import os
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
resp = client.chat.completions.create(
model="anthropic/claude-haiku-5.5",
max_tokens=30,
messages=[{"role": "user", "content": "Reply with exactly: ok"}],
)
print(resp.choices[0].message.content)
В TypeScript то же самое: baseURL: "https://openrouter.ai/api/v1" в конструкторе OpenAI. Параметры, которых нет в OpenAI SDK (models, provider), передаются через extra_body, пример ниже в разделе про fallback.
Что приходит в ответе
Кроме обычных полей OpenAI-формата в ответе есть provider (кто реально обслужил запрос), model (какая модель ответила, важно при fallback) и usage.cost (стоимость в долларах). По документации usage accounting на 7 ноября usage с cost приходит в каждом ответе, параметр usage: {include: true} устарел и ни на что не влияет.
Проверено: 7 ноября 2026 года, anthropic/claude-haiku-5.5, промпт «Reply with exactly: ok». Ответ «ok» пришёл за 1,05 с, провайдер Claude Platform on AWS, 18 входных и 4 выходных токена, cost $0,0000038. Это сходится с ценой $0,10 / $0,50 за 1M токенов. Расход в GET /api/v1/key сразу после проверок показывал 0 и обновился через несколько минут.
Цены и комиссия OpenRouter
Цены моделей OpenRouter передаёт от провайдеров без изменений, в FAQ это сказано прямо: наценки на инференс нет. Платформа зарабатывает на комиссии при покупке кредитов.
| Тариф | Комиссия при пополнении | BYOK | Лимиты |
|---|---|---|---|
| Free | Не применяется | Нет | 50 запросов в сутки, только бесплатные модели |
| Standard | 5,5%, минимум $0,80; крипто 5% без минимума | $25 000 в месяц по прайсу без комиссии, сверх - 5% | Pay-as-you-go |
| Business | 8% | Как у Standard | Pay-as-you-go |
| Enterprise | По договору | Индивидуально | По договору |
Проценты 5,5% и 8% взяты со страницы Pricing, минимум $0,80 и 5% для крипто - из поста о комиссии (обновлён 11 июня 2026 года), условия на ноябрь 2026 года. Фактическое списание проверить не удалось: на аккаунте, где шли проверки, уже был баланс, нового пополнения не было.
Из-за минимума в $0,80 эффективная ставка зависит от суммы:
| Пополнение | Комиссия | Эффективно |
|---|---|---|
| $5 | $0,80 | 16% |
| $10 | $0,80 | 8% |
| $25 | $1,38 | 5,5% |
| $100 | $5,50 | 5,5% |
| $1000 | $55,00 | 5,5% |
Ещё несколько условий из Terms (редакция от 31 августа 2026 года). Одна покупка - от $5 до $25 000. Возврат неиспользованных кредитов можно запросить только в течение 24 часов после оплаты, комиссия не возвращается, криптоплатежи не возвращаются никогда. Неиспользованные кредиты OpenRouter вправе списать через 365 дней после покупки. Пополнять на год вперёд невыгодно.
Цены Claude 5.5 и Fable 5.1 в каталоге
На 7 ноября 2026 года, за 1M токенов:
| Модель | Вход | Выход | Чтение кэша |
|---|---|---|---|
| Fable 5.1 | $10 | $50 | $0,25 |
| Opus 5.5 | $4 | $20 | $0,20 |
| Sonnet 5.5 | $2 | $10 | $0,10 |
| Haiku 5.5 | $0,10 | $0,50 | $0,01 |
У всех четырёх есть :batch-варианты вдвое дешевле. Как считать стоимость не за токен, а за успешно решённую задачу, разобрано в статье об оптимизации LLM-расходов.
Provider routing: как выбрать провайдера
Если провайдер не указан, OpenRouter выбирает его сам. Алгоритм по умолчанию учитывает цену и стабильность провайдеров и меняется: на момент проверки 7 ноября документация описывает его как сравнение эффективной цены, скорости, времени до первого токена, частоты 429 и ошибок и качества tool calls. При ошибке провайдера запрос автоматически уходит к следующему. Задать sort, order, :nitro, :floor или собственный ключ провайдера значит отключить алгоритм по умолчанию.
Управляет выбором объект provider в теле запроса:
| Поле | По умолчанию | Что делает |
|---|---|---|
order | - | Список провайдеров по порядку |
allow_fallbacks | true | При false только провайдеры из order, иначе ошибка |
only / ignore | - | Белый и чёрный списки провайдеров |
sort | - | price, throughput или latency |
quantizations | - | Фильтр: int4, int8, fp4, fp8, fp16, bf16, unknown и другие |
require_parameters | false | Только провайдеры, которые поддерживают все параметры запроса |
data_collection | "allow" | "deny" исключает провайдеров, которые хранят данные и могут обучаться на них |
zdr | - | Только ZDR-эндпоинты |
max_price | - | Потолок цены за 1M токенов; если никто не подходит, запрос падает |
preferred_min_throughput, preferred_max_latency | - | Мягкие пороги скорости, медленных опускают в списке, но не исключают |
Пример: только fp8, не дороже $1 за 1M входных и $2 за 1M выходных токенов.
{
"model": "qwen/qwen3-coder",
"messages": [{"role": "user", "content": "Reply with exactly: ok"}],
"provider": {
"quantizations": ["fp8"],
"max_price": {"prompt": 1, "completion": 2}
}
}
Проверено: 7 ноября 2026 года, qwen/qwen3-coder, тот же короткий промпт.
| Запрос | Провайдер | cost, $ |
|---|---|---|
sort: "price" | DeepInfra | 0,0000059 |
sort: "throughput" | DeepInfra | 0,0000059 |
quantizations: ["fp8"] | Venice | 0,00000755 |
Без фильтра запрос ушёл на DeepInfra, у которого по /endpoints квантизация fp4. С фильтром fp8 его обслужил Venice, и запрос стал на 28% дороже. У открытой модели от квантизации зависит качество ответа, поэтому её лучше задавать явно.
Ошибка 404 и routing_funnel
Ошибки маршрутизации OpenRouter описывает подробно, это помогает при отладке.
Проверено: 7 ноября 2026 года, anthropic/claude-haiku-5.5, provider: {only: ["nonexistent-provider"], allow_fallbacks: false}. Ответ 404, в metadata список провайдеров модели (google-vertex, claude-on-aws, azure, anthropic, amazon-bedrock), routing_funnel по шагам и failed_routing_step. Воронка: 10 эндпоинтов, после фильтра региональной наценки 5, после фильтра провайдеров 0. В ошибке виден полный ID модели: anthropic/claude-haiku-5.5-20261007.
По воронке сразу видно, на каком фильтре отвалился маршрут: опечатка в slug провайдера, слишком жёсткий max_price или настройки приватности аккаунта.
Model fallbacks и Auto Router
Fallback между провайдерами одной модели включён по умолчанию. Fallback между разными моделями задаётся списком models в порядке приоритета (model fallbacks). Следующая модель пробуется при любой ошибке первой: превышение контекста, отказ модерации, rate limit, недоступность. Стоимость считается по модели, которая ответила, её имя приходит в поле model.
С OpenAI SDK список передают через extra_body. Модель из model пробуется первой, models - запасные по порядку:
resp = client.chat.completions.create(
model="anthropic/claude-haiku-5.5",
messages=[{"role": "user", "content": "Reply with exactly: ok"}],
extra_body={
"models": ["anthropic/claude-sonnet-5.5"], # запасные модели по порядку
},
)
print(resp.model) # какая модель ответила на самом деле
Проверено: 7 ноября 2026 года. Запрос с models: ["nonexistent-vendor/no-such-model", "anthropic/claude-haiku-5.5"] вернул 400 «is not a valid model ID». Список моделей валидируется до маршрутизации: опечатка в первой модели не уходит в fallback, а роняет весь запрос. Два запроса подряд с models: ["google/gemma-4-26b-a4b-it:free", "anthropic/claude-haiku-5.5"] оба вернули 200 от anthropic/claude-haiku-5.5 по $0,0000038 каждый: бесплатная модель в этот момент была ограничена у провайдера, и запрос молча ушёл на платную.
Документация об этом предупреждает: если в models за :free стоит платная модель, при fallback списывается цена платной. Чтобы запрос гарантированно остался бесплатным, в списке должны быть только :free-модели, либо используют роутер openrouter/free, который переключается только между бесплатными. В логах приложения стоит писать model из ответа, иначе переход на запасную модель останется незамеченным.
Для Anthropic-формата (/api/v1/messages) вместо models есть параметр fallbacks: не больше 3 записей, у каждой только поле model, совмещать с models нельзя, нарушение любого правила даёт 400.
Auto Router
Auto Router (openrouter/auto) выбирает модель сам под каждый запрос. Дополнительной платы за роутер нет, списывается цена выбранной модели, provider.max_price продолжает действовать. Роутеры OpenRouter обновляет часто: на 7 ноября в каталоге несколько записей с префиксом openrouter/ (auto, auto-code, free и другие), а страница Auto Router описывает уже новое поколение с параметром cost_tier. В проверке Auto Router не запускался. Для предсказуемых расходов в production модель лучше задавать явно.
Бесплатные модели (:free)
Модели с суффиксом :free стоят $0, это отдельные записи каталога со своими лимитами и провайдерами. На 7 ноября 2026 года в каталоге 12 таких записей плюс роутер openrouter/free. Лимиты по документации:
| Куплено кредитов за всё время | Запросов в минуту | Запросов в сутки |
|---|---|---|
| Меньше 10 | 20 | 50 |
| От 10 | 20 | 1000 |
Текущий дневной счётчик отдаёт GET /api/v1/key в поле free_model_daily_requests. Порог записан в документации с оговоркой: чтобы покрыть округление и комиссию, высокий дневной лимит включается на один кредит раньше. При отрицательном балансе ошибки возможны и на бесплатных моделях.
Проверено: 7 ноября 2026 года, google/gemma-4-26b-a4b-it:free. Ответ 429 «temporarily rate-limited upstream», limit_source: upstream_provider_shared_pool, провайдер Google AI Studio. В remedy_hint совет подключить свой ключ (BYOK) или выбрать другого провайдера. Заголовков X-RateLimit-* в ответе не было.
429 на :free возникает и тогда, когда личный лимит не исчерпан: пул бесплатной модели у провайдера общий, и личный счётчик здесь ничего не объяснит. Для чего-то кроме экспериментов бесплатные модели ненадёжны. Учтите и приватность: настройка, разрешающая провайдеров, которые обучаются на данных, в аккаунте задаётся отдельно для платных и бесплатных моделей (provider logging).
BYOK: свои ключи провайдеров
BYOK (bring your own key) - подключение собственного ключа провайдера, например Anthropic или Bedrock. Запросы по-прежнему идут через API OpenRouter, но инференс оплачивается на вашем аккаунте у провайдера, и rate limits тоже ваши. По документации BYOK и Pricing на тарифах Standard и Business первые $25 000 в месяц по прайс-листу проходят без комиссии, сверх этого с кредитов OpenRouter списывается 5% от стоимости такого же запроса. На тарифе Free BYOK нет. В старых сводках встречается правило «1 млн BYOK-запросов в месяц бесплатно», его заменили лимитом по стоимости.
Две детали, которые влияют на счёт:
- Shared capacity fallback. По умолчанию, если ваш ключ упёрся в лимит или вернул ошибку, OpenRouter переходит на свои эндпоинты и тратит кредиты. Чтобы этого не было, в настройках ключа выбирают «Never use shared capacity».
- Приоритет. Ключи бывают Prioritized (пробуются до эндпоинтов OpenRouter) и Fallback (после них). Без
orderв запросе провайдеры, для которых есть ваш Prioritized-ключ, идут первыми.
BYOK в проверке не тестировался: для него нужен отдельный ключ провайдера.
Приватность, логирование и ZDR
По FAQ OpenRouter логирует метаданные запроса (время, модель, число токенов), а промпты и ответы не сохраняет, если вы сами не включили логирование. За включённое логирование OpenRouter даёт скидку 1% на использование.
Запрос при этом уходит провайдеру, и у каждого провайдера своя политика. Документация ZDR на 7 ноября делит эндпоинты на три уровня:
| Уровень | Что с данными |
|---|---|
| ZDR (Zero Data Retention) | Промпты и ответы после обработки обычно не хранятся |
| Safety Retention | Провайдер или OpenRouter может хранить данные только для борьбы со злоупотреблениями, без обучения |
| Retention and Training | Хранение по политике провайдера, возможно обучение |
Как ограничить маршрут:
provider.zdr: trueв запросе: только ZDR-эндпоинты (и Safety Retention, если аккаунт их разрешает).provider.data_collection: "deny": без провайдеров, которые собирают данные.- Настройки приватности аккаунта или guardrails: режим ZDR only, запрет обучения. Если вы задали
provider, а под настройки аккаунта не подходит ни один провайдер, запрос завершится ошибкой.
У self-serve аккаунтов по умолчанию разрешён Safety Retention, у Enterprise только ZDR. ZDR распространяется на инференс, но не на плагины и серверные инструменты вроде веб-поиска: у них свои политики третьих сторон. На момент проверки страница ZDR также сообщает о скрининге всех запросов, включая ZDR-трафик, на CSAM; подозрительный контент может сохраняться для проверки. Для чувствительных данных политику конкретного эндпоинта стоит смотреть до отправки, а слой data policy держать на стороне приложения, как в архитектуре с несколькими провайдерами.
Кэширование промптов через OpenRouter
Кэш промптов работает у провайдера, поэтому повторный запрос должен попасть к тому же провайдеру. Для этого OpenRouter использует sticky routing (prompt caching). Он включается, только если чтение кэша у провайдера дешевле обычного входа, и не работает при ручном provider.order. Разговор определяется по хэшу первого system- и первого не-system сообщения либо по явному session_id в теле или заголовке x-session-id (до 256 символов). По документации на 7 ноября сессия живёт 60 минут без запросов.
Правила по провайдерам разные:
| Провайдер | Как включается | Запись в кэш | Чтение |
|---|---|---|---|
| Anthropic | Явно, cache_control (на блоке или на верхнем уровне запроса) | 1,25x входа (TTL 5 минут), 2x (TTL 1 час) | 0,1x входа; у Opus 5.5 и Sonnet 5.5 0,05x, у Fable 5.1 0,025x |
| OpenAI | Автоматически от 1024 токенов | Бесплатно у моделей до GPT-5.6, у GPT-5.6 и новее 1,25x (TTL 30 минут) или 2,5x (12 часов) | 0,1x или 0,05x входа у GPT-6 и GPT-6.1, у более старых моделей 0,25x или 0,5x |
| Alibaba Qwen | Явно, cache_control | 1,25x, TTL 5 минут | 0,1x входа |
Gemini, DeepSeek и формула окупаемости кэша разобраны в статье о prompt caching у разных вендоров.
Минимальная длина кэшируемого промпта у Claude 5.5 и Fable 5.1 - 512 токенов. Пример с кэшем на system-промпте:
{
"model": "anthropic/claude-haiku-5.5",
"messages": [
{"role": "system", "content": [
{"type": "text", "text": "<длинная инструкция или документ>",
"cache_control": {"type": "ephemeral"}}
]},
{"role": "user", "content": "Reply with exactly: ok"}
]
}
Сколько экономит кэш: проверка на Haiku 5.5
Проверено: 7 ноября 2026 года, anthropic/claude-haiku-5.5, system-промпт на 12 635 токенов с cache_control: {type: "ephemeral"}, два одинаковых запроса с паузой 2 с.
| Запрос | cached_tokens | cost, $ | Время, с |
|---|---|---|---|
| Первый (запись в кэш) | 0 | 0,00158 | 1,51 |
| Второй (чтение) | 12 619 | 0,00013 | 1,41 |
Второй запрос дешевле первого в 12 раз. Первый дороже обычного: 12 635 токенов по $0,10 за 1M дали бы $0,00126, а списано $0,00158, это надбавка 1,25x за запись в кэш. Оба запроса обслужил один провайдер, без этого чтение из кэша не случилось бы.
Кэш окупается со второго попадания, а промпт, который отправляется один раз, с cache_control стоит на 25% дороже. Метрики кэша приходят в usage.prompt_tokens_details.cached_tokens и cache_write_tokens. Как устроено кэширование на стороне Anthropic, описано в гайде по Claude API.
Tool calling и structured outputs: что различается
По каталогу на 7 ноября tools поддерживают 398 записей из 460, tool_choice - 393, structured_outputs - 387, response_format - 401. Это поддержка у модели в целом. У конкретного провайдера набор может быть уже, как у Venice для Qwen3 Coder.
По документации tools, формат ответа (response_format, structured outputs) и verbosity работают как мягкие предпочтения: если у модели есть провайдеры с поддержкой, запрос пойдёт к ним. Остальные параметры при require_parameters: false неподдерживающий провайдер просто игнорирует. Чтобы запрос шёл только к провайдерам, которые поддерживают все его параметры, ставят require_parameters: true.
{
"model": "qwen/qwen3-coder",
"messages": [{"role": "user", "content": "What time is it?"}],
"tools": [{"type": "function", "function": {
"name": "get_time", "parameters": {"type": "object", "properties": {}}}}],
"tool_choice": "required",
"provider": {"require_parameters": true}
}
Проверено: 7 ноября 2026 года, qwen/qwen3-coder, один инструмент get_time, tool_choice: "required", provider: {require_parameters: true}. Ответ 200, провайдер DeepInfra, в ответе есть tool_calls. Это совпадает с данными /endpoints: у Venice tool_choice: required не поддерживается, у DeepInfra поддерживается.
Для агентов, которые опираются на tool calls, require_parameters: true - разумное значение по умолчанию. Альтернатива - суффикс :exacto, который упорядочивает провайдеров по надёжности tool calling; в проверке он не запускался.
Подключение агентов: Claude Code, OpenCode, Codex CLI
Claude Code
По официальной инструкции OpenRouter Claude Code подключается переменными окружения, без локального прокси: OpenRouter принимает Anthropic Messages API.
export ANTHROPIC_BASE_URL="https://openrouter.ai/api"
export ANTHROPIC_AUTH_TOKEN="$OPENROUTER_API_KEY"
export ANTHROPIC_API_KEY="" # явно пустая, иначе конфликт
# необязательно: закрепить модели по классам
export ANTHROPIC_DEFAULT_SONNET_MODEL="~anthropic/claude-sonnet-latest"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="~anthropic/claude-haiku-latest"
claude
Если раньше вы входили в Claude Code через аккаунт Anthropic, один раз нужен /logout, иначе кэшированный вход конфликтует с ключом шлюза. Переменные кладут в профиль оболочки, а не в проектный .env: нативный установщик Claude Code его не читает. Подключение проверяют командой /status: строка Auth token должна называть ANTHROPIC_AUTH_TOKEN.
У схемы два предупреждения. В самой инструкции OpenRouter сказано, что работа гарантируется только с провайдером Anthropic first-party, и его советуют ставить первым в provider routing. А документация Claude Code прямо пишет, что Anthropic не одобряет и не проверяет сторонние шлюзы и не поддерживает работу Claude Code с моделями не от Anthropic через любой шлюз. Официальной поддержки Anthropic у связки Claude Code и OpenRouter нет, она работает на ваш риск. В проверке для этой статьи Claude Code через OpenRouter не запускался. Что ещё есть у Claude Code с альтернативными провайдерами, разобрано в статье Claude Code в России.
OpenCode
В OpenCode OpenRouter - встроенный провайдер (инструкция). В TUI выполняют /connect, выбирают OpenRouter и вводят ключ, затем /models выбирает модель. Дополнительные модели добавляют в opencode.json по их slug в OpenRouter. Конфигурация агента и тест моделей разобраны в гайде по OpenCode.
Codex CLI
Codex CLI подключается блоком провайдера в ~/.codex/config.toml (инструкция):
model_provider = "openrouter"
model = "<vendor/model из каталога>"
[model_providers.openrouter]
name = "openrouter"
base_url = "https://openrouter.ai/api/v1"
[model_providers.openrouter.auth]
command = "sh"
args = ["-c", "echo $OPENROUTER_API_KEY"]
Вариант env_key = "OPENROUTER_API_KEY" тоже работает, но тогда Codex не загружает каталог моделей OpenRouter и для моделей не от OpenAI показывает предупреждение о неизвестной модели.
Лимиты и ошибки
| Код | Когда | Что делать |
|---|---|---|
| 400 | Невалидный ID модели (в том числе в models), лишние поля в fallbacks | Проверить ID по /api/v1/models |
| 402 | Не хватает кредитов или исчерпан in-flight budget | Смотреть metadata.reason, снизить max_tokens, пополнить |
| 404 | Ни один провайдер не прошёл фильтры (only, max_price, приватность) | Смотреть routing_funnel и failed_routing_step |
| 429 | Лимит :free или общий пул провайдера | Смотреть limit_source, повторить с backoff, добавить fallback |
In-flight budget (limits) касается части предоплаченных аккаунтов с небольшим балансом и новых аккаунтов. OpenRouter резервирует оценённую стоимость идущих запросов, и при нехватке отвечает 402 даже при положительном балансе. reason: "in_flight_budget_exhausted" - временное состояние, ждут Retry-After. reason: "weight_exceeds_budget" - один запрос дороже всего бюджета, повтор не поможет, нужно уменьшить max_tokens или промпт.
Фиксированного RPM для платных моделей документация не называет: мощность управляется глобально, и дополнительные аккаунты или ключи лимит не увеличивают. 429 от провайдера OpenRouter сначала пытается обойти другими провайдерами той же модели и только потом возвращает клиенту. Расход и остаток лимита по ключу показывает GET /api/v1/key: поля limit_remaining, usage_daily, usage_weekly, usage_monthly. Лимит расходов можно задать на каждый ключ отдельно, это простой способ ограничить эксперимент или отдельный сервис.
Ограничения OpenRouter и когда нужен другой инструмент
- Данные проходят через третью сторону. Даже с ZDR запрос идёт через серверы OpenRouter и провайдера. Если ключи и трафик должны оставаться в вашем контуре, нужен self-hosted шлюз вроде LiteLLM или локальная модель: варианты собраны в гайде по локальным LLM, запуск разобран в гайде по Ollama, выбор между двумя популярными программами - в сравнении LM Studio и Ollama.
- Качество зависит от провайдера. Квантизация и поддержка параметров различаются у провайдеров одной модели, а провайдер по умолчанию может смениться без вашего участия. Для воспроизводимости фиксируют
quantizations,orderилиonlyи логируютproviderиз ответа. - Каталог меняется. У моделей появляется
expiration_date, цены и состав провайдеров меняются. Жёстко прописанный ID без мониторинга однажды начнёт возвращать ошибку. - Комиссия на мелких суммах. Пополнение на $5 обходится в 16% сверху. Вернуть кредиты можно только в первые 24 часа, а неиспользованные могут сгореть через год.
- Доступность по странам. Ограничения по странам и организациям задают провайдеры моделей, а Terms OpenRouter (п. 5.7) запрещают их обходить; условия стоит проверить до пополнения.
- Один вендор и его новые функции. Если работаете только с Anthropic или OpenAI и вам нужны свежие возможности API в день выхода, прямой API проще и дешевле на размер комиссии.
Как связать шлюз, fallback, evals и мониторинг в одну систему, описано в статье Production LLM Stack.
С чего начать
- Создайте ключ на openrouter.ai и сразу задайте на нём лимит расходов.
- Пополните баланс не меньше чем на $25, если планируете работать регулярно: на этой сумме комиссия выходит на 5,5%, а не 16%. Помните о 24 часах на возврат и сроке 365 дней.
- Подключите OpenAI SDK сменой
base_urlи логируйте из каждого ответаmodel,providerиusage.cost. - Для открытых моделей посмотрите
/api/v1/models/<id>/endpointsи зафиксируйтеquantizationsилиorder. - Для агентов и tool calls поставьте
provider.require_parameters: true. - Для чувствительных данных включите режим ZDR only в настройках приватности или
provider.zdr: trueв запросах. - Длинные system-промпты к Claude отправляйте с
cache_controlи проверяйтеcached_tokensво втором запросе.