Route OpenCode Through an LLM Router (and Where Claude Code Fits)
Coding agents send a lot of requests: a title, a plan, then a long run of tool calls. When the model behind them returns 429 halfway through a refactor, the session stalls. Putting a router between the agent and your providers gives you one endpoint, one key, and automatic failover to another model or provider. This guide shows a tested setup for OpenCode and other OpenAI-compatible tools, then explains what Claude Code needs from a gateway, which is a different API.
As of 2026-10-20. Tested with OpenCode 1.19.3.
Which API each tool speaks
| Tool | API it calls | What a router has to expose |
|---|---|---|
| OpenCode | Any AI SDK provider. Custom providers use @ai-sdk/openai-compatible (/v1/chat/completions) | OpenAI-compatible Chat Completions |
| Aider, Continue, Cline, Roo Code, and most "OpenAI-compatible" settings | OpenAI Chat Completions | OpenAI-compatible Chat Completions |
| Claude Code | Anthropic Messages (/v1/messages), or Bedrock/Vertex/Foundry formats | An Anthropic-format endpoint |
That last row is the important one. Claude Code connects to "any gateway that exposes a supported API format", and those formats are Anthropic's, not OpenAI's. Anthropic also says it "doesn't support routing Claude Code to non-Claude models through any gateway."
OpenCode + SentioGate (tested)
SentioGate is an OpenAI-compatible router. Your provider keys (OpenRouter, OpenAI, Gemini, Groq, Mistral, DeepSeek, xAI) live in its encrypted Vault, you send model: "auto", and when a model rate-limits or fails it moves to the next key or model and remembers the cooldown.
1. Get a SentioGate API key (sg_live_...) from the dashboard, and export it:
export SENTIOGATE_API_KEY="sg_live_..."
2. Add the provider to opencode.json (in your project, or ~/.config/opencode/opencode.json):
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"sentiogate": {
"npm": "@ai-sdk/openai-compatible",
"name": "SentioGate",
"options": {
"baseURL": "https://api.sentiogate.dev/v1",
"apiKey": "{env:SENTIOGATE_API_KEY}"
},
"models": {
"auto": { "name": "SentioGate auto (failover)" },
"openrouter/anthropic/claude-sonnet-4": { "name": "Claude Sonnet 4 via OpenRouter key" }
}
}
},
"model": "sentiogate/auto",
"small_model": "sentiogate/auto"
}
autoroutes across the models you've enabled in your Vault and fails over between them.provider/model(for examplegroq/llama-3.3-70b-versatile) pins a specific model on your own key. SentioGate splits on the first/, so OpenRouter IDs keep their own slash:openrouter/anthropic/claude-sonnet-4.- Setting
small_modelkeeps OpenCode's background tasks, such as session titles, on your router too. Without it, OpenCode uses its own default small model for those.
3. Run it:
opencode run "Reply with exactly the word pong and nothing else."
# > build · auto
# pong
We ran exactly this against the live API (OpenCode 1.19.3). The build agent's request carries OpenCode's tool definitions and came back normally. The first run takes longer, because OpenCode installs the @ai-sdk/openai-compatible package.
What happens on a 429 mid-session
With your own keys, a 429 puts that model on that key into a shared cooldown (it honors the provider's Retry-After), and the request moves to your next key for the same model, then (with auto) to the next model in your pool. OpenRouter's daily free-model cap is recognized and parks all :free models on that key until 00:00 UTC. If nothing is left, OpenCode gets a fast 429 with a Retry-After header instead of a hung request.
Agent sessions are long, so a model switch partway through is a real trade-off. If you need one model throughout, pin a provider/model instead of auto. Pinned models get key failover only (add a second key for that provider) and are never swapped for a different model.
Trying it with no provider keys
A SentioGate key with no provider keys uses the community pool. During the beta that's a shared community tier (600 requests per 5 hours per user). It's enough to check the wiring. Coding agents burn through requests quickly, though, so add your own keys for real work.
Other OpenAI-compatible tools
The same three values work in any tool that has an "OpenAI-compatible" setting:
| Setting | Value |
|---|---|
| Base URL | https://api.sentiogate.dev/v1 |
| API key | your sg_live_... key |
| Model | auto, or provider/model |
For example, Aider documents OPENAI_API_BASE + OPENAI_API_KEY with an openai/ model prefix:
export OPENAI_API_BASE=https://api.sentiogate.dev/v1
export OPENAI_API_KEY=$SENTIOGATE_API_KEY
aider --model openai/auto
(We tested only the OpenCode and SDK paths live. Check other tools against their own docs.)
Claude Code + SentioGate
Claude Code reads ANTHROPIC_BASE_URL plus a gateway credential (see Connect Claude Code to an LLM gateway). The gateway has to speak the Anthropic Messages API and forward the headers Claude Code relies on. SentioGate exposes it at POST /v1/messages (plus /v1/messages/count_tokens) and accepts your SentioGate key as x-api-key or a Bearer token.
With your own Anthropic key saved in the Vault, Claude models go straight to Anthropic: the request and the response stream are passed through as Anthropic sends them (thinking, tool use, prompt caching), with SentioGate's key failover and usage tracking around them.
export ANTHROPIC_BASE_URL=https://api.sentiogate.dev
export ANTHROPIC_API_KEY=sg_live_your_key_here
claude
With an OpenRouter key instead, Claude model ids such as claude-sonnet-4 are sent as anthropic/<model> through OpenRouter and translated to and from the Messages format. Use the model ids OpenRouter lists.
Without any provider keys (the free community tier), SentioGate serves only auto on /v1/messages, on the free community models. It does not supply Claude models. Point every model slot at auto:
export ANTHROPIC_BASE_URL=https://api.sentiogate.dev
export ANTHROPIC_API_KEY=sg_live_your_key_here
export ANTHROPIC_MODEL=auto
export ANTHROPIC_SMALL_FAST_MODEL=auto
export ANTHROPIC_DEFAULT_HAIKU_MODEL=auto
export ANTHROPIC_DEFAULT_SONNET_MODEL=auto
export ANTHROPIC_DEFAULT_OPUS_MODEL=auto
claude
Any other model id without your own key returns 403 permission_error (community_model_only). Keep in mind Anthropic's note that it doesn't support routing Claude Code to non-Claude models: tool use with auto works, but quality depends on the model picked.
Two related details, so nobody is surprised:
- On the OpenAI-compatible endpoint (
/v1/chat/completions), your own Anthropic key works too: SentioGate translates the request to Anthropic's Messages API (streaming and tool calls included) and answers in OpenAI format. Useanthropic/<model>orauto. With an OpenRouter key instead, useopenrouter/anthropic/<model>. - Anthropic server tools (web search, code execution) work only on the native route with your own Anthropic key. On the translated routes, only your own (custom) tools are sent.
Troubleshooting
| Symptom | Likely cause |
|---|---|
401 invalid_api_key | SENTIOGATE_API_KEY isn't exported in the shell that runs opencode. |
Claude Code: 403 permission_error (community_model_only) | No provider keys in your Vault, and Claude Code asked for a Claude model. Set ANTHROPIC_MODEL=auto and the small/fast and default model variables to auto, or add your own Anthropic or OpenRouter key. |
403 no_enabled_models | auto found no enabled models in your Vault. Enable at least one model. |
403 community_pool_disabled_with_byok | You asked for the community pool (the community batch queue, or the older sentiogate-community model name) while provider keys are saved. Send auto or provider/model, or remove the keys to use the community pool. |
429 upstream_rate_limited with Retry-After | With your own keys: the provider rate-limited every model SentioGate tried. Wait the stated seconds, or add another key or provider. |
429 community_pool_exhausted with Retry-After | Community pool: you used your 600 requests for this 5-hour window. Retry-After is the time until it frees up; or add your own provider key in the Vault. |
503 community_busy with Retry-After | Community pool: the shared pool is briefly busy. Retry after the short Retry-After, or add your own provider key. |
| Model not found in OpenCode | The model key in opencode.json must match what you send (auto, or provider/model). Run curl -s https://api.sentiogate.dev/v1/models -H "Authorization: Bearer $SENTIOGATE_API_KEY" to list models. |
FAQ
Can Claude Code use SentioGate?
Yes. Set ANTHROPIC_BASE_URL to the SentioGate API host shown above, without /v1, and use your SentioGate key as ANTHROPIC_API_KEY. SentioGate exposes the Anthropic Messages API at /v1/messages.
Do I need my own Anthropic key for Claude models?
Yes, or an OpenRouter key. Without provider keys, SentioGate serves only auto on the free community models, and other model ids return 403 with community_model_only.
How do I point OpenCode at SentioGate?
Add a custom provider to opencode.json that uses @ai-sdk/openai-compatible with the base URL https://api.sentiogate.dev/v1 and your SentioGate key, then set model to sentiogate/auto.
What does 403 no_enabled_models mean?
auto found no enabled models in your Vault. Enable at least one model.
Sources
- OpenCode, Providers: Custom provider (last updated 2026-10-19, accessed 2026-10-20)
- Anthropic, Claude Code: Other LLM gateways (accessed 2026-10-20)
- Aider, OpenAI-compatible APIs
- LiteLLM, Claude Code tutorial
- SentioGate API reference