Claude Code разговаривает по Anthropic Messages API. Ему нужен HTTPS-адрес, на котором отвечает POST /v1/messages, и ключ. Если эндпоинт отдаёт только OpenAI-совместимый /v1/chat/completions, с Claude Code он напрямую не заработает — это другой протокол. Поэтому первый вопрос к владельцу шлюза — какой формат он поддерживает.

Второй вопрос — в каком заголовке шлюз ждёт ключ. Вариантов два, и от ответа зависит, какую переменную ставить. Authorization: Bearer <ключ> требует переменной ANTHROPIC_AUTH_TOKEN, а x-api-key: <ключ> — переменной ANTHROPIC_API_KEY. Если владелец не уточнил, разумно начать с ANTHROPIC_AUTH_TOKEN: проверка ниже покажет, угадали ли вы. Значительная часть ошибок 401 в этой теме возникает именно из-за того, что ключ положили в переменную, которая отправляет его не в тот заголовок.

Заголовок с ключомПеременная окружения
Authorization: Bearer <ключ>ANTHROPIC_AUTH_TOKEN
x-api-key: <ключ>ANTHROPIC_API_KEY

Способ первый — переменные в shell. Это самый быстрый вариант, годится, чтобы попробовать: export ANTHROPIC_BASE_URL и export ANTHROPIC_AUTH_TOKEN, после чего запускается claude. Минус очевиден — настройка живёт только в этом терминале. Откроете новую вкладку, и Claude Code снова пойдёт в claude.ai.

Заголовок для ключа определяет переменную: Authorization: Bearer — это ANTHROPIC_AUTH_TOKEN, x-api-key — это ANTHROPIC_API_KEY.

Способ второй — файл ~/.claude/settings.json (на Windows это %USERPROFILE%\.claude\settings.json). В блоке env прописываются те же две переменные, и настройка становится постоянной. Здесь есть два момента, о которых редко пишут крупным шрифтом. Первый: если одна и та же переменная задана и в shell, и в settings.json, побеждает settings.json — именно поэтому export может «не действовать». Второй: не стоит класть ключ в.claude/settings.json внутри проекта. Этот файл коммитится и уезжает всем, кто клонирует репозиторий. Для проекта есть.claude/settings.local.json, он в.gitignore по умолчанию.

Способ третий — apiKeyHelper. Если ключ ротируется или лежит в хранилище секретов, вместо статической переменной указывается команда, которая печатает ключ в stdout. Команда должна печатать только ключ, без баннеров и логов, иначе Claude Code возьмёт мусор и вы получите сообщение о том, что скрипт apiKeyHelper падает. Ключ из хелпера отправляется сразу в обоих заголовках, так что вопрос «bearer или x-api-key» здесь отпадает.

Главный совет — проверить эндпоинт до запуска Claude Code. Не запускайте claude, пока не убедитесь curl-ом, что эндпоинт живой и ключ подходит: POST на $ANTHROPIC_BASE_URL/v1/messages с заголовками Authorization, anthropic-version: 2023-06-01 и content-type, телом с моделью, max_tokens и сообщением. Если шлюз ждёт x-api-key, заголовок Authorization заменяется на x-api-key.

Ответ читается так. JSON, который начинается с {"id":"msg_ и содержит "content":[...], означает, что всё работает. Ошибка про неизвестную модель — тоже хороший знак: адрес и ключ верные, шлюз авторизовал запрос и только потом отказал в модели, значит, надо узнать, как модели называются именно на этом шлюзе. 401 — ключ не тот или не в том заголовке; стоит попробовать второй заголовок, прежде чем писать владельцу. 403 с HTML-телом, когда в логах шлюза запроса вообще нет, означает, что запрос режется по дороге — CDN, корпоративным прокси или региональным фильтром; это не проблема Claude Code.

Только после успешного curl запускайте claude, отправьте любое сообщение и наберите /status. Во вкладке Status должны быть две строки: Base URL с вашим адресом и Auth token (или API key) с именем переменной. Если вместо этого там Login method с аккаунтом claude.ai — переменные до процесса не доехали.

Отдельная тема — имена моделей. Claude Code внутри оперирует алиасами opus, sonnet и haiku, а фоновые задачи гоняет на haiku-классе. Если на шлюзе модели называются иначе или каких-то нет, в env прописывается соответствие через ANTHROPIC_DEFAULT_SONNET_MODEL, ANTHROPIC_DEFAULT_OPUS_MODEL и ANTHROPIC_DEFAULT_HAIKU_MODEL. Строка про haiku особенно важна: Claude Code дёргает эту модель для служебных вещей, и если её на шлюзе нет, ошибка 404 прилетит в самый неожиданный момент.

Практический смысл всей этой настройки в том, что Claude Code перестаёт быть жёстко привязанным к аккаунту claude.ai. Для компании это означает возможность пустить трафик к моделям через внутренний шлюз — с единым учётом, лимитами и логированием. Цена такой гибкости — несколько переменных окружения и внимательность к деталям: заголовку с ключом, приоритету settings.json над shell и именам моделей на конкретном шлюзе.