Claude Code with OpenRouter and DeepSeek should start with a route choice, not a command. Pick one active route first: use OpenRouter when you want OpenRouter to own gateway and provider routing, use DeepSeek direct when you specifically want DeepSeek's Anthropic-compatible API and model IDs, and treat router/proxy stacks as experiments until you can prove tools, data handling, and cost.
| Route | Use it when | Must match before you test |
|---|---|---|
| OpenRouter route | You want OpenRouter to choose or expose the provider path. | OpenRouter-owned base URL, OpenRouter token, OpenRouter model name, and OpenRouter provider activity. |
| DeepSeek direct route | You want Claude Code to talk to DeepSeek's Anthropic-compatible route directly. | DeepSeek-owned base URL, DeepSeek token, DeepSeek model ID, and DeepSeek-side activity. |
| Router/proxy route | You are testing a third-party adapter or local proxy. | One owner for base URL, token, model mapping, logs, data handling, and cost proof. |
Stop before the first real repo task if /status, provider logs, and a tiny canary prompt do not point to the same owner. One test should have one base URL, one credential owner, and one model owner; if those disagree, roll back before adding more settings.
Choose The Route Before You Paste Variables
The common failure is not that Claude Code needs one secret command. The failure is route mixing: an OpenRouter base URL with a DeepSeek token, a DeepSeek model name while an old Anthropic login still owns the session, or a proxy that accepts a request but does not preserve the API shape Claude Code expects.
As of the July 3, 2026 source check, the official ownership boundary is:
| Owner | What it controls | What it does not prove |
|---|---|---|
| Anthropic Claude Code docs | Client behavior, supported settings, env-var names, /status, gateway boundary | That every third-party model or proxy is supported by Anthropic |
| OpenRouter docs | The OpenRouter Claude Code route, token, base URL, provider activity, OpenRouter model naming | That DeepSeek direct API behavior is identical to OpenRouter routing |
| DeepSeek docs | DeepSeek's Anthropic-compatible endpoint, DeepSeek model IDs, mapping and ignored-field caveats | That OpenRouter provider routing or a proxy route is active |
| Router/proxy project | Its own adapter, logs, cost, data path, and compatibility claims | That Claude Code support, provider cost, or tool behavior is first-party guaranteed |
OpenRouter's current Claude Code cookbook is useful when you want OpenRouter to own gateway routing. DeepSeek's current coding-agent guide and Anthropic-compatible API docs are useful when you want DeepSeek direct. Anthropic's Claude Code docs for gateways, environment variables, model configuration, and settings remain the boundary for what the Claude Code client itself supports.
That split matters because teams often collapse three different jobs into one setup attempt. Keep them separate so you can select the route, configure only that route, and verify it before a real repository run.
Clean Up Conflicting Claude Code Credentials

