Anthropic Messages
POST /v1/messages is compatible with the Anthropic Messages API. Use it when your code already runs on the Anthropic SDK, or with tools that speak the Anthropic format, such as Claude Code. It serves Claude models only. For every other chat model use /v1/chat/completions.
Models
| Model id | Price |
|---|---|
claude-opus-5.5 | $5.40 / $27.00 per 1M tokens |
claude-sonnet-5 | $3.24 / $16.20 per 1M tokens |
claude-fable-5.1 | $10.80 / $54.00 per 1M tokens |
A non-Claude model id on this endpoint is rejected with an error.
Request
POST https://jantaris.com/v1/messages
x-api-key: sk-jt-...
anthropic-version: 2023-06-01
Content-Type: application/jsonThe anthropic-version: 2023-06-01 header is required. The official SDKs send it automatically. The key can go in x-api-key or Authorization: Bearer (Authentication).
| Field | Type | Required | Description |
|---|---|---|---|
model | string | yes | Claude model id |
max_tokens | integer | yes | Upper limit for generated tokens |
messages | array | yes | Alternating user and assistant turns in Anthropic format |
system | string or array | no | System prompt |
stream | boolean | no | true returns Server-Sent Events in Anthropic format |
temperature | number | no | Sampling temperature |
tools | array | no | Tool definitions in Anthropic format |
Basic call
curl https://jantaris.com/v1/messages \
-H "x-api-key: $JANTARIS_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-5.5",
"max_tokens": 1024,
"system": "You are a concise code reviewer.",
"messages": [{"role": "user", "content": "Review: def add(a, b): return a - b"}]
}'# pip install anthropic
import os
from anthropic import Anthropic
client = Anthropic(base_url="https://jantaris.com", api_key=os.environ["JANTARIS_API_KEY"])
msg = client.messages.create(
model="claude-opus-5.5",
max_tokens=1024,
system="You are a concise code reviewer.",
messages=[{"role": "user", "content": "Review: def add(a, b): return a - b"}],
)
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://jantaris.com", apiKey: process.env.JANTARIS_API_KEY });
const msg = await client.messages.create({
model: "claude-opus-5.5",
max_tokens: 1024,
system: "You are a concise code reviewer.",
messages: [{ role: "user", content: "Review: def add(a, b): return a - b" }],
});
console.log(msg.content[0].text);Note the base URL for the Anthropic SDK: https://jantaris.com, without /v1. The SDK appends /v1/messages itself.
Response
{
"id": "msg_...",
"type": "message",
"role": "assistant",
"model": "claude-opus-5.5",
"content": [{ "type": "text", "text": "The function subtracts instead of adding..." }],
"stop_reason": "end_turn",
"usage": { "input_tokens": 31, "output_tokens": 57 }
}Streaming
With stream: true the response is a stream of Anthropic events (message_start, content_block_delta, message_stop and others).
curl -N https://jantaris.com/v1/messages \
-H "x-api-key: $JANTARIS_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": "Explain SSE in two sentences."}]}'with client.messages.stream(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Explain SSE 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: "Explain SSE in two sentences." }],
});
stream.on("text", (text) => process.stdout.write(text));
await stream.finalMessage();Tool use
Tools follow the Anthropic format: name, description, input_schema. The model answers with a tool_use block, you reply with a tool_result block.
tools = [{
"name": "get_order_status",
"description": "Returns the shipping status of an order",
"input_schema": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
}]
messages = [{"role": "user", "content": "Where is order A-1042?"}]
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"} # your code here
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)Errors
Errors on this endpoint use the Anthropic format, so the Anthropic SDK raises its usual exceptions:
{ "type": "error", "error": { "type": "authentication_error", "message": "Invalid API key." } }HTTP status codes are the same as elsewhere in the API. The default rate limit is 600 requests per minute per key. See Errors.
Which endpoint to pick
| You use | Endpoint |
|---|---|
| Anthropic SDK, Claude Code | /v1/messages |
| OpenAI SDK, Cursor, Cline, Continue, n8n, Make | /v1/chat/completions |
| Claude from the OpenAI SDK | /v1/chat/completions with model: "claude-..." |









