Skip to content

Anthropic Messages

Alongside the OpenAI format, LLMTR serves the Anthropic Messages format. The same API key, quota and pricing apply; only the request and response shapes differ.

This endpoint lets the Anthropic SDKs and any agent tool that speaks the Anthropic format connect to LLMTR directly. Every chat model in the catalog can be called through it.

POST /v1/messages
x-api-key: llmtr-your_key
anthropic-version: 2023-06-01
Content-Type: application/json
{
"model": "qwen/qwen3.8-max",
"max_tokens": 1024,
"system": "Answer briefly and technically.",
"messages": [
{ "role": "user", "content": "What is cursor-based pagination?" }
]
}

Either x-api-key or Authorization: Bearer can be used for authentication; both accept the same key.

max_tokens is required. The Anthropic format has no default for it, and a request without it returns 400.

{
"id": "msg_...",
"type": "message",
"role": "assistant",
"model": "qwen/qwen3.8-max",
"content": [
{ "type": "text", "text": "Cursor-based pagination..." }
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": { "input_tokens": 24, "output_tokens": 180 }
}

stop_reason values: end_turn, max_tokens, tool_use.

With stream: true the response arrives as server-sent events. The event order matches Anthropic:

message_start
content_block_start
content_block_delta (text_delta or input_json_delta)
content_block_stop
message_delta (stop_reason and usage)
message_stop

Token counts arrive in the usage field of the message_delta event.

Terminal window
curl -N https://llmtr.com/v1/messages \
-H "x-api-key: llmtr-your_key" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "qwen/qwen3.8-max",
"max_tokens": 512,
"stream": true,
"messages": [{ "role": "user", "content": "Hello" }]
}'

Anthropic-format tool definitions are supported:

{
"model": "qwen/qwen3.8-max",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "Returns the weather for a city",
"input_schema": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
],
"messages": [{ "role": "user", "content": "What is the weather in Ankara?" }]
}

When the model calls a tool, the response carries stop_reason: "tool_use" and a tool_use block. Send the result back on the next turn as a tool_result block:

{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "call_1", "content": "22 degrees" }
]
}

tool_choice values: auto, any, tool (named), none.

On models that accept images, use an image block:

{
"role": "user",
"content": [
{ "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "iVBOR..." } },
{ "type": "text", "text": "What is in this image?" }
]
}

source.type can be base64 or url.

import anthropic
client = anthropic.Anthropic(
base_url="https://llmtr.com",
api_key="llmtr-your_key",
)
message = client.messages.create(
model="qwen/qwen3.8-max",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
print(message.content[0].text)

Claude Code can be pointed at a gateway with ANTHROPIC_BASE_URL:

Terminal window
export ANTHROPIC_BASE_URL=https://llmtr.com
export ANTHROPIC_AUTH_TOKEN=llmtr-your_key
export ANTHROPIC_MODEL=anthropic/claude-sonnet-5

PowerShell:

Terminal window
$env:ANTHROPIC_BASE_URL = "https://llmtr.com"
$env:ANTHROPIC_AUTH_TOKEN = "llmtr-your_key"
$env:ANTHROPIC_MODEL = "anthropic/claude-sonnet-5"

To verify the connection:

Terminal window
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"}]}'

Models are listed at the /v1/models endpoint. To see LLMTR models in the Claude Code model picker, set CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1; the picker only lists model ids containing claude or anthropic. Any other model can be selected directly with ANTHROPIC_MODEL.

When Claude Code sees a model id that is not in its own list, it assumes a 200K context window and prints a warning. Requests still work. To declare the model's real window:

Terminal window
export CLAUDE_CODE_MAX_CONTEXT_TOKENS=1000000

The following fields currently have no effect on this endpoint. The request is not rejected; the field is ignored:

  • thinking — no thinking block is returned in the response.
  • cache_control — prompt cache markers are not applied and do not affect pricing.
  • context_management

Responses contain only text and tool_use blocks.

Errors use the Anthropic envelope:

{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "max_tokens is required"
}
}

error.type is derived from the HTTP status: 400 invalid_request_error, 401 authentication_error, 403 permission_error, 404 not_found_error, 413 request_too_large, 429 rate_limit_error, 5xx api_error.

For the error format used by the other endpoints, see Errors.