Anthropic Messages
POST /v1/messages mirrors the Anthropic Messages API. It is the right choice if your project is built on the Anthropic SDK, or if you run a tool that expects Anthropic's format, Claude Code being the main example. Only Claude models are available here. Every other chat model goes through /v1/chat/completions.
Claude models on this endpoint
| Model id | Price |
|---|---|
claude-opus-5.5 | $3.78 / $18.90 per 1M tokens |
claude-sonnet-5 | $3.24 / $16.20 per 1M tokens |
claude-fable-5.1 | $9.45 / $47.25 per 1M tokens |
Send any other model id and the request is refused with an error.
Headers and body
POST https://kadraris.com/v1/messages
x-api-key: sk-kd-...
anthropic-version: 2023-06-01
Content-Type: application/jsonEvery request must carry anthropic-version: 2023-06-01. If you use an official SDK you do not have to think about it, because the SDK adds it. Your key may be sent as x-api-key or as Authorization: Bearer (see Authentication).
| Field | Type | Required | Meaning |
|---|---|---|---|
model | string | yes | A Claude model id |
max_tokens | integer | yes | Most tokens the model may write |
messages | array | yes | user and assistant turns, alternating, Anthropic format |
system | string or array | no | The system prompt |
stream | boolean | no | true for Anthropic-style Server-Sent Events |
temperature | number | no | Sampling temperature |
tools | array | no | Tools the model may use, Anthropic format |
Sending a message
curl https://kadraris.com/v1/messages \
-H "x-api-key: $KADRARIS_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-5.5",
"max_tokens": 1024,
"system": "You review code briefly and point out bugs.",
"messages": [{"role": "user", "content": "Review: def is_even(n): return n % 2 == 1"}]
}'# pip install anthropic
import os
from anthropic import Anthropic
client = Anthropic(base_url="https://kadraris.com", api_key=os.environ["KADRARIS_API_KEY"])
msg = client.messages.create(
model="claude-opus-5.5",
max_tokens=1024,
system="You review code briefly and point out bugs.",
messages=[{"role": "user", "content": "Review: def is_even(n): return n % 2 == 1"}],
)
print(msg.content[0].text)
print(msg.usage)// npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://kadraris.com",
apiKey: process.env.KADRARIS_API_KEY,
});
const msg = await client.messages.create({
model: "claude-opus-5.5",
max_tokens: 1024,
system: "You review code briefly and point out bugs.",
messages: [{ role: "user", content: "Review: def is_even(n): return n % 2 == 1" }],
});
console.log(msg.content[0].text);Watch the base URL. For the Anthropic SDK it is https://kadraris.com with no /v1 at the end, since the SDK adds /v1/messages on its own.
What the API returns
{
"id": "msg_...",
"type": "message",
"role": "assistant",
"model": "claude-opus-5.5",
"content": [{ "type": "text", "text": "The check is inverted: n % 2 == 1 is true for odd numbers..." }],
"stop_reason": "end_turn",
"usage": { "input_tokens": 31, "output_tokens": 57 }
}Streamed replies
Setting stream: true switches the reply to a sequence of Anthropic events, among them message_start, content_block_delta and message_stop.
curl -N https://kadraris.com/v1/messages \
-H "x-api-key: $KADRARIS_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{"model": "claude-sonnet-5", "max_tokens": 512, "stream": true, "messages": [{"role": "user", "content": "Describe a CDN in two sentences."}]}'with client.messages.stream(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Describe a CDN in two sentences."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)const stream = client.messages.stream({
model: "claude-sonnet-5",
max_tokens: 512,
messages: [{ role: "user", content: "Describe a CDN in two sentences." }],
});
stream.on("text", (text) => process.stdout.write(text));
await stream.finalMessage();Tools
A tool is described with name, description and input_schema, as in Anthropic's API. When the model wants to use one, it returns a tool_use block. You run the tool and answer with a tool_result block in the next user turn.
tools = [{
"name": "get_order_status",
"description": "Look up where an order is in shipping",
"input_schema": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
}]
messages = [{"role": "user", "content": "Has order B-2210 shipped yet?"}]
first = client.messages.create(model="claude-sonnet-5", max_tokens=1024, tools=tools, messages=messages)
if first.stop_reason == "tool_use":
call = next(b for b in first.content if b.type == "tool_use")
result = {"order_id": call.input["order_id"], "status": "shipped"} # replace with a real lookup
messages += [
{"role": "assistant", "content": first.content},
{"role": "user", "content": [{"type": "tool_result", "tool_use_id": call.id, "content": str(result)}]},
]
final = client.messages.create(model="claude-sonnet-5", max_tokens=1024, tools=tools, messages=messages)
print(final.content[0].text)Error responses
Errors come back in Anthropic's format, and the Anthropic SDK turns them into its standard exceptions:
{ "type": "error", "error": { "type": "authentication_error", "message": "Invalid API key." } }Status codes match the rest of the Kadraris API. By default one key may make 600 requests per minute. More in Errors.
Choosing between the two chat endpoints
| Your client | Endpoint |
|---|---|
| Anthropic SDK, Claude Code | /v1/messages |
| OpenAI SDK, Cursor, Cline, Continue, n8n, Make | /v1/chat/completions |
| OpenAI SDK, but you want a Claude model | /v1/chat/completions with model: "claude-..." |























