Default WorkspaceGuides
429 fallback, coding agents & gateway comparisons

Route OpenCode Through an LLM Router (and Where Claude Code Fits)

Updated · · Published · Facts and limits are dated; check the linked sources.

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

ToolAPI it callsWhat a router has to expose
OpenCodeAny 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" settingsOpenAI Chat CompletionsOpenAI-compatible Chat Completions
Claude CodeAnthropic Messages (/v1/messages), or Bedrock/Vertex/Foundry formatsAn 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"
}
  • auto routes across the models you've enabled in your Vault and fails over between them.
  • provider/model (for example groq/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_model keeps 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:

SettingValue
Base URLhttps://api.sentiogate.dev/v1
API keyyour sg_live_... key
Modelauto, 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. Use anthropic/<model> or auto. With an OpenRouter key instead, use openrouter/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

SymptomLikely cause
401 invalid_api_keySENTIOGATE_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_modelsauto found no enabled models in your Vault. Enable at least one model.
403 community_pool_disabled_with_byokYou 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-AfterWith 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-AfterCommunity 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-AfterCommunity pool: the shared pool is briefly busy. Retry after the short Retry-After, or add your own provider key.
Model not found in OpenCodeThe 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