Before you configure OpenRouter or DeepSeek, remove stale route owners from the current shell. You are not trying to print secrets; you are checking whether a higher-priority credential is present.
bashtest -n "$ANTHROPIC_AUTH_TOKEN" && echo "ANTHROPIC_AUTH_TOKEN is set" test -n "$ANTHROPIC_API_KEY" && echo "ANTHROPIC_API_KEY is set" test -n "$ANTHROPIC_BASE_URL" && echo "ANTHROPIC_BASE_URL is set" test -n "$ANTHROPIC_MODEL" && echo "ANTHROPIC_MODEL is set"
If the output surprises you, stop and locate the source. It may be a shell profile, .env loader, terminal launcher, devcontainer, CI secret, or .claude/settings.local.json. Fixing that source is safer than stacking another export on top.
Use this cleanup pattern when you want a clean route test in the current shell:
bashunset ANTHROPIC_AUTH_TOKEN unset ANTHROPIC_API_KEY unset ANTHROPIC_BASE_URL unset ANTHROPIC_MODEL
Then open a new shell or start Claude Code from the same shell you inspected. A test is only meaningful when the active environment is the one you intended.
If you need the broader credential precedence ladder, use the Claude Code API configuration guide. Keep this runbook focused on the OpenRouter, DeepSeek direct, and router/proxy split.
OpenRouter Setup For Claude Code
Use the OpenRouter branch when you want OpenRouter to own the gateway route. That means the token comes from OpenRouter, the base URL points to OpenRouter, model naming follows OpenRouter's current docs, and provider activity should be visible in OpenRouter's own surfaces.
For a temporary shell-scoped test:
bashexport ANTHROPIC_BASE_URL="https://openrouter.ai/api" export ANTHROPIC_AUTH_TOKEN="$OPENROUTER_API_KEY" unset ANTHROPIC_API_KEY claude /status
Use a fake placeholder in documentation and scripts; never paste a real key into a shared file or screenshot. The important ownership rule is that ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, and the model selector all belong to the OpenRouter route for this test.
OpenRouter's Claude Code guide also documents route-specific details such as model environment variables, /logout, /status, and Fast Mode caveats. Treat those as OpenRouter-route instructions, not as a general statement that every provider or model behind a gateway will behave like first-party Claude Code.
The first proof should be boring:
- Start a fresh Claude Code session from the shell where the variables are set.
- Run
/status. - Send a tiny canary prompt such as "Reply with the active route I should verify."
- Check OpenRouter activity for a matching request, model, and provider route.
- Only then run a small repository read or lint task.
If /status and OpenRouter activity disagree, do not keep changing model names. Roll back, clear the shell, and rebuild the route from one owner.
DeepSeek Direct Setup For Claude Code
Use the DeepSeek direct branch when you specifically want Claude Code to send Anthropic-compatible requests to DeepSeek's API. In this branch, DeepSeek owns the endpoint, token, model IDs, compatibility caveats, and provider-side activity.
DeepSeek's current docs show an Anthropic-compatible Claude Code path. A shell-scoped test can look like this:
bashexport ANTHROPIC_BASE_URL="https://api.deepseek.com/anthropic" export ANTHROPIC_AUTH_TOKEN="$DEEPSEEK_API_KEY" export ANTHROPIC_MODEL="deepseek-v4-pro[1m]" claude /status
DeepSeek's docs also list deepseek-v4-flash as a current coding-agent model option. Do not treat model IDs as permanent. Model availability, suffixes, web-search behavior, mapping, and pricing are volatile provider facts; recheck DeepSeek's docs before publishing a team runbook or hard-coding a default.
The DeepSeek direct route has a different proof burden from OpenRouter. You should see DeepSeek-side activity, DeepSeek model IDs, and the DeepSeek endpoint in the active route. OpenRouter logs do not prove a DeepSeek direct run; they prove an OpenRouter-owned run that may or may not route to a DeepSeek provider.
This distinction also keeps support language honest. Anthropic can document how Claude Code points at gateways and environment variables, but Anthropic does not become the support owner for a non-Claude model's behavior through a third-party route.
Use Settings Local When You Do Not Want Shell Drift
Shell exports are good for one canary test. They are bad when you come back two days later and forget which terminal tab owned the route. For repeatable local experiments, keep route variables in a local-only scope that does not get committed.
A local settings pattern is:
json{ "env": { "ANTHROPIC_BASE_URL": "https://api.deepseek.com/anthropic", "ANTHROPIC_AUTH_TOKEN": "$DEEPSEEK_API_KEY", "ANTHROPIC_MODEL": "deepseek-v4-flash" } }
Use this as a shape, not as a file to paste blindly. Confirm that .claude/settings.local.json is ignored in your repository before putting anything sensitive there. Put shared team behavior in shared project settings, but keep tokens, private base URLs, and personal provider choices out of committed settings.
For OpenRouter, the same ownership pattern applies:
json{ "env": { "ANTHROPIC_BASE_URL": "https://openrouter.ai/api", "ANTHROPIC_AUTH_TOKEN": "$OPENROUTER_API_KEY", "ANTHROPIC_MODEL": "openrouter-model-id-from-your-current-docs" } }
The point is not that settings files are always better than shell variables. The point is scope. Use one local route per test and keep it auditable. If you need billing-owner guidance across subscription login, API keys, and credits, use the Claude Code API key vs subscription billing guide.
Verify Before Real Work

The verification loop is part of the setup, not a cleanup step after something breaks. A backend switch is safe only when route, credential, model, and provider evidence all agree.
Use this loop:
| Step | What to check | Pass condition |
|---|---|---|
| 1. Minimal prompt | A tiny prompt with no repository edits | The session responds without tool or auth errors |
2. /status | Active account, route, and model context | It matches the route you selected |
| 3. Environment presence | Base URL, token owner, model variable | Only the intended route variables are set |
| 4. Provider activity | OpenRouter or DeepSeek dashboard/log/activity | A matching request appears under the right provider owner |
| 5. Canary repo action | Read-only repo question or harmless command | The answer/tool behavior matches expectations |
| 6. Rollback | Clear env vars and restart | The session returns to the previous known route |
Do not skip provider activity proof when the reason for switching is cost, availability, or model choice. Local status can tell you what Claude Code thinks it is using; provider activity tells you who actually saw the request.
Avoid a canary that modifies files. Good first tasks are "summarize the package scripts", "read this config and explain it", or "run a harmless version command". A canary that edits a real branch before you have route proof converts a setup test into an incident.
Fix The First Failed Run

