Add Router One to DeepSeek Harness as a custom model API
DeepSeek Harness (dsh) is DeepSeek's open-source agent harness: it runs tools on your machine and sends each model turn to the provider you configure. Its Settings → Models page takes a Custom model API provider, made of a base URL, one API protocol, a key and model IDs. Add Router One there and one key reaches the Claude, GPT, Gemini, Grok and DeepSeek chat models in the catalog, with every request in Dashboard → Logs. This guide follows the Web UI that dsh web starts. Checked against dsh 0.2.0-rc.2 (npm's latest tag on 2026-10-03), its providers guide and its source on 2026-10-03. dsh is still a preview: its README warns of compatibility-breaking changes, and per deepseek.com (checked 2026-10-03) DeepSeek Harness is in public preview, with desktop downloads for macOS and Windows, so match the steps to the version you run.
Start the dsh Web UI and create a dedicated key
Per dsh's README, run it from npm: install Node.js, then run npx @deepseek-ai/dsh web, which starts the Web UI at http://127.0.0.1:3080 and opens it in your default browser (--no-open skips the browser). On 2026-10-03, npm's latest tag was 0.2.0-rc.2, published on September 29, 2026; add @0.2.0-rc.2 to the package name to run exactly that version. Per dsh 0.2.0-rc.2's source, a first run with no working provider opens a prompt to add an API key for the official DeepSeek provider; choose Configure later there, because the Router One provider takes its own key. Then create a key for dsh alone in Dashboard → API Keys with Create Key and give it a maxSpend cap. An agent run sends one request per model turn, including every turn that only hands a tool result back to the model, so a long task can bill many requests without further input from you. The cap is the hard stop, and a dedicated key lets you filter Dashboard → Logs down to dsh's requests.
npx @deepseek-ai/dsh web # Web UI at http://127.0.0.1:3080 npx @deepseek-ai/dsh@0.2.0-rc.2 web # the version this guide was checked against
Add Router One as a Custom model API provider
Open Settings → Models and choose Add model provider. The card opens on Third-party model provider, dsh's list of vendors' own APIs; switch it to Custom model API. Enter a Provider ID such as router-one: it starts with a lowercase letter and uses only lowercase letters, digits and dashes, and dsh's docs say it is permanent, because requests, saved sessions, model defaults and the stored credential refer to it. Give the provider a display name such as Router One, set Base URL to https://api.router.one/v1 and API protocol to OpenAI Chat Completions, and paste the dedicated key into API key; per dsh's docs, keys are write-only and stored in $DSH_HOME/.credentials.yaml. Add at least one model by its exact catalog ID, for example anthropic/claude-sonnet-5 (the section on adding models covers Fetch available models), then choose Create provider. The models appear in the model picker. Picking one also makes it the default for new sessions, while a session that has already sent a request keeps the model it started with, so open a new session to switch. The finished form:
- Base URL (OpenAI Chat Completions, OpenAI Responses)
- https://api.router.one/v1
- Base URL (Anthropic Messages)
- https://api.router.one
# DeepSeek Harness:设置 → 模型 → 添加模型提供商 → 自定义模型 API # DeepSeek Harness: Settings → Models → Add model provider → Custom model API Provider ID: router-one 显示名称 / Display name: Router One API 地址 / Base URL: https://api.router.one/v1 API 协议 / API protocol: OpenAI Chat Completions API 密钥 / API key: sk-your-router-one-key 模型 ID / Model ID: anthropic/claude-sonnet-5 # GPT 的 ID:第二个提供商 / GPT IDs: a second provider router-one-responses OpenAI Responses https://api.router.one/v1 # 可选:Claude 原生格式 / Optional: Claude in its native format router-one-anthropic Anthropic Messages https://api.router.one
One provider per protocol: base URL and model IDs
dsh's docs put it plainly: a provider speaks one protocol, so a gateway that serves two needs two providers. Router One serves every chat model on Chat Completions; GPT-family, DeepSeek V4 and Grok chat IDs natively on Responses; and Claude-family and DeepSeek V4 IDs on Anthropic Messages, so the protocol you pick decides which IDs that provider can list. Enter the base URL without the final /chat/completions, /responses or /messages segment; dsh's form shows https://gateway.example/v1 as the placeholder for the two OpenAI protocols and https://gateway.example for Anthropic Messages. Keep the host root for Anthropic Messages: per dsh's architecture notes, Fetch available models accepts either spelling there, but chat requests use the base URL as entered and the Anthropic client adds /v1 itself. A Claude ID sent on the Responses provider is rejected with HTTP 400 before any model runs (model '<id>' must be called via /v1/messages or /v1/chat/completions), and a chat ID outside the Claude and DeepSeek families sent on the Anthropic Messages provider gets 400 with must be called via /v1/chat/completions.
| dsh API protocol (stored as) | Provider ID in this guide | Base URL | Router One request and model IDs |
|---|---|---|---|
| OpenAI Chat Completions (openai-completions) | router-one | https://api.router.one/v1 | POST /v1/chat/completions; every chat model: Claude, GPT, Gemini, Grok and DeepSeek IDs |
| OpenAI Responses (openai-responses) | router-one-responses | https://api.router.one/v1 | POST /v1/responses; GPT-family, DeepSeek V4 and Grok chat IDs |
| Anthropic Messages (anthropic-messages) | router-one-anthropic | https://api.router.one | POST /v1/messages; Claude-family and DeepSeek V4 IDs |
Add models: Fetch available models or exact IDs
In the form's model list, Fetch available models asks the endpoint with the base URL, protocol and key currently in the form. Per dsh 0.2.0-rc.2's source, it sends GET {Base URL}/models with a Bearer key for the two OpenAI protocols, and GET /v1/models with an x-api-key header for Anthropic Messages; Router One accepts either header. Router One answers that call only when a valid key is present, and its list is the whole catalog, image-generation models included, whichever protocol asked, so tick only the chat IDs the provider's protocol serves and choose Add selected. dsh's docs call discovery a convenience rather than a guarantee: when it fails or lists nothing, add each ID by hand with Add model, copied exactly from /models, and it works the same. Check every row before you save: per the same source, rows added by Fetch can carry capacity values taken from the listing. Set Context window from the model's page on /models, which shows the window rounded (1.05M, 500K), as a whole number rounded down: 1000000 for anthropic/claude-sonnet-5 and deepseek-v4.1-flash, 500000 for grok-4.7. Set Max output tokens to the cap you want, or clear it to fall back to dsh's own default for the provider; on reasoning models, thinking tokens count toward that cap, so leave headroom. For image input, dsh's docs have you edit the provider, open Customized settings and expand the model's Model options; tick Image under Input types only when the model page lists image input (deepseek-v4-flash, for example, is text-only).
Agent runs: tool calls, GPT IDs and the Responses provider
dsh runs its tools locally, on the machine where dsh itself runs, and sends each model turn to the provider of the model you picked; Router One carries only those model requests. Pick IDs whose model page lists tool calling. GPT IDs belong on the OpenAI Responses provider: per OpenAI's GPT-6 guide (checked 2026-10-03), GPT-6 Astra and GPT-6.1 Sol call tools only through the Responses API and do not accept reasoning effort none, and GPT-6 Sol calls functions on Chat Completions only with reasoning effort none. Router One serves GPT-family models natively on /v1/responses, so add openai/gpt-6.1-sol or openai/gpt-5.6-sol to router-one-responses, not to the Chat Completions provider. Claude IDs work on Chat Completions or on an Anthropic Messages provider, Gemini IDs on Chat Completions, Grok IDs on Chat Completions or Responses, and DeepSeek V4 IDs on any of the three. Every turn, including each one that only returns a tool result, is a separate billed request in Dashboard → Logs.
Reasoning levels and request settings in cordis.patch.yml
The Models page has no field for reasoning levels or request-compatibility switches. dsh keeps them in $DSH_HOME/profiles/<profile>/cordis.patch.yml, the same file the page writes; for the standard Web UI launch with dsh web, <profile> is web (per dsh's docs), and Open configuration file in the Settings header opens the file when the browser runs on the same machine as dsh. Edit the provider entries the page wrote and keep their other fields and models, because a Cordis override replaces the whole entry; dsh re-reads the file on the next request. A model entered by hand declares no reasoning levels, so no Effort menu appears for it and the model's own default decides whether it thinks. Add reasoningEfforts to the model to get the menu, as for openai/gpt-5.6-sol below. Per dsh's docs, a model that declares levels has its system prompt sent with the developer role; Router One's Chat Completions reference documents the roles system, user, assistant and tool, so on the Chat Completions provider also set compat.supportsDeveloperRole: false. For GPT-6 Astra and GPT-6.1 Sol, do not set the off level to none in reasoningEfforts: per OpenAI's GPT-6 guide (checked 2026-10-03), neither model accepts none. The output cap needs no switch: dsh's docs say pi-ai sends it as max_completion_tokens to an address it does not recognize, and Router One's Chat Completions accepts both max_tokens and max_completion_tokens as the output cap (when both are sent, max_completion_tokens wins); on the Responses API the cap is max_output_tokens.
# $DSH_HOME/profiles/<profile>/cordis.patch.yml (dsh web: <profile> is web)
# Edit the entries the Models page wrote; keep their other fields and models.
- id: llm-pi-ai
config:
providers:
router-one:
compat:
supportsDeveloperRole: false
router-one-responses:
models:
- id: openai/gpt-5.6-sol
reasoningEfforts:
low: low
medium: medium
high: highWhich model ID should DeepSeek Harness send?
Copy the exact model ID from /models, preserving case, hyphens, and version suffixes; do not substitute a display name. Open its detail page and match the supported API endpoints, context window, and capabilities such as tool calling to the provider and features selected in DeepSeek Harness. A catalog listing does not mean the client can use every feature of that model. Give each client or application a dedicated API key with a maxSpend cap.
Which API protocol is DeepSeek Harness using?
OpenAI-compatible describes an interface format; it does not make Chat Completions (/v1/chat/completions), Responses (/v1/responses), and Anthropic Messages (/v1/messages) interchangeable. Check the installed client version, provider configuration, and actual request path against the model detail page and API compatibility fact sheet. A successful plain-text chat does not establish support for hosted tools, conversation state, or file-editing features.
Verify the DeepSeek Harness call in your request trace
Send a simple text request from DeepSeek Harness, then match its trace in Dashboard → Logs by time, model, and request_id: tokens, cost, latency, and status. Next, test streaming, tool calls, and multi-turn history separately. For failures, retain the actual request path, full error message, and request_id. If there is no matching log, check client configuration and connectivity before attributing the error to the gateway or upstream.
FAQ
Where do I add Router One in DeepSeek Harness?
In Settings → Models, choose Add model provider and switch the card from Third-party model provider to Custom model API; the third-party list covers vendors' own APIs with their own keys. Enter Provider ID router-one, Base URL https://api.router.one/v1, API protocol OpenAI Chat Completions, your Router One key and at least one exact model ID from /models, then choose Create provider. Add a second provider with OpenAI Responses for GPT IDs, and optionally a third with Anthropic Messages and the host root https://api.router.one for Claude in its native format.
DeepSeek Harness says the API key is invalid. What should I check?
First check which provider holds the key: the Router One key goes in the API key field of your Custom model API provider, while the DeepSeek card on Settings → Models holds a key for DeepSeek's own API. Paste the raw key only: per dsh 0.2.0-rc.2's source, Fetch available models refuses a key containing characters that no HTTP header can carry and asks for the raw key, and it reports a 401 from the endpoint with the hint check the API key. Then confirm that the key is still active in Dashboard → API Keys. dsh keeps keys write-only, so to replace a stored key, type the new value into the form.
Fetch available models fails or lists nothing. Can I still use the provider?
Yes. dsh's docs say to add the model IDs by hand when discovery fails or lists nothing, and that they work the same. A 401 there means the key in the form is missing or wrong, because Router One answers GET /v1/models only with a valid key. When the list does load, it is the whole catalog, image models included, so tick only the chat IDs that the provider's protocol serves.
Can I use Claude models in DeepSeek Harness?
Yes. Add Claude-family IDs such as anthropic/claude-sonnet-5 to the Chat Completions provider, or create an Anthropic Messages provider with the host root https://api.router.one for Claude's native message format; DeepSeek V4 IDs work on that provider too. Keep Claude IDs off the Responses provider, where they get HTTP 400. These requests bill to your Router One account: per token from the wallet, or from plan quota for the models each tier lists on /pricing.
Do I still need a DeepSeek API key?
Not for the Router One provider, which uses only your Router One key; deepseek-v4.1-flash and deepseek-v4-flash from the catalog run on it like any other ID. The DeepSeek card holds a key for DeepSeek's own API and is needed only for the models you run through that card. This guide covers the Web UI that dsh web starts and does not describe the desktop app's first-run screens; per dsh's architecture notes, the desktop app keeps its own profile, so its cordis.patch.yml is not the web one.
Can I point the built-in DeepSeek card at Router One instead?
No. Per dsh's docs, a built-in provider's model list always comes from dsh's installed catalog, even when its base URL points at a gateway, so its model IDs need not match Router One's. Add a Custom model API provider and use the IDs from /models.
Why is there no Effort menu for a model I added?
Per dsh's docs, a model entered by hand declares no reasoning levels, so the picker shows no Effort entry and the model's own default decides whether it thinks. Add reasoningEfforts to that model in cordis.patch.yml, as in the section above; on the Chat Completions provider, also set compat.supportsDeveloperRole: false.
Which models can DeepSeek Harness use through the gateway?
Choose a current catalog model that supports both the endpoint and the features DeepSeek Harness uses. Check /models and the model detail page for the exact ID, current rates, and capabilities; a family name such as GPT or Claude is not a compatibility guarantee. A client that lists a model has only read the ID, from its own configuration or from GET /v1/models; verify an actual request too.
Models are listed, but requests fail with 400 or 404. What should I check?
Record the actual request path and error message, then check the exact model ID. A 400 can indicate invalid parameters, unsupported tools, or a model/endpoint mismatch; a 404 can indicate an incorrect path or missing resource, so it does not by itself establish that a model was retired. If the error says must be called via, use the named endpoint or select a model supported on the current endpoint. Do not add or remove /v1 or /chat/completions across all clients indiscriminately.
Does this work from Mainland China?
Yes. Router One is reachable from Mainland China without a VPN, and dsh sends model requests from the machine it runs on straight to api.router.one, so the provider settings are the same everywhere. Installing dsh itself, with npx from the npm registry or as a desktop download from deepseek.com, is separate from Router One.
How do I debug a 401/402/403/429?
Match the request and error message in Dashboard → Logs. For 401, check whether the key was sent and is valid; for 402, check wallet balance and maxSpend; for 403, check key permissions and access restrictions. For 429, distinguish request/token limits from upstream throttling using the error details. Keep the request_id and follow the error-codes reference.