Integration guides ยท 2026-08-29
Connecting Claude Code to LLMTR through the Anthropic Messages endpoint
The environment variables Claude Code needs to reach LLMTR, the identifier filter in its model picker, the 200K context window assumption and the request fields that have no effect on the Anthropic Messages endpoint.
Which wire format Claude Code speaks
Claude Code is a terminal coding agent and it emits model requests in the Anthropic Messages format. LLMTR serves that format on its own endpoint: the /v1/messages path is appended to the base URL, and every chat model in the catalog can be called through it. Nothing on the tool side has to be replaced, patched or proxied.
Two details of the endpoint shape the setup. The first is authentication: both the x-api-key header and the Authorization Bearer header accept the same key, so the tool keeps its own header layout. The second is that max_tokens is required. The Anthropic format defines no default for it, and a request without it returns 400. Claude Code always sends the field, so day-to-day use never surfaces this, but you will meet it the moment you hit the same endpoint from your own script.
Connecting with three environment variables
The whole setup is environment variables. The base URL carries no endpoint path: the client appends /v1/messages itself, so ANTHROPIC_BASE_URL is set to the llmtr.com root. If you append the /v1 suffix you are used to from OpenAI-compatible clients, the path is written twice and the request lands on an address the gateway does not serve.
The credential travels in ANTHROPIC_AUTH_TOKEN. LLMTR keys start with the llmtr- prefix, which makes a wrong value easy to spot by eye. The session default model comes from ANTHROPIC_MODEL and its value is the canonical catalog identifier, written as provider slash model. Writing the full identifier instead of a short alias keeps you on the intended route even when model discovery is switched off.
| Variable | Example value | Effect |
|---|---|---|
| ANTHROPIC_BASE_URL | https://llmtr.com | Requests go to this root with /v1/messages appended |
| ANTHROPIC_AUTH_TOKEN | llmtr-your_key | Key is carried in the Authorization header |
| ANTHROPIC_MODEL | anthropic/claude-sonnet-5 | Default model identifier for the session |
| CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY | 1 | Adds the gateway catalog to the model picker |
| CLAUDE_CODE_MAX_CONTEXT_TOKENS | 1000000 | Replaces the assumed context window with the real one |
Baseline setup for a bash or zsh session
export ANTHROPIC_BASE_URL=https://llmtr.com
export ANTHROPIC_AUTH_TOKEN=llmtr-your_key
export ANTHROPIC_MODEL=anthropic/claude-sonnet-5
Which identifiers reach the model picker
The catalog is readable from /v1/models without a key, so you can inspect the list before you sign in anywhere. To make LLMTR entries appear in the Claude Code model picker itself, the discovery flag has to be switched on.
The picker applies a filter: it lists only identifiers that contain claude or anthropic. Turning the flag on therefore does not move the whole catalog into the picker. For a model that the filter excludes, you pass the identifier directly through ANTHROPIC_MODEL. Absence from the picker is a listing rule, not a rejection: the request still runs.
- anthropic/claude-sonnet-5 shows up in the picker as the balanced default
- anthropic/claude-opus-4.8 is listed for heavier editing sessions
- anthropic/claude-haiku-4.5 suits short and frequent calls
- Identifiers such as qwen/qwen3.8-max never pass the filter and are set through ANTHROPIC_MODEL only
Enabling discovery and searching the catalog for identifiers
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
curl -s https://llmtr.com/v1/models \
| grep -o '"id":"anthropic/[^"]*"'
The 200K assumption and the context window warning
When Claude Code meets a model identifier that is not in its own list, it assumes a 200K context window and prints a warning line. The request is still sent and the response still comes back; the warning is not an error. Its real cost is a wrong context budget: on a wide-window model the tool may compact far too early, and on a narrow one it may notice the ceiling too late.
The correct move is to declare the real window with CLAUDE_CODE_MAX_CONTEXT_TOKENS. Read the value from the context_length field in the catalog, which reports input and output combined. Update the variable whenever you switch models, otherwise the previous window is applied to the new route.
PowerShell session setup including the window value
$env:ANTHROPIC_BASE_URL = "https://llmtr.com"
$env:ANTHROPIC_AUTH_TOKEN = "llmtr-your_key"
$env:ANTHROPIC_MODEL = "anthropic/claude-sonnet-5"
$env:CLAUDE_CODE_MAX_CONTEXT_TOKENS = "1000000"
Fields with no counterpart on this endpoint
This is the part of the integration that has to be stated plainly. Three request fields currently have no effect on the Anthropic Messages endpoint. The request is not rejected and the field is silently ignored, so you notice the difference in the response body rather than in an error message.
The practical consequence: if you planned to make long system instructions cheaper through prompt caching, do not budget for that saving on this endpoint. Any tool surface that renders thinking blocks stays empty. Tool calling itself behaves normally, returning a tool_use block that you answer with tool_result on the following turn.
- thinking can be sent, but no thinking block comes back in the response
- cache_control markers are not applied and do not affect pricing
- context_management is disregarded
- Response bodies contain only text and tool_use blocks
Verification and reading the error envelope
Test the setup with a single request before you start the agent. A 200 response proves the base URL, the key and the model identifier are all correct at once. Keep max_tokens small in that probe; you are confirming a route, not collecting output.
Errors arrive in the Anthropic envelope: the body type is error and error.type is derived from the HTTP status. That mapping turns the one-line failure in your terminal into a specific part of the setup to inspect, which is exactly what the table below gives you.
| HTTP | error.type | What to inspect in the setup |
|---|---|---|
| 400 | invalid_request_error | Missing max_tokens or an invalid body field |
| 401 | authentication_error | The ANTHROPIC_AUTH_TOKEN value and key validity |
| 403 | permission_error | Whether the key may reach this model |
| 404 | not_found_error | An extra path on the base URL or a mistyped identifier |
| 413 | request_too_large | The size of the context being sent |
| 429 | rate_limit_error | Request frequency |
| 5xx | api_error | A transient condition on the upstream provider |
Probing the connection with one request
curl https://llmtr.com/v1/messages \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"anthropic/claude-sonnet-5","max_tokens":16,"messages":[{"role":"user","content":"test"}]}'
Frequently asked questions
Do I need a separate build of Claude Code for LLMTR?
No. The integration is entirely environment variables. Once ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN and ANTHROPIC_MODEL are set, the tool sends its requests to the Anthropic Messages endpoint on LLMTR. There is no repository to switch, no patch to apply and no plugin to install.
Why does the model picker show only part of the catalog?
The picker lists only identifiers containing claude or anthropic. Enabling the discovery flag does not remove that filter. Any model missing from the list can still be used by writing its full canonical identifier into ANTHROPIC_MODEL.
Can I ignore the context window warning?
The request keeps working, but the tool assumes a 200K window and therefore budgets context incorrectly. Declaring the model's real window with CLAUDE_CODE_MAX_CONTEXT_TOKENS removes both the warning and the wrong arithmetic.
Do prompt cache markers reduce cost on this endpoint?
No. cache_control is ignored here and has no pricing effect. Because the request does not fail, the only symptom is that the saving you expected never appears. Billing is token based and follows the tariff of the model you selected.