DeepSeek Harness: connect a third-party API and diagnose Connection error
A third-party gateway goes into DeepSeek Harness through Add model provider → Custom model API: Provider ID, base URL, protocol, credential and at least one model. For go2llm that is https://go2llm.tech, protocol Anthropic Messages, key gk_sk_…. Connection error says nothing about your key or your model: DSH uses it when the request never reached the server.
Updated November 1, 2026. The go2llm production answers quoted here were checked with curl on the same day; prices come from catalog v43 of October 30, 2026.
Why the error is called Connection error
Connection error. is APIConnectionError from the Anthropic SDK that DSH runs on. The client got no HTTP response: DNS, TCP or TLS failed. There is no status code in that case, which is why the line talks about the connection rather than about a 401.
DSH retries that failure. In the chat it looks like this:
Retried model request (2/5) · 1s
Retry delay: 961ms
Failure reason: Connection error.
DSH repeats the request, and the turn stops after the last attempt. Changing the key while the line still reads Connection error changes nothing: the request never got far enough to be authenticated.
| What DSH shows | What it means | Where to look |
|---|---|---|
Connection error. | The request never reached the server | Network, proxy, VPN, base URL |
API key is invalid, 401 no-key | Key missing or unknown | The credential field, gk_sk_… |
403 key revoked / expired | Key revoked or expired | Key settings in the cabinet |
404 endpoint_not_found | Base URL carries an extra segment | /v1 in the address |
404 model_not_found | Model id is not in the published catalog | GET /v1/models |
402 insufficient_balance | Balance is gone | Cabinet, GET /v1/me |
429 rate_limit | More than 60 requests per minute per key | Retry-After |
A request without a key gets 401 no-key from go2llm. That is an authorization answer, not a broken connection, and one curl command tells the two apart.
The six fields of the Custom model API form
| Field | Value for go2llm | What breaks it |
|---|---|---|
| Provider ID | go2llm | Lowercase, and it cannot be renamed after saving |
| Display name | go2llm | Affects nothing |
| Base URL | https://go2llm.tech | A trailing /v1 returns 404 |
| API protocol | Anthropic Messages | Another protocol means another endpoint and another address |
| API key | gk_sk_… | Stored write-only in $DSH_HOME/.credentials.yaml |
| Models | At least one id from the catalog | An empty list will not save |
DSH offers three protocols: openai-completions, openai-responses, anthropic-messages. One provider speaks one of them, so a gateway serving both Anthropic and OpenAI styles is added twice.
Fetch available models calls GET {base URL}/models. go2llm publishes no route at the domain root: https://go2llm.tech/models answers 404, and the public catalog lives at GET /v1/models. Add the ids by hand instead: claude-sonnet-5, deepseek-v4-pro, kimi-k3, glm-5.3 are all in the /v1/models answer.
Where /v1 belongs, and where it breaks everything
The Anthropic client in DSH adds the path itself: the request goes to POST {base URL}/v1/messages. The base URL field therefore takes the domain root, with no /v1.
The mistake is one path segment long and reads as a riddle in the app. With https://go2llm.tech/v1 as the base URL, DSH calls https://go2llm.tech/v1/v1/messages. The gateway answered that path on November 1, 2026 with:
{"error":{"type":"endpoint_not_found","code":"endpoint_not_found",
"message":"/v1/v1/messages is not published by this gateway. Available: POST /v1/messages, …"}}
The gateway names the right route inside the message, but DSH shows a short line, and the doubled segment never reaches the screen.
Two correct addresses for one key:
- Anthropic Messages (DSH, Claude Code, Claude Agent SDK):
https://go2llm.tech - OpenAI Chat Completions (OpenAI SDK, OpenCode, LiteLLM):
https://go2llm.tech/v1
A 30-second check that skips DSH
Three commands answer whether the gateway or your network is at fault. All three were run against production on November 1, 2026.
# 1. Catalog, no key: expect 200 with a model list
curl -sS https://go2llm.tech/v1/models | head -c 200
# 2. The Anthropic route, no key: expect 401 no-key, not a timeout
curl -sS -X POST https://go2llm.tech/v1/messages \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-5","max_tokens":5,"messages":[{"role":"user","content":"hi"}]}' \
-w "\nHTTP %{http_code}\n"
# 3. A real request with the key
curl -sS https://go2llm.tech/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-5","max_tokens":120,"messages":[{"role":"user","content":"Reply with one word: works"}]}'
401 no-key on the second command means go2llm accepted the connection and refused authorization, so the host and port are reachable. Could not resolve host on the first command points at DNS or at the domain being unreachable from that machine.
The answer of go2llm to POST /v1/messages carries usage.cost_usd, the actual price of the call in dollars. The same field closes the SSE stream, so billing can be checked from inside the client.
When curl works and DSH does not
Four places where an application loses the connection, none of them in the key.
- VPN or a corporate proxy. A terminal and a desktop app do not necessarily share a route. If DSH does not use the same proxy as the terminal, set
HTTPS_PROXYandHTTP_PROXYin the environment that launches it, then restart the app. - Antivirus that inspects TLS. It replaces the certificate, Node rejects the chain, and from the outside that looks like a dropped connection.
- A malformed base URL.
http://instead ofhttps://, or a trailing space copied together with the address. curl typed by hand will not reproduce that. - A network that filters the domain. Corporate firewalls and some ISPs block unknown hosts. The check is the same first command from the block above.
The order that works: curl first, key second, model third. Until curl answers, there is nothing else to test.
The key, the limits, and what goes in the field
A go2llm key is issued in the cabinet and starts with gk_sk_. Registration adds $1 to the balance, enough for a first request without a top-up. Billing is pay-as-you-go: $1 minimum, payment by card transfer in rubles or in crypto, no subscriptions and no packs.
Per-key limits: 60 requests per minute across all models and endpoints, plus separate 60 RPM counters for GET /v1/me and POST /v1/messages/count_tokens, a dollar quota, an allowed-model list and an IP allow-list. The balance never goes below zero: the gateway reserves an estimate before the call and settles the actual cost after. GET /v1/me reports the balance, the quota and the configured rpm_limit of that key.
What it costs
Catalog v43, October 30, 2026. Prices are US dollars per 1M tokens; cache is cache read.
| Model | Input | Output | Cache | Vendor input / output / cache | Cheaper |
|---|---|---|---|---|---|
claude-sonnet-5 | 0.329 | 1.64 | 0.03288 | 2 / 10 / 0.2 | 6.1× |
claude-haiku-4-5 | 0.13 | 0.65 | 0.01299 | 1 / 5 / 0.1 | 7.7× |
deepseek-v4-pro | 0.066 | 0.198 | 0.0022 | 0.66 / 1.98 / 0.022 | 10.0× |
kimi-k3 | 0.302 | 1.51 | 0.03015 | 3 / 15 / 0.3 | 9.9× |
claude-sonnet-5-5 | 1.5 | 7.5 | 0.075 | 2 / 10 / 0.1 | 1.3× |
The top four rows are models usually picked for a coding agent; the fifth shows the floor of the discount, so the table is not a hand-picked best case. A coding agent spends most of its tokens on cache reads, so the number that matters is the blended price: 10% fresh input, 5% output, 85% cache read. For claude-sonnet-5 that is $0.1428 per 1M blended tokens against $0.87 at Anthropic's own price (platform.claude.com). Current prices and the catalog version live at GET /api/pricing.
Where this approach does not fit
The Custom model API form in DSH configures text calls and knows nothing about image generation: /v1/images/generations has no field there, so image models are wired separately through their own SDK or curl.
The model list does not fill itself: ids are typed by hand, and Fetch works only where GET {base URL}/models answers. A stale id copied from a six-month-old post returns 404 model_not_found; GET /v1/models is the only source that cannot be out of date.
A DeepSeek subscription is not replaced either: the DSH account route and a third-party provider coexist, and switching between them stays manual in the model menu.
What we verified and what we did not: the DSH form and the go2llm answers in this post were checked against the DeepSeek Harness documentation and against production with curl on November 1, 2026. This post does not contain a full live DSH run with a go2llm key, and we will not present one as verified. If your setup disagrees with this page, write to support@go2llm.tech or Telegram @go2llm_support.
What next
The error reference with retry strategies is in API errors, pricing and settlement on the pricing page, and the quick start with every endpoint in the documentation.
Get a key and send your first request in 3 minutes → https://go2llm.tech/