Run OpenCode on every model through one provider block
OpenCode is the open-source terminal coding agent from Anomaly, and it takes custom model providers straight from opencode.json. One provider block pointing at Router One's OpenAI-compatible endpoint puts GPT, Claude, Gemini, and DeepSeek family models in its model picker behind a single key — and because agent sessions burn tokens unattended, every call lands in a per-request cost trace on the gateway, with a maxSpend cap on the key as the hard stop.
Configure OpenCode to use the Router One base URL
Add an entry under provider in opencode.json (project-level, or ~/.config/opencode/opencode.json globally) with npm set to @ai-sdk/openai-compatible, options.baseURL on the gateway, and one models entry per catalog model you want in the picker. The key can be read from an environment variable with the {env:VAR} syntax so it never sits in the file. Select a model as provider-id/model-id — router-one/<model-id> here — from the /models command in the TUI, or pin it in the top-level model field:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"router-one": {
"npm": "@ai-sdk/openai-compatible",
"name": "Router One",
"options": {
"baseURL": "https://api.router.one/v1",
"apiKey": "{env:ROUTER_ONE_API_KEY}"
},
"models": {
"<model-id-from-/models>": {
"name": "<label shown in the picker>"
}
}
}
},
"model": "router-one/<model-id-from-/models>"
}Which model ID should OpenCode send?
Copy the exact model ID from the /models page — IDs are case-sensitive, and the page lists each model's context window, capabilities, and current per-token rates. Create a dedicated API key per tool with its own maxSpend cap, so one runaway tool can't affect other workloads.
Verify the OpenCode call in your request trace
After your first request, open Dashboard → Logs to see its full trace: model, tokens, cost, latency, and status code. From here every OpenCode call has a ledger and a trail instead of being a black box.
FAQ
Why does OpenCode report the model as unknown or fail to authenticate?
Check three things in order: the provider id in the model string must match the key you used under provider (router-one/<model-id>), every model must be listed in that provider's models map with the exact ID from /models, and options.apiKey must resolve — with {env:ROUTER_ONE_API_KEY} the variable has to be exported in the shell that launches opencode, because an unset variable is replaced with an empty string rather than raising an error.
Can OpenCode use Router One's Anthropic-compatible endpoint for Claude models?
Yes, optionally. The OpenAI-compatible block above already serves the Claude family; if you want the native Messages API for those models, add a second provider with npm set to @ai-sdk/anthropic and options.baseURL set to https://api.router.one/v1 — the gateway serves Claude models natively on /v1/messages and accepts the same key in the x-api-key header that package sends. Keep the two providers under different ids so their model lists stay separate.
Which models can OpenCode use through the gateway?
Any chat-capable model in the catalog — GPT, Claude, Gemini, Grok, DeepSeek, GLM, MiniMax, and Doubao families. The /models page is the source of truth for model IDs and per-token rates.
Does this work from Mainland China?
Yes. The gateway is reachable from Mainland China without a VPN, and the configuration is identical to the global setup.
How do I debug a 401/403/429?
Open Dashboard → Logs first to see whether requests reached the gateway and with what status, then walk the error-codes reference to check env vars, key status, and limits.