DeepSeek through 9Router: models and request checks
Connect an authorized DeepSeek provider, discover current model IDs, and diagnose reasoning, context, and tool-call differences when routing through 9Router.
For a direct DeepSeek account, add an OpenAI-compatible provider in 9Router with base URL https://api.deepseek.com, save your DeepSeek key, and expose the chosen model under a local prefix. A third-party host serving DeepSeek models has its own endpoint, key and billing; this recipe is specifically for DeepSeek’s API.
You need a working local router, an eligible funded DeepSeek API account, curl and jq for the Bash/zsh examples. Each chat test may consume paid usage. The instructions below are source-reviewed; this Wiki has not run a paid DeepSeek benchmark.
1. Establish the direct API baseline
Set DEEPSEEK_API_KEY in your local environment. As checked on October 23, 2026, DeepSeek’s first-call documentation lists deepseek-flash; check its current catalog before copying that alias into an older installation. Start with thinking explicitly disabled so the comparison has fewer moving parts.
curl --fail-with-body -i https://api.deepseek.com/chat/completions \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"model":"deepseek-flash","messages":[{"role":"user","content":"Return a short greeting."}],"thinking":{"type":"disabled"},"stream":false}'
A successful baseline is a complete chat response with choices[0].message.content. If this fails, fix the direct account or payload first. Do not add 9Router to a request whose upstream credential already fails.
2. Save the DeepSeek route
Open Providers → Custom Providers (OpenAI/Anthropic Compatible) → Add OpenAI Compatible.
| Setting | Enter |
|---|---|
| Name | DeepSeek direct |
| Prefix | ds-local (an unused local namespace) |
| API Type | Chat Completions |
| Base URL | https://api.deepseek.com |
| Optional check key/model | DeepSeek key / the exact upstream model ID |
Select the API type first, then the URL. Although the form’s hint mentions /v1, the reviewed executor appends /chat/completions to this base, matching DeepSeek’s documented route. Do not substitute the separate /anthropic endpoint into this Chat Completions recipe.
Check may make an inference request when model discovery fails. Its API Key (for Check) is temporary validation input. Click Create, open the node, then Add API Key: give the connection a name, enter your DeepSeek API Key, set Default Model to deepseek-flash or your verified upstream choice, and Save.
Use Import from /models to discover models, or type the exact upstream ID into the models field and click Add. Copy the resulting model row; with the example prefix and model it is ds-local/deepseek-flash. The upstream Default Model remains unprefixed.
3. Repeat through the router
Set NINEROUTER_API_KEY to the local router key and ROUTER_MODEL to the copied local ID. Keep the same prompt and thinking setting as the direct baseline.
curl --fail-with-body --noproxy '*' http://localhost:20128/v1/models \
-H "Authorization: Bearer $NINEROUTER_API_KEY"
jq -n --arg model "$ROUTER_MODEL" \
'{model:$model,messages:[{role:"user",content:"Return a short greeting."}],thinking:{type:"disabled"},stream:false}' \
> /tmp/deepseek-router-probe.json
curl --fail-with-body --noproxy '*' -i \
http://localhost:20128/v1/chat/completions \
-H "Authorization: Bearer $NINEROUTER_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary @/tmp/deepseek-router-probe.json
Check both the returned chat body and the selected provider in the router log. The model-list response is discovery evidence only. If direct succeeds but local fails, compare the exact model ID, saved key, base URL and request body before adding a combo.
4. Add thinking as a separate comparison
DeepSeek’s thinking documentation describes an enabled thinking mode and reasoning effort. For the supported direct model, replace the disabled field with:
{"thinking":{"type":"enabled"},"reasoning_effort":"high"}
Merge those fields into the existing request object; this fragment is not a complete chat request. Run the direct version first, then the local version with the identical fields. Expect reasoning-capable responses to differ from the disabled baseline; do not assume another host accepts DeepSeek’s parameter names. With the Python OpenAI SDK, DeepSeek documents putting thinking inside extra_body.
Issue #5108 reports a translation failure involving thinking fields and a strict upstream. If only the enabled local request returns 400, keep the working disabled route, record the router version and redacted error, and inspect the installed release’s translation support. More retries or a larger token budget cannot repair an invalid schema.
Context and tools need their own checks
For a long-context rejection, shorten the same request until it succeeds, retaining the provider error and approximate size. A catalog context figure is not proof of the route’s effective limit; issue #5097 documents a route-specific discrepancy. Do not generalize its threshold to all DeepSeek accounts.
Before using an agent, test one harmless tool operation in a scratch directory and verify the tool result reaches the next turn. If enabling fallback changes the serving model, label the result accordingly. Continue with OpenCode setup or proxy diagnostics once the plain route is established.
References for this guide
- DeepSeek first API call
- DeepSeek error reference
- 9Router reasoning-parameter report
- 9Router context-limit report
- 9Router compatible-provider form
- 9Router saved key and default model
- 9Router compatible model controls
- DeepSeek thinking mode
- 9Router compatible URL construction
Steps were checked against the linked documentation and source. Provider access and model availability depend on your account. We do not claim a completed live model test unless explicitly stated.