Coding agents

Set up OpenCode with Router

Add Router to OpenCode as a custom provider in opencode.json. Nothing to install and no installer to run.

OpenCode can use any provider that speaks the OpenAI Responses API, so all you have to do is add Router as a provider in your opencode.json. This page shows how to do that by hand. We also offer automated setup using the Router installer, which makes the same changes.

Requirements: OpenCode (1.x or 2.x) and a Router API key from the API keys page.

The installer offers a richer experience: the Router installer adds a plugin to OpenCode that refreshes the model list automatically as Router adds models, fills in each model's limits, pricing, and reasoning levels, and shows a status line with the model that served your last prompt and your savings. With manual setup, you add and update models yourself.

1. Create an API key

Open API keys, create a key, and copy it. The secret is shown only once. Add it to your shell profile (for example ~/.zshrc) so OpenCode can read it:

export RAMP_ROUTER_API_KEY="your-router-key"

2. Add Router as a provider

OpenCode's global config lives at ~/.config/opencode/opencode.json. You can also put the same entry in an opencode.json at the root of a project to use Router for that project only. Create the file if it doesn't exist, or add the provider entry to your existing one.

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "ramp-router": {
      "npm": "@ai-sdk/openai",
      "name": "Ramp Router",
      "options": {
        "baseURL": "https://api.router.com/v1",
        "apiKey": "{env:RAMP_ROUTER_API_KEY}"
      },
      "models": {
        "gpt-5.6-sol": {
          "name": "GPT 5.6 Sol",
          "reasoning": true,
          "tool_call": true,
          "attachment": true,
          "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
          "limit": { "context": 1000000, "output": 128000 }
        }
      }
    }
  },
  "model": "ramp-router/gpt-5.6-sol"
}

Here is what the entry does:

Setting
What it does
npm
@ai-sdk/openai makes OpenCode call the Responses API, which is what Router serves. OpenCode downloads this package itself the first time it's needed.
options.baseURL
Router's address. Keep /v1 at the end.
options.apiKey
{env:RAMP_ROUTER_API_KEY} makes OpenCode read your key from the environment, so it never sits in the file.
models
The models that appear in OpenCode's picker. You list each one you want.
model
Optional. The model new sessions start on, written as ramp-router/<model-id>.

The limit values tell OpenCode how much a model can read and write, and modalities and attachment tell it what the model accepts. Without them, OpenCode won't send images or PDFs to the model. Take all of these from GET /v1/models, which reports each model's limits and input types. Router calls PDF input file, and OpenCode calls it pdf.

3. Add more models

You choose which models OpenCode offers, so add an entry under models for each one you want. List the models your key can use:

curl https://api.router.com/v1/models \
  -H "Authorization: Bearer $RAMP_ROUTER_API_KEY"

To generate the whole models list instead of typing it, this jq command writes a complete opencode.json with every model your key can use through the Responses API. It prints to the terminal, so merge the output into your own config, or redirect it to a new file if you don't have one yet:

Show less

curl -fsS https://api.router.com/v1/models \
  -H "Authorization: Bearer $RAMP_ROUTER_API_KEY" | jq '
{
  "$schema": "https://opencode.ai/config.json",
  provider: {
    "ramp-router": {
      npm: "@ai-sdk/openai",
      name: "Ramp Router",
      options: {
        baseURL: "https://api.router.com/v1",
        apiKey: "{env:RAMP_ROUTER_API_KEY}"
      },
      models: (
        [ .data[]
          | select(.router.surfaces | index("responses"))
          | .router.limits as $limit
          | .router.capabilities.modalities as $modalities
          | def kinds: [.[] | if . == "file" then "pdf" else . end | select(IN("text", "audio", "image", "video", "pdf"))] | unique | if length > 0 then . else ["text"] end;
          {
            key: .id,
            value: (
              { name: .display_name,
                reasoning: .router.capabilities.reasoning.supported,
                tool_call: .router.capabilities.tools.supported,
                attachment: ($modalities.input | any(. != "text")),
                modalities: { input: ($modalities.input | kinds), output: ($modalities.output | kinds) } }
              + (if $limit.context_window != null and $limit.max_output_tokens != null
                 then { limit: { context: $limit.context_window, output: $limit.max_output_tokens } }
                 else {} end)
              | with_entries(select(.value != null))
            )
          }
        ] | from_entries
      )
    }
  }
}'

Router adds models over time, so run the command again to refresh the list.

4. Start OpenCode

Run opencode, then use /models to pick a Router model. Models are listed as ramp-router/<model-id>. To check the setup without starting a session, list the models OpenCode knows about and look for the ramp-router/ entries:

opencode models

Reasoning levels

OpenCode shows reasoning levels for a model only if you describe them. The generated entry above marks reasoning models with "reasoning": true. To offer specific levels, add variants to the model, using the effort values the model reports in GET /v1/models:

"gpt-5.6-sol": {
  "reasoning": true,
  "variants": {
    "low": { "reasoningEffort": "low" },
    "high": { "reasoningEffort": "high" }
  }
}

Undo the setup

Remove the ramp-router entry from provider, and the model line if it points at Router. OpenCode then goes back to your other providers.

Troubleshooting

What you see
What to check
Router models don't appear in /models
The config isn't valid JSON, or RAMP_ROUTER_API_KEY isn't set in the shell that started OpenCode. Run opencode models and look for ramp-router/ entries.
Configuration is invalid ... Expected number, got null
A limit value is null or missing. Give both context and output a number, or remove limit.
401
The key is wrong or was revoked. Check it on the API keys page.
"Not found" or a 404
baseURL is missing /v1, or the model isn't available for your key.

If a failure persists, report it to the Router team with the x-request-id from the response. See Support and feedback.