# Claude Code

> Run Claude Code against Deference with a base URL and your key.

Claude Code speaks the Anthropic Messages API. Point it at `https://deference.si` (no `/v1`) and give it your key as the auth token.

## Set up

1. Create a key in [API keys](https://deference.si/keys) and export it as `DEFERENCE_API_KEY`.
2. Set the base URL, the token and model discovery in your shell profile.

**macOS and Linux**

```bash
export ANTHROPIC_BASE_URL="https://deference.si"
export ANTHROPIC_AUTH_TOKEN="$DEFERENCE_API_KEY"
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY="1"
```

**Windows**

```powershell
$env:ANTHROPIC_BASE_URL = "https://deference.si"
$env:ANTHROPIC_AUTH_TOKEN = $env:DEFERENCE_API_KEY
$env:CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY = "1"
```

3. Start `claude`. If you were signed in to Claude before, run `/logout` once so the saved login does not compete with the token.

To keep the setup out of your shell profile, put it in the `env` block of your user file, `~/.claude/settings.json` (on Windows, `%USERPROFILE%\.claude\settings.json`). The block does not expand variables, so the key goes in as text.

```json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://deference.si",
    "ANTHROPIC_AUTH_TOKEN": "sk-df-...",
    "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1"
  }
}
```

> **Keep the key out of your projects**
>
> Use your user file only, never a project's committed `.claude/settings.json`. Claude Code does not read these variables from a project `.env` file either.

## Verify

1. Check the route and the key with one request. A reply that starts with `{"id":"msg_` means it works.

```bash
curl https://deference.si/v1/messages \
  -H "Authorization: Bearer $DEFERENCE_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5.5",
    "max_tokens": 1,
    "messages": [{ "role": "user", "content": "." }]
  }'
```

2. Start `claude`, send a short prompt, then run `/status`. It lists the Anthropic base URL as `https://deference.si` and names the auth token. A login method that names claude.ai means Claude Code did not pick up the token.
3. Run `claude --debug` to see the model discovery lines in the debug log.
4. Open [Activity](https://deference.si/activity). The request is the top row, and its client reads Claude Code.

## Pick a model

Claude Code asks for a model class (Opus, Sonnet or Haiku) and resolves it to Anthropic's own model id. Pin each class to a Deference id so the request names a model in the catalog.

| Variable                         | Sets                                                              |
| -------------------------------- | ----------------------------------------------------------------- |
| `ANTHROPIC_MODEL`                | The model for the session                                         |
| `ANTHROPIC_DEFAULT_SONNET_MODEL` | The id used for Sonnet, for example `anthropic/claude-sonnet-5.5` |
| `ANTHROPIC_DEFAULT_HAIKU_MODEL`  | The id used for Haiku, for example `anthropic/claude-haiku-4.5`   |
| `ANTHROPIC_DEFAULT_OPUS_MODEL`   | The id used for Opus                                              |
| `CLAUDE_CODE_SUBAGENT_MODEL`     | The id used by subagents                                          |

* With discovery on, `/model` lists the catalog ids that contain `claude` or `anthropic`. Select any other model with `/model <id>` or `claude --model <id>`, using its full id.
* A model Claude Code does not recognize is assumed to have a 200K context window. Append `[1m]` to the id, as in `anthropic/claude-sonnet-5.5[1m]`, to ask for 1M. Deference ignores the suffix when it looks up the model and its price, and forwards the request unchanged.
* Claude Code is built for Claude models. Other models in the catalog answer, but tool use and thinking can behave differently.
* On a team, set `allowedProviders` to `["customEndpoint"]` in Claude Code's managed settings to keep everyone on the gateway.

## Use it in other Claude clients

The Claude Agent SDK and the Claude Code GitHub Action read the same variables. The VS Code extension reads them from its own setting, `claudeCode.environmentVariables`, not from `settings.json`. The Claude desktop app ignores `ANTHROPIC_BASE_URL`.

## Let the agent manage keys

Connect the [MCP server](https://deference.si/docs/coding-tools/mcp) and Claude Code creates, rotates and revokes its own capped keys and checks your credit. You sign in once.

## Troubleshooting

Messages errors carry a `type` and a `message`, not a `code`, so each row names the status, the type and how the message starts.

| You see                                                          | Cause                                                                  | Fix                                                                                                                         |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Claude Code asks you to log in                                   | A saved login wins, or the variables are not set                       | Run `/logout`, and check the variables in the shell that starts `claude`                                                    |
| A warning names two credential sources                           | A saved login and a gateway token are both present                     | Run `/logout`, or unset one                                                                                                 |
| `401 authentication_error`                                       | The token variable is empty or mistyped                                | Set `ANTHROPIC_AUTH_TOKEN` again from your saved key, or create a replacement. Keep the value out of logs and shared output |
| `ANTHROPIC_API_KEY` is set but ignored                           | Claude Code asks for a one-time approval of that key and never re-asks | Use `ANTHROPIC_AUTH_TOKEN` instead                                                                                          |
| `404 not_found_error`, "The model ... does not exist"            | A class variable holds a short name                                    | Use the full id, such as `anthropic/claude-sonnet-5.5`                                                                      |
| `402 billing_error`, "This account has no credit left"           | No available credit                                                    | [Add credit](https://deference.si/wallet?tab=add)                                                                                               |
| `402 billing_error`, "This account has only free credit"         | The account has only free credit, which never pays for Claude models   | [Add credit](https://deference.si/wallet?tab=add), or select an open-weight text model                                                          |
| `402 billing_error`, "This API key has reached its credit limit" | The key reached the credit limit set on it                             | Raise the key's limit in API keys, or use another key                                                                       |
| The picker lacks a non-Claude model                              | Discovery lists only ids with `claude` or `anthropic`                  | Select it with `/model` and its full id                                                                                     |
| The picker is empty                                              | Discovery is off, or `/v1/models` took over 3 seconds or redirected    | Set `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`                                                                          |
| `400` naming `anthropic-beta` or an extra input                  | The model rejects a beta feature Claude Code sends                     | Set `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1`                                                                              |
| Variables seem ignored                                           | They were set in a project `.env`                                      | Export them in your shell or in `~/.claude/settings.json`                                                                   |