When the first run fails, classify the error before adding settings. Most broken OpenRouter/DeepSeek Claude Code attempts are ownership mismatches.
| Symptom | Likely cause | First fix |
|---|---|---|
401 or 403 | Token does not belong to the base URL owner, key is expired, or the wrong credential variable is winning | Clear route variables, set one token owner, restart, and test again |
404, model not found, or model mismatch | Model ID belongs to the other route or a stale provider catalog | Use the current model ID from the route owner, then verify provider activity |
| Provider dashboard is quiet | Request did not reach the provider you expected | Check ANTHROPIC_BASE_URL, shell source, and whether another auth route is winning |
| Claude Code hangs or tools behave oddly | Proxy/gateway compatibility is partial, headers are not preserved, or the model does not support the expected tool flow | Fall back to a documented route and test the proxy separately |
| Cost or usage appears in the wrong place | The route owner is not the billing owner you assumed | Use /status plus provider/Console usage before running more tasks |
| A "free" or "unlimited" route fails | The claim was not supported by current provider proof | Treat it as unverified marketing until the provider route, model, and limits are documented |
The fastest recovery pattern is:
bashunset ANTHROPIC_AUTH_TOKEN unset ANTHROPIC_API_KEY unset ANTHROPIC_BASE_URL unset ANTHROPIC_MODEL claude /status
Once the session is back to a known route, add only the variables for one branch. If the OpenRouter branch fails, debug OpenRouter's base URL, token, model, and activity. If the DeepSeek direct branch fails, debug DeepSeek's endpoint, token, model ID, and activity. Do not mix fixes across branches until one branch passes a canary.
Cost, Data, And Support Stop Rules
Cost is the wrong first promise for this route decision. The right promise is proof. Prices, free tiers, provider priority, web-search charges, model availability, and rate limits can change faster than a team runbook. Treat any "free forever", "unlimited", "2-5% cost", or "works with any model" claim as unverified until the current route owner proves it.
Use these stop rules:
| Stop rule | Why it matters |
|---|---|
| Do not send sensitive code through an unverified proxy | You may not know who logs prompts, files, or tool output |
| Do not trust a cost claim without current provider proof | OpenRouter and DeepSeek pricing/availability can change |
| Do not call non-Claude routing Anthropic-supported | Anthropic owns the Claude Code client boundary, not every gateway result |
| Do not commit tokens or private base URLs | Shared settings are the wrong place for route secrets |
| Do not run real edits before provider activity proof | You need a rollback path before an agent changes files |
If your real question is gateway selection rather than setup, read the Claude gateway guide. If your real question is installing the CLI, start with the Claude Code install guide. If your real question is DeepSeek in a different product, the Janitor DeepSeek setup guide is a separate route.
FAQ
Can Claude Code use OpenRouter and DeepSeek?
Yes, but not as one blended route. Claude Code can be pointed at an OpenRouter route or at DeepSeek's Anthropic-compatible direct route when the base URL, credential, model, and verification evidence all belong to that same route.
Should I use DeepSeek through OpenRouter or DeepSeek direct?
Use OpenRouter when you want OpenRouter to own provider routing, dashboards, model catalog, and gateway behavior. Use DeepSeek direct when you want DeepSeek's own Anthropic-compatible API route and DeepSeek model IDs. The better route is the one you can verify for your repo, cost boundary, and support needs.
Where should Claude Code OpenRouter or DeepSeek settings live?
Use shell variables for a temporary canary and .claude/settings.local.json only for local, ignored, machine-specific experiments. Do not put provider tokens, private base URLs, or personal route choices in shared .claude/settings.json.
What does /status prove?
/status is the first client-side route check. It helps confirm what Claude Code thinks is active, but it is not enough by itself. Pair it with environment checks and OpenRouter or DeepSeek provider activity before real work.
Can I use a free or unlimited OpenRouter DeepSeek route?
Only treat that as true when the current provider route proves it. Free-tier, unlimited, provider-priority, and pricing claims are volatile. For a publishable runbook, date the proof and include a rollback path.
Why does the model name keep failing?
The model ID may belong to the wrong route owner. An OpenRouter model name, a DeepSeek direct model ID, and an Anthropic model alias are not interchangeable. Clear the route, set one owner, and verify the model against that owner's current docs.
Is this the same as choosing a local coding model?
No. This setup path is about routing Claude Code through OpenRouter or DeepSeek-compatible APIs. If you are choosing local models for another stack, use a model-comparison or local-inference guide instead of changing Claude Code gateway settings.
