Messages (Anthropic)
Creates a model response using the Anthropic-compatible API format.
Endpoint
POST https://gateway.mytokengate.com/v1/messagesRequest Example
curl --request POST \
--url https://gateway.mytokengate.com/v1/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "claude-sonnet-4-6",
"messages": [
{
"role": "user",
"content": "What opportunities and challenges will the AI industry face in 2025?"
}
],
"max_tokens": 8192
}'Authentication
All requests require a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_KEYRequest Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model name. See Models for available options. |
messages | array | Yes | A list of messages comprising the conversation. See Message Formats. |
max_tokens | integer | Yes | Maximum tokens to generate (1-128000). |
system | string or array | No | System prompt for context and instructions. See System Prompt. |
stream | boolean | No | If true, returns Server-Sent Events. |
temperature | float | No | Controls randomness. Range: 0-1. Default: 1. Not supported on Opus 4.7+. |
top_p | float | No | Nucleus sampling. Range: 0-1. Not supported on Opus 4.7+. |
top_k | integer | No | Top-k sampling. Not supported on Opus 4.7+. |
stop_sequences | array | No | Custom sequences that stop generation. |
tools | array | No | Tool definitions for function calling. See Tool Use. |
tool_choice | object | No | How the model should use tools. See Tool Use. |
thinking | object | No | Thinking/reasoning configuration. See Thinking Mode. |
System Prompt
Unlike OpenAI, Anthropic uses a separate top-level system parameter instead of a role: "system" message:
{
"model": "claude-sonnet-4-6",
"system": "You are a helpful coding assistant.",
"messages": [...],
"max_tokens": 4096
}For prompt caching, use the array form with cache_control:
{
"system": [
{
"type": "text",
"text": "You are a helpful assistant with access to the following documents...",
"cache_control": { "type": "ephemeral" }
}
]
}Message Formats
User Message (Text Only)
{ "role": "user", "content": "Hello!" }User Message (With Image)
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "<base64-encoded-image>"
}
},
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/photo.jpg"
}
},
{ "type": "text", "text": "Describe this image." }
]
}User Message (With PDF Document)
{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": "<base64-encoded-pdf>"
}
},
{ "type": "text", "text": "Summarize this document." }
]
}Assistant Message (With Tool Use)
{
"role": "assistant",
"content": [
{ "type": "text", "text": "Let me check the weather for you." },
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "get_weather",
"input": { "location": "Paris", "unit": "celsius" }
}
]
}Tool Result Message
In the Anthropic format, tool results are sent as role: "user" messages with tool_result content blocks (not a separate role: "tool" message like OpenAI):
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "22°C and sunny in Paris",
"is_error": false
}
]
}Key difference from OpenAI: tool results go in
role: "user"with atool_resultcontent block, andinputis a JSON object (not a string like OpenAI’sarguments).
Response
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "The response text..."
}
],
"model": "claude-sonnet-4-6",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 2095,
"output_tokens": 503,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}stop_reason Values
| Value | Description |
|---|---|
end_turn | Natural end |
max_tokens | Reached max_tokens limit |
stop_sequence | Hit a custom stop sequence |
tool_use | Model is calling a tool |
refusal | Safety refusal |
usage Fields
| Field | Description |
|---|---|
input_tokens | Input tokens (uncached portion) |
output_tokens | Output tokens |
cache_creation_input_tokens | Tokens written to cache |
cache_read_input_tokens | Tokens served from cache |
Total input = input_tokens + cache_creation_input_tokens + cache_read_input_tokens
Streaming
Set stream: true to receive responses as Server-Sent Events (SSE):
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://gateway.mytokengate.com/v1"
)
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=[{"role": "user", "content": "Hello!"}]
) as stream:
for text in stream.text_stream:
print(text, end="")Streaming Event Sequence
The stream follows this event order:
1. message_start → Message metadata (id, model, role, initial usage)
2. content_block_start → A new content block begins (text, tool_use, or thinking)
3. content_block_delta → Incremental content (text_delta, input_json_delta, thinking_delta)
4. content_block_stop → Content block ends
5. message_delta → Stop reason and final output token usage
6. message_stop → Stream endsDelta Types
delta.type | Content block type | Field | Description |
|---|---|---|---|
text_delta | text | delta.text | Text content increment |
thinking_delta | thinking | delta.thinking | Thinking content increment |
input_json_delta | tool_use | delta.partial_json | Tool input JSON fragment |
Streaming with Python SDK
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=[{"role": "user", "content": "Explain quantum computing"}],
thinking={"type": "enabled", "budget_tokens": 10000}
) as stream:
for event in stream:
if event.type == "content_block_delta":
if event.delta.type == "thinking_delta":
print(f"[Thinking] {event.delta.thinking}")
elif event.delta.type == "text_delta":
print(event.delta.text, end="")Tool Use
Tool Definition
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and state"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}Note: Anthropic tools use
input_schema(notparameters) and have notype: "function"wrapper like OpenAI.
tool_choice Options
| Value | Description |
|---|---|
{"type": "auto"} | Model decides whether to use tools (default) |
{"type": "any"} | Model must call at least one tool |
{"type": "tool", "name": "xxx"} | Model must call the specified tool |
{"type": "none"} | Model will not use any tools |
Complete Tool Use Example
import anthropic
import json
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://gateway.mytokengate.com/v1"
)
tools = [
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
]
# Step 1: Model decides to call a tool
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=[{"role": "user", "content": "How is the weather in Paris?"}],
tools=tools
)
# Step 2: Extract tool call and execute
tool_use_block = next(b for b in response.content if b.type == "tool_use")
tool_result = get_weather(**tool_use_block.input)
# Step 3: Send tool result back
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=[
{"role": "user", "content": "How is the weather in Paris?"},
{"role": "assistant", "content": response.content},
{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use_block.id,
"content": tool_result
}]
}
],
tools=tools
)
print(response.content[0].text)Thinking Mode
Anthropic models support extended thinking for complex reasoning tasks.
Basic Usage
{
"model": "claude-sonnet-4-6",
"max_tokens": 16000,
"thinking": { "type": "enabled", "budget_tokens": 10000 },
"messages": [{"role": "user", "content": "Solve this math problem step by step..."}]
}budget_tokensmust be less thanmax_tokens(minimum 1024)- When thinking is enabled, the response
contentarray will containthinkingblocks beforetextblocks
Response with Thinking
{
"content": [
{
"type": "thinking",
"thinking": "Let me analyze this step by step..."
},
{
"type": "text",
"text": "Based on my analysis..."
}
],
"stop_reason": "end_turn"
}Prompt Caching
Anthropic supports prompt caching to reduce cost and latency for repeated context. Add cache_control to content blocks:
{
"system": [
{
"type": "text",
"text": "You are a helpful assistant with access to these documents: ...",
"cache_control": { "type": "ephemeral" }
}
],
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What does the document say about X?",
"cache_control": { "type": "ephemeral" }
}
]
}
]
}- Maximum 4 cache breakpoints per request
- Cache TTL: 5 minutes (default) or 1 hour (
{ "type": "ephemeral", "ttl": "1h" }) - Cache hits cost approximately 0.1x the standard input price
- Cache writes cost 1.25x (5-minute TTL) or 2x (1-hour TTL) the standard input price
- Verify cache hits via
usage.cache_read_input_tokensin the response
Error Codes
| Code | Description |
|---|---|
| 400 | Invalid request parameters |
| 401 | Invalid or missing API key |
| 404 | Model not found |
| 429 | Rate limit exceeded |
| 503/504 | Service temporarily unavailable |