Connect a custom API provider to OpenCode
Add a custom OpenCode provider, align credentials and model IDs, and check the installed version before mixing provider/npm/options with the v2 configuration.
To connect a custom provider to OpenCode, register the credential, define the provider and its models, then select a model using provider_id/model_id. First run opencode --version: the regular documentation and the v2 documentation use different configuration fields. Copy a complete example for the version you actually run.
This guide was checked against the regular Providers documentation and v2 Providers documentation on September 9, 2026. Their differences do not establish that v2 is the latest stable package or that every installation should migrate. The configuration below is a documented template with placeholders, not a paid inference test.
Still choosing where to buy API access? Compare OpenCode API providers and billing options before adding a credential.
Check the installed version and configuration format
opencode --version
| Setting | Regular documentation | v2 documentation |
|---|---|---|
| Provider map | provider | providers |
| Runtime package field | npm | package |
| Options map | options | settings |
| Compatible runtime | @ai-sdk/openai-compatible | @opencode/ai/providers/openai-compatible |
| Base URL | provider.<id>.options.baseURL | providers.<id>.settings.baseURL |
Do not repair a configuration by changing just one of these keys. The package and options belong to the same version’s format. If the error names an unknown configuration field, confirm the executable and documentation version before investigating the remote API.
Add the credential and provider together
For the regular configuration path, run /connect inside OpenCode, choose Other, and enter a provider ID such as myprovider. Enter your API key when prompted. The credential ID must match the key used in the configuration.
The official documentation notes that this action stores a credential; it does not create the whole custom-provider configuration. Add an opencode.json file in the project with the following structure:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"myprovider": {
"npm": "@ai-sdk/openai-compatible",
"name": "My provider",
"options": {
"baseURL": "https://api.example.com/v1"
},
"models": {
"your-model-id": { "name": "My coding model" }
}
}
},
"model": "myprovider/your-model-id"
}
Replace https://api.example.com/v1 with your provider’s documented API base URL and your-model-id with an available model ID. These are placeholders and will not call a real service as written. Do not paste a website homepage into baseURL.
Keep the credential out of the JSON file. The example uses the credential registered through /connect; it does not require pasting a key into source control. If your provider is already built in, its documented connection flow may be simpler than a custom block. For Ofox, verify the endpoint in the SDK documentation and the exact remote model in the catalog; apply the OpenCode configuration format shown here.
Choose the runtime for the actual protocol
The regular documentation uses @ai-sdk/openai-compatible for compatible /v1/chat/completions services. For a provider or model that uses /v1/responses, it documents @ai-sdk/openai. A compatible-looking API key does not tell you which protocol the endpoint serves.
Use the provider’s current documentation to check the endpoint, credentials and model identifier together. Do not assume every model on a gateway supports the same request schema, tool calls or context limits. When an API call fails, record the response rather than changing the model name repeatedly without checking its cause.
Select the registered model
Run /models inside OpenCode after the provider is configured. The Models documentation defines selection as provider_id/model_id. In the example, that is myprovider/your-model-id; both parts must match the configuration keys.
The visible model name is a label. Changing name does not give the provider access to a nonexistent remote model. If you use a gateway whose model ID itself contains a slash, preserve that full provider-documented ID rather than dropping the vendor prefix.
Diagnose a missing model before replacing the key
| Symptom | Check |
|---|---|
| Credential saved, model absent | Provider/model declarations as well as the credential |
| Custom provider absent | Credential ID and provider map key match |
| Unknown configuration field | Installed version and the matching schema |
| 401 or 403 from the API | Key validity, intended service and access permissions |
| 404 or model-not-found | Endpoint path and exact remote model ID |
| Tool calls fail | Protocol and model/tool compatibility |
For the regular path, opencode auth list can help inspect registered credential entries. Do not print key values as a diagnostic step. If you change configuration or secrets, restart the affected process and inspect the resulting model list.
A stale registry or cache is one possible investigation path, not a universal explanation. A historical observation from one build should not be turned into a promise that running a command twice always fixes first-run setup.
When moving to a v2 setup
Use the v2 provider example in full. Besides the renamed maps and runtime packages, that page describes modelID as the identifier sent to the remote provider. Do not copy that field into an older installation merely because it looks similar to an alias field there.
Preserve a copy of your working configuration, change the version-specific fields together, then check loading and model selection before sending a task. Keep validation separate from real inference: a readable JSON file does not establish that the endpoint accepts your credentials or supports the selected model’s tools.
For another terminal agent’s setup, see the Pi custom-provider guide. If the connection works but a request is rate limited, use the 429 retry guide to distinguish transient limits from conditions that need a configuration or quota change.
Frequently Asked Questions
- Why is my custom model missing after /connect?
- The command stores credentials. The regular custom-provider flow also requires a matching provider block and model declaration in opencode.json.
- Can I mix provider and providers in the same example?
- Use the configuration documented for your installed version. The regular and v2 provider formats use different map, package and options fields.
- Which model string should I select?
- Use provider_id/model_id, matching the provider key and model key in the configuration. Confirm the remote model ID with the actual service.


