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

Прежде чем править конфиг, выясните, виноват ли ключ. Сделайте запрос напрямую:

bash
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».

Проверьте:

bash
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 в корне проекта:

bash
{
  "$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 получит пустой ключ. Это самая частая причина «ключ же правильный». Что проверить:

bash
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:

bash
{
  "$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.