Invalid API key в opencode: почему ключ не принимается и как проверить
Ошибка Invalid API key в opencode почти всегда сводится к четырём причинам. Проверяем ключ отдельно от opencode и находим, где ломается цепочка.
5 мин · · ошибки · IDE
Вы подключили шлюз, запустили opencode, отправили первый запрос и получили «Invalid API key» или просто «не работает». Ключ при этом скопирован из кабинета, и выглядит правильно. В этой статье разберём, почему invalid api key в opencode появляется при рабочем ключе, и пройдём проверку по шагам: от запроса без opencode до конфига и переменных окружения.
Адреса и формат ключа ниже относятся к Zukko: ключ начинается с fetch_, адрес для opencode — https://api.zukko.pro/v1. Если вы пользуетесь другим сервисом, логика проверки та же, а значения подставьте свои.
Шаг 1. Проверьте ключ без opencode
Прежде чем править конфиг, выясните, виноват ли ключ. Сделайте запрос напрямую:
curl -i https://api.zukko.pro/v1/models \
-H "Authorization: Bearer fetch_ваш_ключ"Читайте первую строку ответа. Ниже коды шлюза, которые встречаются и при такой проверке, и позже в работе (403 и 404 по имени модели появятся уже на запросах к конкретной модели):
| Ответ | Что значит |
|---|---|
200 и список моделей | ключ рабочий, проблема в opencode |
401 | ключ неверный: опечатка, обрезан, отозван или это не тот ключ |
402 | ключ верный, но не хватает баланса |
403 | ключ верный, но модель не разрешена для этого ключа (model_not_allowed_for_key) |
404 | неверный адрес или имя модели |
429 | исчерпан дневной или месячный лимит ключа |
Если пришло 200, переходите к шагу 2. Если 401, создайте новый ключ на странице ключей и повторите: полный ключ показывается только один раз при создании, поэтому потерять его конец при копировании проще, чем кажется.
Шаг 2. Убедитесь, что ключ попал в нужного провайдера
В opencode ключ привязан к провайдеру. Вы вводите его командой /connect в интерфейсе, и он сохраняется в файле ~/.local/share/opencode/auth.json (это описано в документации opencode). Типичная ошибка: ключ fetch_... вставлен в провайдер, который смотрит на другой сервер. Например, в «OpenCode Zen» или в OpenAI, у которых свои ключи. Для них ваш fetch_... действительно «invalid».
Проверьте:
opencode auth listКоманда показывает, для каких провайдеров сохранены учётные данные. Затем откройте список моделей (/models) и посмотрите, под каким провайдером выбрана модель. Если запрос уходит в провайдера, чей baseURL не переопределён на шлюз, он полетит на официальный сервер вместе с вашим ключом шлюза, и вы получите отказ.
Если вы задаёте ключ и в /connect, и в opencode.json (поле apiKey), в игре два источника. Какой из них имеет приоритет в вашей версии, лучше проверить по документации opencode, а надёжнее оставить один источник.
Шаг 3. Проверьте baseURL: нужен /v1
Для opencode через провайдер anthropic адрес указывается с /v1. Это отличается от Claude Code и официального Anthropic SDK, где /v1 не нужен. Без /v1 запросы уходят на /messages и дают 404. Такое 404 легко принять за проблему с ключом, особенно если интерфейс показывает общий текст ошибки.
Рабочий конфиг, глобальный ~/.config/opencode/opencode.json или opencode.json в корне проекта:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"anthropic": {
"options": {
"baseURL": "https://api.zukko.pro/v1",
"apiKey": "{env:ZUKKO_API_KEY}"
},
"models": {
"claude-sonnet-5-5": {},
"claude-opus-5-5": {}
}
}
}
}Конструкция {env:ИМЯ} — подстановка переменной окружения, она описана в документации opencode по конфигу. Если нужной модели нет в /models, проверьте, что её id указан в блоке models точно так, как в GET /v1/models. Как именно opencode строит каталог моделей для провайдера, сверьте с его документацией.
Шаг 4. Переменная окружения не подхватилась
Если вы используете {env:ZUKKO_API_KEY}, а переменная пустая, opencode получит пустой ключ. Это самая частая причина «ключ же правильный». Что проверить:
echo "${ZUKKO_API_KEY:0:8}"Должно вывести fetch_... (первые восемь символов). Пусто — переменной в текущем окружении нет. Типичные причины:
- переменная прописана в
~/.zshrc, но терминал открыт до правки: выполнитеsource ~/.zshrcили откройте новый; - вы используете другой шелл (bash вместо zsh) и правили не тот файл;
- opencode запущен из приложения или редактора, которые не читают файлы шелла: переменные нужно задать там, где запускается процесс;
- в значении остались кавычки, пробел или перевод строки после вставки из мессенджера.
Для проверки временно впишите ключ прямо в apiKey в конфиге, запустите opencode и посмотрите, исчезла ли ошибка. Если да, дело в окружении. Потом верните подстановку и не храните ключ в файлах, которые попадают в git.
Шаг 5. Альтернатива: провайдер через OpenAI-совместимый API
Если вам нужны не только Claude, а, скажем, gpt-6.1-sol или deepseek-v4.1-flash, можно завести отдельного провайдера. По документации opencode, для OpenAI-совместимых серверов используется пакет @ai-sdk/openai-compatible:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"zukko": {
"npm": "@ai-sdk/openai-compatible",
"name": "Zukko",
"options": {
"baseURL": "https://api.zukko.pro/v1",
"apiKey": "{env:ZUKKO_API_KEY}"
},
"models": {
"gpt-6.1-sol": { "name": "GPT-6.1 Sol" },
"deepseek-v4.1-flash": { "name": "DeepSeek V4.1 Flash" }
}
}
}
}Идентификатор провайдера (zukko) должен совпадать с тем, что вы вводили в /connect (пункт «Other»), если используете этот способ. Это прямо указано в разделе Troubleshooting на странице провайдеров в документации opencode.
Когда ошибка не про ключ
После того как curl вернул 200, а конфиг проверен, обратите внимание на соседние причины:
- 402 — баланс закончился. Пополните его в кабинете, статус виден в разделе «Использование».
- 403
model_not_allowed_for_key— у ключа задан список разрешённых моделей, а вы выбрали модель вне списка. - 429
key_daily_limit_reachedилиkey_monthly_limit_reached— сработал дневной или месячный лимит именно этого ключа. - 503
model_disabled— модель временно выключена, выберите другую изGET /v1/models.
Общую схему ошибок подключения смотрите в статьях Ошибка 401 invalid API key и Подключение opencode, а подробный разбор настроек — в документации по opencode.
Частые вопросы
Ключ работает в curl, но не в opencode. С чего начать?
Начните с opencode auth list и с проверки провайдера у выбранной модели. Затем убедитесь, что baseURL содержит /v1, и что переменная окружения, на которую ссылается конфиг, не пустая.
Почему при отсутствии /v1 я вижу ошибку про ключ, а не 404?
Интерфейс клиента может показывать общий текст ошибки независимо от кода ответа. Поэтому первым делом проверяйте ключ отдельно через curl -i: по коду ответа сразу видно, где проблема.
Можно ли хранить ключ прямо в opencode.json?
Технически можно, но файл часто лежит в репозитории проекта. Безопаснее переменная окружения или отдельный файл вне репозитория. Если ключ всё же попал в git, отзовите его в кабинете и создайте новый.
Нужен ли отдельный ключ для opencode?
Желательно. Отдельный ключ с дневным лимитом в долларах и списком разрешённых моделей ограничивает ущерб, если агент зациклится или ключ утечёт. Создать его можно в кабинете за минуту.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- JetBrains AI Assistant не работает: причины и обходные путиAI Assistant не активируется, молчит или недоступен в отдельных файлах. Разбираем причины по документации JetBrains и подключаем свои модели через шлюз.
- Ошибка 403 в Codex: причины и как продолжить работу403 в Codex бывает трёх видов: отказ по региону, проблема с аккаунтом и ограничения ключа на шлюзе. Показываем, как отличить их по тексту ошибки и что поправить.
- Cursor не работает: разбор частых проблем и как их исправитьCursor завис, пишет Reconnecting или не отвечает. Идём от простых причин к сложным и отдельно разбираем проблемы со своим ключом и шлюзом.
- Лимиты Cursor AI: как устроены и что делать, когда закончилисьЛимит в Cursor — это расход включённого объёма, а не число сообщений. Разбираем, что его съедает и четыре способа продолжить работу, когда он кончился.