# Claude Code

# Claude Code

[Claude Code](https://docs.anthropic.com/en/docs/claude-code) speaks the
**Anthropic Messages API**. Hyphen serves that API at `/v1/messages`, so Claude
Code works against the gateway — **once you map its model tiers to Hyphen
models**. That mapping is required; skip it and every request fails. The
copy-paste block below does the whole thing.

## 1. Get a key

[app.hyphen-solution.com](https://app.hyphen-solution.com) → sign in →
**Dashboard → API Keys → Create**. Copy the `sk-hy-...` key.

## 2. Configure — one copy-paste block

Create or edit **`~/.claude/settings.json`** and paste this. Replace the token
with your key; leave the model mappings as-is.

```json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.hyphen-solution.com",
    "ANTHROPIC_AUTH_TOKEN": "sk-hy-YOUR_KEY",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "m3",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "m3",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "m2.5"
  }
}
```

That's the entire setup. Restart Claude Code so it re-reads the file, then jump
to [Verify](#3-verify).

### Prefer shell exports?

The same config as environment variables — add to `~/.zshrc` or `~/.bashrc`:

```bash
export ANTHROPIC_BASE_URL="https://api.hyphen-solution.com"
export ANTHROPIC_AUTH_TOKEN="sk-hy-YOUR_KEY"
export ANTHROPIC_DEFAULT_SONNET_MODEL="m3"
export ANTHROPIC_DEFAULT_OPUS_MODEL="m3"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="m2.5"
```

Then `source ~/.zshrc` (or open a new terminal) and run `claude`.

## Why the model mappings are required

This is the detail that trips people up, so it's worth 30 seconds.

Claude Code doesn't send a model name like `m3`. It sends **Anthropic model
names** — `claude-sonnet-4-...`, `claude-opus-4-...`, `claude-haiku-...` —
because it's built to talk to Anthropic. The Hyphen gateway does **not** accept
those names; sending one returns:

```json
{ "error": { "message": "Invalid model name", "type": "invalid_request_error" } }
```

So pointing only `ANTHROPIC_BASE_URL` at Hyphen is **not enough** — every
request 400s on the model name. The `ANTHROPIC_DEFAULT_*_MODEL` variables fix
this: they tell Claude Code to substitute a real Hyphen model wherever it would
otherwise send a `claude-*` name.

```
Claude Code wants "claude-sonnet-4"  ──▶  sends "m3" instead   (SONNET → m3)
Claude Code wants "claude-opus-4"    ──▶  sends "m3" instead   (OPUS   → m3)
Claude Code wants "claude-haiku"     ──▶  sends "m2.5" instead (HAIKU  → m2.5)
```

We map both Sonnet and Opus to **`m3`** (Hyphen's strongest, a reasoning model)
so heavy agent work always lands on the best model, and Haiku — Claude Code's
lightweight background tier — to **`m2.5`** to keep those calls cheap and fast.

### Want a lighter, cheaper default?

Map the Sonnet tier to `m2.7` (balanced) instead — day-to-day work gets cheaper,
and you can still call the strongest model on demand:

```json
"ANTHROPIC_DEFAULT_SONNET_MODEL": "m2.7",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "m3",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "m2.5"
```

## 3. Verify

```bash
claude -p "Reply with the single word: connected"
```

If it prints **`connected`**, Claude Code is wired to the gateway and the model
mapping is working. (A `400 Invalid model name` here means the
`ANTHROPIC_DEFAULT_*_MODEL` variables aren't being read — see below.)

## Troubleshooting

- **`400 Invalid model name`** — the model mappings aren't taking effect. Confirm
  `~/.claude/settings.json` is valid JSON (no trailing commas) and that you
  restarted Claude Code. If you used shell exports, make sure the current
  terminal actually has them (`echo $ANTHROPIC_DEFAULT_SONNET_MODEL`).
- **`401 Invalid API key`** — the `sk-hy-...` token is wrong or unset. Re-copy it
  from the console and check `ANTHROPIC_AUTH_TOKEN`.
- **`429`** — your monthly budget is spent. Claude Code surfaces the reset date;
  see [Rate limits & caps](/rate-limits).
- **Env var names changed?** Flag and env names can shift between Claude Code
  releases. If a variable seems ignored, check `claude --help` for the current
  names in your installed version.
- **Settings not applied at all** — Claude Code reads `~/.claude/settings.json`
  on startup. Fully quit and relaunch; delete and recreate the file if a stale
  copy is being picked up.
