# Claude Code

Claude Code speaks the Anthropic API format, which kenari serves at `/v1/messages`. To connect, set three environment variables. Claude Code needs a chat model that supports tool calling. Check that `tool_call` is `true` for the model in the live catalog:

```bash
curl -s https://kenari.id/v1/models \
  | jq -r '.data[] | select(.tool_call == true) | .id'
```

A request with tools to a model without tool calling returns `400`, and so do image, speech, transcription and video ids.

## Set the variables

You need an API key in `KENARI_API_KEY`. See [Quickstart](/en/docs/quickstart) to create one and export it.

```bash
export ANTHROPIC_BASE_URL=https://kenari.id
export ANTHROPIC_AUTH_TOKEN=$KENARI_API_KEY
export ANTHROPIC_MODEL=step-3-7-flash:free
```

| Variable | Value |
| --- | --- |
| `ANTHROPIC_BASE_URL` | `https://kenari.id`, with no `/v1`. Claude Code adds `/v1/messages` itself. |
| `ANTHROPIC_AUTH_TOKEN` | Your kenari API key, starting with `kn-`. See [Authentication and API keys](/en/docs/authentication). |
| `ANTHROPIC_MODEL` | A model id from [Models and pricing](/en/docs/models). `step-3-7-flash:free` runs with zero balance. |

`ANTHROPIC_API_KEY` also works in place of `ANTHROPIC_AUTH_TOKEN`. kenari accepts the key from either the `Authorization` header or the `x-api-key` header.

### Keep the variables between sessions

Add the `export` lines to your shell profile, such as `~/.zshrc` or `~/.bashrc`, together with `export KENARI_API_KEY=kn-...` so that the source variable exists in every new terminal. Then open a new terminal. Or put them in the `env` block of Claude Code's `settings.json`:

```json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://kenari.id",
    "ANTHROPIC_AUTH_TOKEN": "kn-...",
    "ANTHROPIC_MODEL": "step-3-7-flash:free"
  }
}
```

A `settings.json` file stores the key in plain text, so keep it out of version control.

### Keep every request on your model

`ANTHROPIC_MODEL` sets the main conversation only. Claude Code still sends some requests to Claude models: background tasks run on the `haiku` model, and a subagent runs on another model when Claude or the subagent's definition asks for one. kenari serves Claude models too, so those requests succeed and are billed at that model's price. To send every request to one model, point every alias at the same id and force that id onto subagents:

```bash
export ANTHROPIC_DEFAULT_FABLE_MODEL=step-3-7-flash:free
export ANTHROPIC_DEFAULT_OPUS_MODEL=step-3-7-flash:free
export ANTHROPIC_DEFAULT_SONNET_MODEL=step-3-7-flash:free
export ANTHROPIC_DEFAULT_HAIKU_MODEL=step-3-7-flash:free
export CLAUDE_CODE_SUBAGENT_MODEL=step-3-7-flash:free
export CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1
```

`CLAUDE_CODE_SUBAGENT_MODEL_FORCE` needs Claude Code v2.1.257 or later. Without it, a subagent that asks for a full Claude model id still runs on that model. In `settings.json`, add the same variables to the `env` block and write the `1` as a string, `"1"`.

## Verify the connection

If you set environment variables, check that the key is set without printing it. Use `ANTHROPIC_API_KEY` in place of `ANTHROPIC_AUTH_TOKEN` if that is the one you chose. If you use `settings.json`, skip this check.

```bash
test -n "$ANTHROPIC_AUTH_TOKEN" && echo set
```

Then start Claude Code and send any message:

```bash
claude
```

A reply means the connection works.

## Token counting

Claude Code asks `POST /v1/messages/count_tokens` before each turn to size its context window. kenari answers with an estimate and does not bill the call. It still needs your key.

## Choose between this and the kenari CLI

The variables above send every Claude Code session to one model. The [kenari CLI](/en/docs/cli) routes only the sessions you start with `kenari claude`, and lets you put a different model behind each role, such as `opus` or `subagents`. Pick one. If you leave the variables set, `kenari claude` overrides them for its own session.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| `401` with `invalid key` or `missing authorization` | The variable did not load, or the key does not start with `kn-`. | Use the key you saved, then open a new terminal. A lost key cannot be shown again, so create a new one. See [Authentication and API keys](/en/docs/authentication). |
| `400` with `model_not_found` | The model id is misspelled or not in the catalog. | Copy the id from [Models and pricing](/en/docs/models). |
| `402` with `insufficient_balance` | The model is paid and your balance is empty. | Use a `:free` model, or top up. See [How billing works](/en/docs/billing). |
| `405` | The base URL ends in `/v1`, so the request goes to `/v1/v1/messages`. | Set `ANTHROPIC_BASE_URL` to `https://kenari.id`. |
| `model_not_found` for a model you did not choose | Claude Code also sends background requests to a small default model that kenari may not carry. | Set `ANTHROPIC_DEFAULT_HAIKU_MODEL` to a catalog model id. |
| Usage shows a Claude model you did not choose | Claude Code sent subagent or background requests to its default Claude models. | Set the variables in [Keep every request on your model](#keep-every-request-on-your-model). |

## See also

- [kenari CLI](/en/docs/cli)
- [Messages](/en/docs/messages)
- [Integrations overview](/en/docs/integrations)
- [Errors](/en/docs/errors)
