DeepSeek Harness (DSH) is built on the idea that everything is a plugin, but the box only ships two model providers: DeepSeek itself, and a generic OpenAI-compatible adapter called pi-ai. That second one is the door. You do not need to write a plugin to bring other models in — you point pi-ai at a gateway that already speaks OpenAI, and every model behind that gateway becomes selectable inside DSH.
APIMODELS is that gateway. One key, one balance, and 60+ models across Anthropic, OpenAI, Google, xAI, Moonshot and DeepSeek behind a single OpenAI-compatible endpoint. Because DSH is an agent framework, it burns tokens in loops rather than in single calls — which is exactly where paying per-token from one shared balance beats holding a separate account and a separate prepaid balance for every vendor.
There are two ways to add your API key. Most users follow steps 1–2 below: copy the config, launch DSH, then paste your key in Settings — no terminal required. Developers who prefer the command line can use the alternative path in step 3.
apimodels.yml
- id: llm-pi-ai
config:
providers:
apimodels:
displayName: APIMODELS
baseURL: https://api.apimodels.app/v1
api: openai-completions
models:
- id: claude-sonnet-5
name: Claude Sonnet 5
contextWindow: 200000
maxTokens: 8192
- id: deepseek-v4-flash
name: DeepSeek V4 Flash
contextWindow: 131072
maxTokens: 8192
# make it the default model DSH starts with
- id: agent-default-model
config:
provider: apimodels
model: claude-sonnet-52. Add your key in DSH
1. Launch DSH: npx @deepseek-ai/dsh web
2. Open Settings → Models → apimodels → paste your API key → Apply
3. Done — Claude, DeepSeek and any model you add are now availableFor developers — env var (alternative)
# Add this one line to apimodels.yml, then run:
# apiKeyEnv: APIMODELS_API_KEY
export APIMODELS_API_KEY=sk_your_key_here
npx @deepseek-ai/dsh web --patch ./apimodels.ymlcURL
# sanity-check the gateway before wiring it into DSH
curl https://api.apimodels.app/v1/chat/completions \
-H "Authorization: Bearer $APIMODELS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-5",
"messages": [{"role": "user", "content": "Reply with exactly: OK"}],
"max_tokens": 16
}'No. DSH already ships the pi-ai provider, a generic OpenAI-compatible adapter that takes a baseURL, an API-key environment variable, and a model list. Pointing it at APIMODELS is a config change, not code. Most users do not even touch the terminal: copy the config, launch DSH, paste your key in Settings → Models.
Any chat model APIMODELS serves — Claude (Opus / Sonnet / Haiku), GPT, Gemini, Grok, Kimi, GLM, MiniMax and DeepSeek — since they all sit behind the same OpenAI-compatible endpoint. Add one entry per model to the `models` list in the config; the id is the same string you would send as `"model"` in a normal API call. The full list and current prices are on our pricing page.
No — it adds a route beside it. The built-in `deepseek-official` route keeps working with your own DeepSeek key; the block above only changes which route is the default. You can leave the default alone and switch models from the UI, keeping both sources available. Many people route DeepSeek through us as well, so that agent loops draw down one balance instead of two.
Two reasons specific to agents. First, an agent loop calls the model many times per task, so a provider outage in the middle of a run costs you the whole run — a gateway with fallback channels absorbs that. Second, agent work tends to mix models (a cheap one for routine steps, a strong one for hard ones), and doing that across vendors normally means several accounts, several keys and several prepaid balances. Here it is one key and one balance, billed per token, with failed calls not charged.
It is verified against dsh 0.1.0-rc.6, and DSH is a developer preview whose maintainers state that breaking changes are coming. The field names here come from the project's own config catalog, so they will move if that catalog moves. If you hit a version where this block no longer loads, tell us — we re-test and update this page rather than leaving a stale snippet up.