Skip to main content
Claude Code is Anthropic’s terminal coding agent. It speaks the Anthropic Messages API and nothing else, and this API serves that wire at POST /v1/messages, so Claude Code is pointed here with two environment variables and a model id.

The settings

The base URL is an origin, with no /v1. Claude Code appends /v1/messages itself, along with a query string. Every other harness on this site wants the /v1 included, so this one is the exception rather than the rule, and pasting the value from another page would be wrong. Either credential variable works. ANTHROPIC_AUTH_TOKEN sends the key as Authorization: Bearer, and ANTHROPIC_API_KEY sends it as x-api-key. The Messages endpoint reads both, so pick the one your setup already uses. Set one, not both with different values: a request carrying two different keys is refused with a 401 rather than served on either. ANTHROPIC_AUTH_TOKEN is the one Anthropic recommends for a third-party gateway. Every model setting takes a pinned id. Anthropic states that Claude Code’s model id check runs only against Anthropic’s own API, and that behind a custom base URL the gateway defines the names, so a slashed, provider-prefixed id is passed through. That is the shape this API needs: anthropic/ followed by the model, and a bare id is refused with model_id_not_pinned. There are several ids to pin rather than one, a session model and separate family settings of which the small fast one drives background work; set each one you use to an id from GET /v1/models that lists the messages family.

What happens on the wire

The request Claude Code sends is forwarded as a Messages request, and the reply is Anthropic’s own, streamed as Anthropic’s own events. Claude Code reads the stream as it arrives and gives up on one that goes quiet, which a streamed reply through this API satisfies. Token counting: Claude Code will use a token-counting endpoint when one exists and count through the inference endpoint when one does not. This API does not serve /v1/messages/count_tokens, which answers the usual 404 endpoint_not_supported, so Claude Code falls back to counting through inference. That costs requests, not correctness. Refusals that come from this platform, such as an empty balance or a guardrail, arrive in the OpenAI error envelope rather than Anthropic’s error object. That is the one departure from Anthropic’s own API and Anthropic Messages API explains it. Claude Code surfaces the status and the message either way.

What we did not verify

  • That a Claude Code session against this API succeeds or fails in any particular way. Nothing was run; the settings above are the ones the endpoint’s behaviour implies.
  • Whether Claude Code’s adaptive thinking field is accepted. Claude Code sends it without a matching beta header for model names it does not recognise, which includes any id a gateway defines, and an endpoint that rejects it answers 400 naming the field. Beta headers you send are not forwarded by this API. Claude Code has a setting that turns the field off. We have not tested the interaction.
  • Which of the model settings a working configuration needs to pin. Anthropic’s documentation does not state a number and we are not going to invent one.