LLMoxy provides a fully compatible Anthropic Messages API interface, optimized for the Claude series models. Users of the official Anthropic SDK only need to change base_url to switch.
Base URL
https://llmoxy.com/v1
Authentication
Two authentication methods are supported:
Method 1: x-api-key (recommended)
x-api-key: YOUR_API_KEY
Method 2: Authorization
Authorization: Bearer YOUR_API_KEY
Messages API
Claude's core conversation interface.
Request URL
POST /v1/messages
Request Example
curl https://llmoxy.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Write a binary search algorithm in Python"
}
]
}'
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | Yes | Model name |
| messages | array | Yes | Conversation message list |
| max_tokens | integer | Yes | Maximum generated token count |
| system | string | No | System prompt |
| temperature | number | No | Temperature parameter, 0–1 |
| top_p | number | No | Nucleus sampling parameter |
| stream | boolean | No | Whether to stream output |
| stop_sequences | array | No | Stop sequences |
Message Format
Unlike OpenAI, the Anthropic format uses a separate parameter for the system prompt:
{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"system": "You are a Python programming expert",
"messages": [
{
"role": "user",
"content": "Write a quicksort"
},
{
"role": "assistant",
"content": "Sure, I'll write a Python quicksort..."
},
{
"role": "user",
"content": "Add detailed comments"
}
]
}
Note
- messages can only contain
userandassistantroles- Must start with a
usermessageuserandassistantmessages must alternate
Response Format
{
"id": "msg_123",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "This is Claude's reply content"
}
],
"model": "claude-sonnet-4-20250514",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 25,
"output_tokens": 150
}
}
Streaming Output
Set stream: true to enable streaming:
curl https://llmoxy.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}'
Streaming Response Format
event: message_start
data: {"type":"message_start","message":{"id":"msg_123",...}}
event: content_block_delta
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"H"}}
event: content_block_delta
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"i"}}
event: message_stop
data: {"type":"message_stop"}
Supported Models
| Model | Description | Available Groups |
|---|---|---|
| claude-opus-4-20250514 | Best performance | Max, Kiro |
| claude-sonnet-4-20250514 | Balanced choice | Max, Kiro |
| claude-haiku-4-20250414 | Fast response | Max, Kiro |
TIP See the official model hub for currently available models.
Multimodal Support
Claude supports image input:
{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "/9j/4AAQSkZJRg..."
}
},
{
"type": "text",
"text": "What is in this image?"
}
]
}
]
}
Supported image formats: JPEG, PNG, GIF, WebP. Max 5MB per image.
Code Examples
Python (Official SDK)
from anthropic import Anthropic
client = Anthropic(
api_key="YOUR_API_KEY",
base_url="https://llmoxy.com/v1"
)
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{"role": "user", "content": "Write a Python decorator"}
]
)
print(message.content[0].text)
Python (Streaming)
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Write an article"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Node.js (Official SDK)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: 'YOUR_API_KEY',
baseURL: 'https://llmoxy.com/v1'
});
const message = await client.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'Write a quicksort' }
]
});
console.log(message.content[0].text);
cURL
curl https://llmoxy.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello, Claude!"}
]
}'
Error Handling
Error Response Format
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "Error description"
}
}
Common Error Types
| Error Type | Description |
|---|---|
| invalid_request_error | Request parameter error |
| authentication_error | Authentication failed |
| permission_error | Insufficient permissions |
| not_found_error | Resource not found |
| rate_limit_error | Rate limit exceeded |
| api_error | Internal error |
| overloaded_error | Service overloaded |
Error Handling Example
from anthropic import Anthropic, APIError
client = Anthropic(
api_key="YOUR_API_KEY",
base_url="https://llmoxy.com/v1"
)
try:
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}]
)
except APIError as e:
print(f"Error type: {e.type}")
print(f"Error message: {e.message}")
Advanced Usage
1. System Prompt
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="You are a Python expert, good at data analysis and machine learning.",
messages=[
{"role": "user", "content": "How to handle missing values with pandas?"}
]
)
2. Multi-turn Conversation
conversation = [
{"role": "user", "content": "Write a user class"},
{"role": "assistant", "content": "Sure, I'll write a User class..."},
{"role": "user", "content": "Add password encryption"}
]
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=conversation
)
3. Image Analysis
import base64
with open("image.jpg", "rb") as f:
image_data = base64.b64encode(f.read()).decode()
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_data
}
},
{
"type": "text",
"text": "Analyze this architecture diagram"
}
]
}
]
)
Best Practices
1. Set max_tokens Reasonably
Different models have different maximum outputs: Opus 32K, Sonnet 64K, Haiku 8K. Set according to actual needs to avoid waste.
2. Use the system Parameter for Prompts
Put role definitions in the system parameter, not in messages:
# ✅ Recommended
message = client.messages.create(
system="You are a Python expert",
messages=[{"role": "user", "content": "Write code"}],
...
)
# ❌ Not recommended
message = client.messages.create(
messages=[{"role": "user", "content": "You are a Python expert. Write code"}],
...
)
3. Handle Long Conversations
Claude has a 200K context window, but it is recommended to periodically summarize conversations and remove unimportant historical messages to save token consumption.
4. Implement Retry Logic
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10)
)
def call_claude():
return client.messages.create(...)
Next Steps
- Groups and Pricing — learn about pricing details
- Get Support — contact us if you encounter issues
