Anthropic Messages API Reference
In addition to the OpenAI-compatible /v1/chat/completions endpoint, RouteLLM exposes an Anthropic-native Messages API at /v1/messages. It accepts requests in the Anthropic Messages API format and returns responses in the same format, so existing Anthropic SDK code and tooling work with a one-line base-URL change.
Overview​
The Messages endpoint is a thin pass-through to Claude: your request body is forwarded to the model unchanged, and the Claude response (including streaming events) is returned verbatim. This preserves every Anthropic-native feature — system prompts, tool use, extended thinking, and prompt caching — while billing and credit tracking are handled transparently on the Abacus.AI side.
Key Features​
- Drop-in Anthropic Compatibility: Point the official Anthropic SDK at RouteLLM by changing only the base URL and API key.
- Streaming Support: Server-sent event (SSE) streaming in the native Anthropic event format.
- Tool Use: Full support for Anthropic tool definitions and
tool_use/tool_resultturns. - Extended Thinking:
thinkingblocks pass through unchanged for reasoning-capable models. - Prompt Caching: Native
cache_controlcaching to cut cost and latency on repeated context. - Vision & PDF: Image and document content blocks are supported for compatible Claude models.
This endpoint serves Claude models only. To use OpenAI, Google, xAI, or other providers, use the OpenAI-compatible /v1/chat/completions endpoint (or the /v1/responses endpoint for the OpenAI Responses API).
Base URLs​
The Messages endpoint lives at /v1/messages under your RouteLLM base URL. The base URL depends on your organization type:
- Self-Serve Organizations:
https://routellm.abacus.ai/v1 - Enterprise Platform:
https://<workspace>.abacus.ai/v1
Replace <workspace> with your specific workspace identifier for enterprise deployments. To find your correct base URL, refer to the RouteLLM API page.
Authentication​
All requests require a RouteLLM API key. The endpoint accepts the key in either of the two standard headers, so the official Anthropic SDK (which sends x-api-key) works without modification:
x-api-key: <your_api_key>
Authorization: Bearer <your_api_key>
You can obtain your API key from the Abacus.AI platform.
Supported Models​
Pass any Claude model identifier in the model field:
| Model | Model |
|---|---|
claude-opus-4-7 | claude-opus-4-7-xhigh |
claude-opus-4-6 | claude-sonnet-4-6 |
claude-opus-4-5 | claude-sonnet-4-5 |
claude-haiku-4-5 |
Retrieve the full, up-to-date list programmatically via the GET /v1/models endpoint.
Request Parameters​
The request body follows the Anthropic Messages API schema. Common parameters:
Required Parameters​
model (string, required)​
A Claude model identifier (see Supported Models).
messages (array, required)​
The conversation so far. Each message is an object with:
role(string):userorassistantcontent(string or array): Text, or an array of content blocks (text,image,document,tool_use,tool_result)
Optional Parameters​
max_tokens (integer)​
Maximum number of tokens to generate. The Anthropic API treats this as required; if omitted, RouteLLM defaults it to 1024.
system (string or array)​
A system prompt. Provide a string, or an array of text blocks (required if you want to attach cache_control — see Prompt Caching).
stream (boolean)​
Set to true to stream the response as SSE events. Defaults to false.
temperature (number)​
Sampling temperature (0.0–1.0).
top_p / top_k (number / integer)​
Nucleus and top-k sampling controls.
stop_sequences (array)​
Custom sequences that stop generation.
tools / tool_choice (array / object)​
Tool definitions and the tool-selection strategy for tool use.
thinking (object)​
Enables extended thinking, e.g. {"type": "enabled", "budget_tokens": 4096}, for reasoning-capable models.
Response Format​
A non-streaming request returns a standard Anthropic Message object:
{
"id": "msg_01Abc123",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-6",
"content": [
{ "type": "text", "text": "Hello! How can I help you today?" }
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 12,
"output_tokens": 18,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}
Counting tokens​
Every response includes a usage object with the exact token counts for that request, so you don't need a separate call to measure consumption:
input_tokens: tokens in the request prompt (messages, system prompt, tools).output_tokens: tokens generated in the response.cache_creation_input_tokens: input tokens written to the prompt cache on this request.cache_read_input_tokens: input tokens served from the prompt cache (billed at the reduced cache-read rate).
For streaming requests the same figures are reported across the message_start (input, including cache tokens) and message_delta (cumulative output) events — see Streaming.
A dedicated pre-flight token-counting endpoint (Anthropic's POST /v1/messages/count_tokens) is not currently exposed by the proxy. To measure token usage, read the usage object returned with each response. If you need an estimate before sending a request, count tokens client-side with Anthropic's token-counting guidance.
Streaming​
When stream is true, the response is a text/event-stream of Anthropic-format events. Each event is emitted as an SSE event: / data: pair:
event: message_start
data: {"type":"message_start","message":{"id":"msg_01Abc123","type":"message","role":"assistant","model":"claude-sonnet-4-6","content":[],"usage":{"input_tokens":12,"output_tokens":0}}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":18}}
event: message_stop
data: {"type":"message_stop"}
Token usage is reported on the message_start (input, including cache tokens) and message_delta (output) events.
Prompt Caching​
The endpoint supports Anthropic prompt caching natively. Caching lets you reuse large, stable portions of a prompt (long system instructions, documents, tool definitions) across requests, reducing both cost and latency.
To cache a block, add cache_control: { "type": "ephemeral" } to the last content block you want included in the cached prefix. Everything up to and including that block is cached.
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You are a support assistant. Here is the full product manual:\n<large reusable context>",
"cache_control": { "type": "ephemeral" }
}
],
"messages": [
{ "role": "user", "content": "How do I reset my password?" }
]
}
Cache usage & billing​
The usage object reports cache activity so you can verify hits:
cache_creation_input_tokens: tokens written to the cache on this request (a cache miss / first write).cache_read_input_tokens: tokens served from the cache (a cache hit).
Cached tokens are billed at Anthropic's standard prompt-caching rates — cache writes at 1.25× and cache reads at 0.1× the base input-token price — so a warm cache is substantially cheaper than resending the same context. On the first request the cached prefix appears under cache_creation_input_tokens; subsequent requests that reuse it (within the cache lifetime) report those tokens under cache_read_input_tokens.
Place cache_control on the largest stable prefix (system prompt, tool definitions, or a long document) and keep the dynamic, per-turn content after it. This maximizes cache reuse.
Tool Use​
Define tools with the Anthropic schema and let the model request calls. Return results as tool_result content blocks in a follow-up user turn.
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "Get the current weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "City name" }
},
"required": ["location"]
}
}
],
"messages": [
{ "role": "user", "content": "What's the weather in Boston?" }
]
}
The model responds with a tool_use content block; send the tool's output back as a tool_result block to continue the turn.
Code Examples​
Basic Request​
- Python SDK
- TypeScript/JavaScript
- cURL
from anthropic import Anthropic
client = Anthropic(
base_url="<your base url>",
api_key="<your_api_key>",
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "What is the meaning of life?"}
],
)
print(message.content[0].text)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
baseURL: '<your base url>',
apiKey: '<your_api_key>',
});
const message = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'What is the meaning of life?' }
],
});
console.log(message.content[0].text);
curl -X POST "<your base url>/messages" \
-H "x-api-key: <your_api_key>" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "What is the meaning of life?"}
]
}'
Streaming Request​
- Python SDK
- cURL
from anthropic import Anthropic
client = Anthropic(
base_url="<your base url>",
api_key="<your_api_key>",
)
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explain quantum computing in simple terms."}
],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
curl -X POST "<your base url>/messages" \
-H "x-api-key: <your_api_key>" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Explain quantum computing."}
],
"stream": true
}'
Prompt Caching​
- Python SDK
- cURL
from anthropic import Anthropic
client = Anthropic(
base_url="<your base url>",
api_key="<your_api_key>",
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": "You are a support assistant. Product manual:\n<large reusable context>",
"cache_control": {"type": "ephemeral"},
}
],
messages=[
{"role": "user", "content": "How do I reset my password?"}
],
)
# Inspect cache_creation_input_tokens / cache_read_input_tokens
print(message.usage)
curl -X POST "<your base url>/messages" \
-H "x-api-key: <your_api_key>" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You are a support assistant. Product manual:\n<large reusable context>",
"cache_control": {"type": "ephemeral"}
}
],
"messages": [
{"role": "user", "content": "How do I reset my password?"}
]
}'
Error Handling​
Errors are returned in the Anthropic error format:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "A description of the problem."
}
}
Common HTTP status codes:
| Status | Meaning |
|---|---|
200 | Success |
400 | Invalid request (bad parameters or malformed body) |
401 | Invalid or missing API key |
403 | Anthropic models are disabled for the organization |
429 | Rate limit exceeded or insufficient credits |
500 | Internal server error |
Best Practices​
- Use the official Anthropic SDK and override only the base URL and API key.
- Always set an explicit
max_tokenssized to your use case. - Use
cache_controlon large, stable prefixes (system prompts, documents, tool definitions) to cut cost and latency. - Prefer streaming for long or interactive responses.
- Inspect
usage.cache_read_input_tokensto confirm your cache is being hit as expected.