DeepSeek is the price-performance story in coding models right now, and OpenCode speaks the OpenAI-compatible API format DeepSeek serves. So wiring the two together is a short config block, not a project.
This is the OpenCode-specific walkthrough: the credential step, the provider block, which V4 model to point at, and the errors that send people to a search bar. If you run OpenClaw as well, the DeepSeek + OpenClaw guide covers that agent’s different config shape.
Which DeepSeek model to pick
| Model | SWE-bench Verified | Context | Best for |
|---|---|---|---|
| deepseek-v4-pro | 80.6% | 1M | Default pick: frontier coding, cheap |
| deepseek-v4-flash | ~79% | 1M | High volume, cheaper still |
Start with deepseek-v4-pro. It is a Mixture-of-Experts model (1.6T total parameters, ~49B active) with a 1M-token context window, and it posts frontier coding scores at sub-dollar token pricing after DeepSeek made its price cut permanent. Drop to deepseek-v4-flash when you are running heavy volume and want to shave cost for a small quality trade. For the fuller ranking, see best DeepSeek models for OpenClaw.
One thing to get right up front: use these V4 model IDs, not the old deepseek-chat / deepseek-reasoner names. More on that below, because the deadline matters.
Step 1: store the credential
OpenCode keeps credentials separate from provider config. Store the key first:
opencode auth login
Choose Other, enter a provider ID (use deepseek), and paste your DeepSeek API key. The credential lands in:
~/.local/share/opencode/auth.json
The provider ID you pick here has to match the key you use in config in the next step. Mismatching the two is the single most common reason a working key still fails.
Step 2: add the provider block
Open or create your OpenCode config. This is opencode.json in the project root, or a global file under ~/.config/opencode/. Add a provider entry using the same deepseek ID:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"deepseek": {
"npm": "@ai-sdk/openai-compatible",
"name": "DeepSeek",
"options": {
"baseURL": "https://api.deepseek.com/v1"
},
"models": {
"deepseek-v4-pro": { "name": "DeepSeek V4 Pro" },
"deepseek-v4-flash": { "name": "DeepSeek V4 Flash" }
}
}
}
}
What each field does:
npm: the SDK adapter. For any OpenAI-compatible API, use@ai-sdk/openai-compatible. OpenCode loads it on demand.options.baseURL: DeepSeek’s API root, ending in/v1.models: the keys must match exactly what DeepSeek accepts in themodelfield of a request.deepseek-v4-proanddeepseek-v4-flashare the current IDs.
Step 3: restart and pick the model
OpenCode does not always reload provider changes live. Quit it completely, start it again, then run:
/models
DeepSeek should appear with the models you listed. Select one and send a small prompt before turning it loose on real code.
Heads up: the legacy model names expire 2026-07-24
If you copied an older DeepSeek config from somewhere, it probably uses deepseek-chat or deepseek-reasoner. Those names are being discontinued after 2026-07-24. They currently map to V4 Flash in non-thinking and thinking mode for backward compatibility, but they stop resolving after that date.
For any new OpenCode setup, list deepseek-v4-pro and deepseek-v4-flash directly. If an existing config breaks in late July with a model-not-found error, this is almost certainly why. Swap the old name for a V4 ID and restart.
The easiest path: one endpoint, automatic failover
DeepSeek’s own API is cheap but not always calm under load. It returns 503s at peak hours and time-to-first-token can drift. If you would rather not write retry logic or manage a separate DeepSeek account, route through a gateway instead:
- haimaker.ai — point OpenCode at one OpenAI-compatible endpoint (
https://api.haimaker.ai/v1) and get DeepSeek V4 alongside hundreds of other models, with unified billing and automatic fallback to another model when DeepSeek is busy. Same block as above; swap thebaseURLand use your haimaker key with namespaced model IDs:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"haimaker": {
"npm": "@ai-sdk/openai-compatible",
"name": "Haimaker",
"options": {
"baseURL": "https://api.haimaker.ai/v1"
},
"models": {
"deepseek/deepseek-v4-pro": { "name": "DeepSeek V4 Pro" },
"deepseek/deepseek-v4-flash": { "name": "DeepSeek V4 Flash" }
}
}
}
}
- DeepSeek directly — the lowest nominal price if you only ever use DeepSeek and do not mind the occasional retry. Set a generous request timeout (60s or more).
Troubleshooting
DeepSeek doesn’t appear in /models
Check four things, in order:
- The provider ID from
opencode auth loginmatches the provider key inopencode.json. - The config file is valid JSON or JSONC.
- You restarted OpenCode after editing the config.
- The model is listed under the provider’s
modelsobject.
Authentication fails on the first request
The credential is missing or attached to the wrong provider ID. Run opencode auth list and confirm deepseek is there and matches your config. Do not put Bearer in the key field.
Model shows up but requests fail
The model ID likely does not match DeepSeek’s API. Custom providers pass model IDs through unchanged, so deepseek-v4-pro in your config must be exactly what the API expects. Verify the key and the model list directly:
curl https://api.deepseek.com/v1/models \
-H "Authorization: Bearer your-deepseek-api-key"
Requests time out or return 503
That is DeepSeek under load, not your config. Raise the request timeout, or route through a gateway with failover so a busy DeepSeek does not stall your agent.
The bottom line
DeepSeek drops into OpenCode with one provider block: store the credential, point baseURL at https://api.deepseek.com/v1, list deepseek-v4-pro, and restart. Use it directly for the rock-bottom token price, or route it through a gateway if you would rather have failover and one bill for every model. Either way, skip the legacy model names: V4 Pro is the model you actually want.