RouteMux Docs
IntegrationsDev tool

OpenCode

Add RouteMux to opencode as a custom provider, for both the OpenAI and Anthropic protocol paths.

opencode reads providers from opencode.json in your project, or ~/.config/opencode/opencode.json globally. Each provider picks its own wire protocol, so one RouteMux key can serve both paths.

opencode the client, not OpenCode Zen

This page is about the opencode agent. OpenCode Zen is a separate paid model service run by the same project — it is an upstream, not a client, and nothing here applies to it.

OpenAI-compatible path (most models)

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "routemux": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "RouteMux",
      "options": {
        "baseURL": "https://api.routemux.com/v1",
        "apiKey": "{env:ROUTEMUX_API_KEY}"
      },
      "models": {
        "openai/gpt-5.5": {
          "name": "GPT-5.5",
          "limit": { "context": 1000000, "output": 128000 }
        }
      }
    }
  }
}

Three things decide whether this works:

  • npm is the protocol selector. @ai-sdk/openai-compatible sends /v1/chat/completions. Use @ai-sdk/openai instead if you want /v1/responses. You can override npm per model inside one provider block for a mixed setup.
  • Model keys must be exactly what the gateway returns. GET /v1/models is authoritative. A key that does not match is not a typo opencode can recover from — it simply will not resolve.
  • limit is not decoration. opencode uses it to track remaining context; leaving it out or copying the wrong numbers makes its context accounting wrong, not just cosmetic. The values are on each model's page.

A model is referenced as <providerID>/<modelID>. Our model ids already contain a slash, so the full reference has three segments:

opencode run --model routemux/openai/gpt-5.5 "hello"

Anthropic protocol path (Claude models)

Published anthropic/claude-* models are served on the Anthropic Messages protocol only — they return 400 MODEL_PROTOCOL_UNSUPPORTED on /v1/chat/completions. Override the built-in anthropic provider's base URL instead:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "anthropic": {
      "options": { "baseURL": "https://api.routemux.com/v1" }
    }
  }
}

This base URL keeps /v1 — unlike Claude Code

The AI SDK's Anthropic provider appends only /messages, so the base URL has to end at /v1. That is the opposite of Claude Code, where ANTHROPIC_BASE_URL is the bare origin and the client appends /v1/messages itself. Both land on the same endpoint; the field conventions differ.

Credentials

/connectOther stores a credential in ~/.local/share/opencode/auth.json and nothing more — you still have to write the provider block, and the id you typed must match the key in your config. A mismatch there is the first thing to check. opencode auth list shows what is stored. Using {env:ROUTEMUX_API_KEY} in options.apiKey skips /connect entirely.

Trimming the model picker

whitelist narrows first, then blacklist subtracts — both take the model ids shown in the picker. Useful when one RouteMux key can call more models than you want in the list.

What RouteMux does for you here

  • Thinking parameters are sanitised. Some opencode releases send extra keys inside thinking (a 1.18.26 build sent thinking.adaptive.block_binding). The upstream schema is strict and rejects the whole request over one unknown key, so RouteMux forwards only the keys the upstream accepts.
  • Your client User-Agent is not forwarded. Requests reach the upstream as RouteMux/1, which avoids bot rules that have 403'd specific client user-agents outright.

Verify

curl https://api.routemux.com/v1/chat/completions \
  -H "Authorization: Bearer $ROUTEMUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"openai/gpt-5.5","messages":[{"role":"user","content":"ping"}]}'

Troubleshooting

SymptomCause
Provider missing from the model listProvider id in opencode.json does not match the id used in /connect, or models is empty.
400 MODEL_PROTOCOL_UNSUPPORTEDA Claude model on the openai-compatible provider. Use the anthropic base URL override above.
404 on every requestbaseURL missing /v1, or pointing at a full operation path instead of the API root.
400 AUTH_AMBIGUOUS_API_KEYA key in options.apiKey and a different one in options.headers. Keep one.
Context warnings look wronglimit.context / limit.output do not match the model.
422 BILLING_INSUFFICIENT_CREDITSWallet lacks credit. Failed requests are not billed.

On this page