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

ModelSWE-bench VerifiedContextBest for
deepseek-v4-pro80.6%1MDefault pick: frontier coding, cheap
deepseek-v4-flash~79%1MHigh 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 the model field of a request. deepseek-v4-pro and deepseek-v4-flash are 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 the baseURL and 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).

GET A DEEPSEEK ENDPOINT

Troubleshooting

DeepSeek doesn’t appear in /models

Check four things, in order:

  1. The provider ID from opencode auth login matches the provider key in opencode.json.
  2. The config file is valid JSON or JSONC.
  3. You restarted OpenCode after editing the config.
  4. The model is listed under the provider’s models object.

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.