POST/v1/messages

Anthropic Messages

Anthropic Messages dialect for Claude SDKs — translated and routed to the serving provider.

The Anthropic Messages API, as used by Claude SDKs. The gateway translates the request to the serving backend and returns the native Anthropic body plus provider_metadata. model echoes your alias.

This is the gateway's second wire dialect — same contract as the OpenAI endpoints, different shapes. See OpenAI & Anthropic Compatibility for the side-by-side.

Auth

x-api-key: <key> (Anthropic SDK default) or Authorization: Bearer — both accepted (Auth headers). The anthropic-version header is accepted and forwarded to the provider.

curl https://api.<domain>/v1/messages \
  -H "x-api-key: $TOKENFACTORY_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.<domain>",  # the SDK appends /v1/messages
    api_key=os.environ["TOKENFACTORY_API_KEY"],
)

message = client.messages.create(
    model="claude-sonnet",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(message.content[0].text)

Request body

Native Anthropic shape. Only model is gateway-validated (curated alias rule); everything else passes to the dialect adapter:

FieldTypeRequired
modelstringyes
messagesarrayyes
max_tokensintegeryes (Anthropic requires it)
systemstring / blocksno
streambooleanno
temperaturenumberno
stop_sequencesstring[]no
tools, metadataobjectno

Response

{
  "id": "msg_1",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet",
  "content": [{ "type": "text", "text": "Hi" }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 10,
    "output_tokens": 2,
    "cache_read_input_tokens": 6,
    "cache_creation_input_tokens": 4
  },
  "provider_metadata": {
    "provider": "anthropic",
    "actual_model": "claude-sonnet-4-5-20250929",
    "native_finish_reason": "end_turn",
    "cache": { "read_tokens": 6, "write_tokens": 4 }
  }
}

Prompt-cache usage is surfaced both in the native usage keys and in provider_metadata.cache — priced at the cached rate when the model defines one.

Errors

This path uses the Anthropic error envelope — not the OpenAI one. request_id is a top-level sibling of error, and there is no code/param:

{"type": "error", "error": {"type": "not_found_error", "message": "…"}, "request_id": "req_01J…"}

Status codes and their meanings are identical to the OpenAI paths (Errors).

Streaming

With stream: true, the native Anthropic event sequence is preserved (message_start … content_block_delta … message_stop), with the X-TF-* side-channel headers. See Streaming.