OpenCode Integration Guide

Point OpenCode at TheRouter with one custom provider block, then reach every model on your rate card through a single key.

OpenCode speaks the OpenAI-compatible protocol, which is the protocol TheRouter serves at https://api.therouter.ai/v1. That makes the integration a configuration change rather than an adapter: one provider block, one key, and the models you already pay for become selectable inside the editor β€” with routing, failover, and billing staying in one place instead of one per vendor.

When this guide is the right one
Use this path if OpenCode is your primary client. If your team switches between OpenCode, Claude Code, Codex, and Gemini CLI, the cc-switch guide manages all of their presets from one place instead.

1. Create a routing key in TheRouter

Create a tenant API key in the dashboard. This is the key OpenCode will send. Do not use a management key.

text
Dashboard β†’ API Keys
Create Key
Copy the raw tenant key immediately

Expected format: sk-...

2. Export the key

Keep the key in the environment rather than in the config file, so it does not end up committed alongside the provider block.

bash
export THEROUTER_API_KEY="sk-..."

3. Add TheRouter as a custom provider

Add the block below to your opencode.json. List the models you actually want to see in the picker β€” the ids are TheRouter's standard model names, the same ones /v1/models returns.

json
{
  "provider": {
    "therouter": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "TheRouter",
      "options": {
        "baseURL": "https://api.therouter.ai/v1"
      },
      "models": {
        "anthropic/claude-opus-5": { "name": "Claude Opus 5" },
        "anthropic/claude-sonnet-5": { "name": "Claude Sonnet 5" },
        "openai/gpt-5.2-codex": { "name": "GPT-5.2 Codex" },
        "deepseek/deepseek-v3.2": { "name": "DeepSeek V3.2" }
      }
    }
  }
}

4. Validate the path before deeper debugging

Confirm the key and the model ids are live before touching the editor config again. If this returns your catalog, any remaining problem is on the client side.

bash
curl https://api.therouter.ai/v1/models \
  -H "Authorization: Bearer $THEROUTER_API_KEY" | head -c 400

Then restart OpenCode and send the smallest possible request against one of the models you listed.

Reasoning effort

TheRouter accepts reasoning_effort with the values low, medium, and high, and translates it to whatever the routed upstream expects β€” an effort level for OpenAI-style APIs, a thinking budget for Anthropic-style ones. You set one control and it survives a failover to a different provider.

bash
curl https://api.therouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $THEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.2-codex",
    "reasoning_effort": "high",
    "messages": [{"role": "user", "content": "Explain this stack trace."}]
  }'

Common mistakes

text
1. Using a management key instead of a tenant routing key
2. Setting the base URL without the /v1 suffix
3. Using an upstream vendor's own model id instead of TheRouter's standard name
4. Expecting a model you have not listed in "models" to appear in the picker
5. Forgetting to restart OpenCode after editing opencode.json
A hand-written provider block shows no prices
Prices come from the model catalog, not from your config, so a custom provider block renders without them. Your own rate card is always in the dashboard, and usage is billed the same either way.

Related setup paths

Open the adjacent guide when a different client is your primary one.

Help & contact