Skip to main content

Claude Code with OpenRouter and DeepSeek: Setup, Routes, and First-Error Fixes

A
12 min readClaude Code

A route-first Claude Code setup guide for OpenRouter and DeepSeek: env vars, model names, /status, provider proof, first-error fixes, and free/unlimited stop rules.

Claude Code with OpenRouter and DeepSeek: Setup, Routes, and First-Error Fixes

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.

RouteUse it whenMust match before you test
OpenRouter routeYou want OpenRouter to choose or expose the provider path.OpenRouter-owned base URL, OpenRouter token, OpenRouter model name, and OpenRouter provider activity.
DeepSeek direct routeYou 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 routeYou 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:

OwnerWhat it controlsWhat it does not prove
Anthropic Claude Code docsClient behavior, supported settings, env-var names, /status, gateway boundaryThat every third-party model or proxy is supported by Anthropic
OpenRouter docsThe OpenRouter Claude Code route, token, base URL, provider activity, OpenRouter model namingThat DeepSeek direct API behavior is identical to OpenRouter routing
DeepSeek docsDeepSeek's Anthropic-compatible endpoint, DeepSeek model IDs, mapping and ignored-field caveatsThat OpenRouter provider routing or a proxy route is active
Router/proxy projectIts own adapter, logs, cost, data path, and compatibility claimsThat 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

Environment variable ownership map for Claude Code, OpenRouter, DeepSeek, and router/proxy paths

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.

bash
test -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:

bash
unset 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:

bash
export 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:

  1. Start a fresh Claude Code session from the shell where the variables are set.
  2. Run /status.
  3. Send a tiny canary prompt such as "Reply with the active route I should verify."
  4. Check OpenRouter activity for a matching request, model, and provider route.
  5. 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:

bash
export 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

Verification loop for checking Claude Code backend route 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:

StepWhat to checkPass condition
1. Minimal promptA tiny prompt with no repository editsThe session responds without tool or auth errors
2. /statusActive account, route, and model contextIt matches the route you selected
3. Environment presenceBase URL, token owner, model variableOnly the intended route variables are set
4. Provider activityOpenRouter or DeepSeek dashboard/log/activityA matching request appears under the right provider owner
5. Canary repo actionRead-only repo question or harmless commandThe answer/tool behavior matches expectations
6. RollbackClear env vars and restartThe 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

First-error triage board for Claude Code with OpenRouter and DeepSeek

When the first run fails, classify the error before adding settings. Most broken OpenRouter/DeepSeek Claude Code attempts are ownership mismatches.

SymptomLikely causeFirst fix
401 or 403Token does not belong to the base URL owner, key is expired, or the wrong credential variable is winningClear route variables, set one token owner, restart, and test again
404, model not found, or model mismatchModel ID belongs to the other route or a stale provider catalogUse the current model ID from the route owner, then verify provider activity
Provider dashboard is quietRequest did not reach the provider you expectedCheck ANTHROPIC_BASE_URL, shell source, and whether another auth route is winning
Claude Code hangs or tools behave oddlyProxy/gateway compatibility is partial, headers are not preserved, or the model does not support the expected tool flowFall back to a documented route and test the proxy separately
Cost or usage appears in the wrong placeThe route owner is not the billing owner you assumedUse /status plus provider/Console usage before running more tasks
A "free" or "unlimited" route failsThe claim was not supported by current provider proofTreat it as unverified marketing until the provider route, model, and limits are documented

The fastest recovery pattern is:

bash
unset 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 ruleWhy it matters
Do not send sensitive code through an unverified proxyYou may not know who logs prompts, files, or tool output
Do not trust a cost claim without current provider proofOpenRouter and DeepSeek pricing/availability can change
Do not call non-Claude routing Anthropic-supportedAnthropic owns the Claude Code client boundary, not every gateway result
Do not commit tokens or private base URLsShared settings are the wrong place for route secrets
Do not run real edits before provider activity proofYou 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.

#Claude Code#OpenRouter#DeepSeek#Developer Tools#API Configuration
Share: