Skip to main content

Endpoint

POST https://www.samuraiapi.in/api/v1/messages
When using the official anthropic SDK, set base_url="https://www.samuraiapi.in/api" — the SDK appends /v1/messages automatically.

Request Parameters

ParameterTypeRequiredDescription
modelstringClaude model ID (e.g. claude-3-5-sonnet-20241022)
messagesarrayConversation history — alternating user / assistant turns
max_tokensintegerMaximum tokens to generate. No default — must always be set
systemstringSystem prompt. Top-level field, not inside messages
streambooleanStream the response via SSE. Default: false
temperaturenumberCreativity: 0 = deterministic, 1 = default
top_pnumberNucleus sampling. Default: 1
top_kintegerSample from top K tokens only
stop_sequencesarrayStrings that stop generation when encountered
toolsarrayTool definitions the model can invoke
tool_choiceobjectControl when tools are called: auto, any, tool, none
metadata.user_idstringYour end-user ID for monitoring

Message Object

Each entry in messages must alternate user / assistant roles. The first message must be user.
{
  "role": "user",
  "content": "Hello!"
}
Content can be a string or an array of content blocks (for multimodal input):
{
  "role": "user",
  "content": [
    { "type": "text", "text": "What is in this image?" },
    {
      "type": "image",
      "source": {
        "type": "base64",
        "media_type": "image/jpeg",
        "data": "/9j/4AAQ..."
      }
    }
  ]
}

Basic Example

from anthropic import Anthropic

client = Anthropic(
    base_url="https://www.samuraiapi.in/api",
    api_key="YOUR_SAMURAI_KEY"
)

message = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    system="You are a concise assistant. Keep answers under 3 sentences.",
    messages=[
        {"role": "user", "content": "What is the capital of Japan?"}
    ]
)

print(message.content[0].text)
# => "The capital of Japan is Tokyo."

print(f"Tokens: {message.usage.input_tokens} in / {message.usage.output_tokens} out")

Response Format

{
  "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "The capital of Japan is Tokyo."
    }
  ],
  "model": "claude-3-5-sonnet-20241022",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 28,
    "output_tokens": 9
  }
}

stop_reason Values

ValueMeaning
end_turnModel finished naturally
max_tokensHit the max_tokens limit
stop_sequenceMatched a stop_sequences entry
tool_useModel wants to call a tool

Streaming

Set stream: true to receive tokens as they are generated. The SDK handles SSE parsing automatically.
from anthropic import Anthropic

client = Anthropic(
    base_url="https://www.samuraiapi.in/api",
    api_key="YOUR_SAMURAI_KEY"
)

with client.messages.stream(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a short story about a samurai."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

# After the stream, access usage:
final = stream.get_final_message()
print(f"\nTotal tokens: {final.usage.input_tokens + final.usage.output_tokens}")

SSE Event Sequence

Samurai AI emits the full Anthropic SSE event sequence:
event: message_start
data: {"type":"message_start","message":{"id":"msg_01...","type":"message","role":"assistant","content":[],"model":"claude-3-5-sonnet-20241022","stop_reason":null,"usage":{"input_tokens":14,"output_tokens":1}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: ping
data: {"type":"ping"}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"In"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" feudal Japan"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":142}}

event: message_stop
data: {"type":"message_stop"}

Multi-turn Conversations

Build multi-turn conversations by appending each exchange to the messages array:
from anthropic import Anthropic

client = Anthropic(
    base_url="https://www.samuraiapi.in/api",
    api_key="YOUR_SAMURAI_KEY"
)

conversation = []

def chat(user_input: str) -> str:
    conversation.append({"role": "user", "content": user_input})

    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=512,
        system="You are a knowledgeable travel guide.",
        messages=conversation,
    )

    reply = response.content[0].text
    conversation.append({"role": "assistant", "content": reply})
    return reply

print(chat("What's special about Kyoto?"))
print(chat("What's the best time of year to visit?"))  # Claude remembers the context
print(chat("How long should I stay?"))

Tool Use (Function Calling)

Give Claude access to external tools. Tools use input_schema (not parameters).
import json
from anthropic import Anthropic

client = Anthropic(
    base_url="https://www.samuraiapi.in/api",
    api_key="YOUR_SAMURAI_KEY"
)

tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather for a city",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "The city name, e.g. 'Tokyo'"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "Temperature unit"
                }
            },
            "required": ["city"]
        }
    }
]

# Step 1: Send initial message with tools
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "What's the weather in Tokyo?"}]
)

# Step 2: Check if Claude wants to use a tool
if response.stop_reason == "tool_use":
    tool_use = next(b for b in response.content if b.type == "tool_use")
    print(f"Claude called: {tool_use.name}({tool_use.input})")

    # Step 3: Execute the tool
    def get_weather(city: str, unit: str = "celsius"):
        return {"city": city, "temperature": 18, "condition": "Partly cloudy", "unit": unit}

    result = get_weather(**tool_use.input)

    # Step 4: Send the result back
    final = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=1024,
        tools=tools,
        messages=[
            {"role": "user", "content": "What's the weather in Tokyo?"},
            {"role": "assistant", "content": response.content},
            {
                "role": "user",
                "content": [
                    {
                        "type": "tool_result",
                        "tool_use_id": tool_use.id,
                        "content": json.dumps(result)
                    }
                ]
            }
        ]
    )
    print(final.content[0].text)
    # => "The current weather in Tokyo is 18°C and partly cloudy."

tool_choice Options

ValueBehavior
{"type": "auto"}Claude decides whether to use a tool (default)
{"type": "any"}Claude must use at least one tool
{"type": "tool", "name": "X"}Claude must use the named tool
{"type": "none"}Claude cannot use tools

Vision (Image Input)

Claude can analyze images passed as base64 or URLs.
import base64
from pathlib import Path
from anthropic import Anthropic

client = Anthropic(
    base_url="https://www.samuraiapi.in/api",
    api_key="YOUR_SAMURAI_KEY"
)

# From a local file
image_data = base64.standard_b64encode(Path("photo.jpg").read_bytes()).decode("utf-8")

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": image_data,
                    },
                },
                {
                    "type": "text",
                    "text": "Describe what you see in this image."
                }
            ],
        }
    ],
)

print(response.content[0].text)

Supported Image Formats

Formatmedia_type
JPEGimage/jpeg
PNGimage/png
GIFimage/gif
WebPimage/webp

Temperature & Sampling

# Deterministic — best for factual tasks, code generation
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=512,
    temperature=0.0,
    messages=[{"role": "user", "content": "List the planets in order from the Sun."}]
)

# Creative — best for writing, brainstorming
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=512,
    temperature=1.0,
    top_p=0.95,
    messages=[{"role": "user", "content": "Write an opening line for a mystery novel."}]
)

Error Handling

Errors are returned in Anthropic format:
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "max_tokens is required"
  }
}

Error Types

error.typeHTTP StatusCause
invalid_request_error400Missing or invalid parameters
authentication_error401Invalid or missing API key
permission_error403Key lacks access to this model or tier
not_found_error404Unknown model ID
rate_limit_error429Too many requests or quota exceeded
api_error500/503Server-side error — safe to retry

Error Handling in Code

from anthropic import Anthropic, APIError, RateLimitError, AuthenticationError

client = Anthropic(
    base_url="https://www.samuraiapi.in/api",
    api_key="YOUR_SAMURAI_KEY"
)

try:
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello!"}]
    )
    print(response.content[0].text)

except AuthenticationError:
    print("Invalid API key. Check your credentials.")

except RateLimitError:
    print("Rate limit hit. Slow down or upgrade your plan.")

except APIError as e:
    print(f"API error {e.status_code}: {e.message}")

Migration from Anthropic Cloud

Change one line — everything else stays the same:
# Before
from anthropic import Anthropic
client = Anthropic(api_key="sk-ant-api03-...")

# After — Samurai AI
from anthropic import Anthropic
client = Anthropic(
    base_url="https://www.samuraiapi.in/api",
    api_key="YOUR_SAMURAI_KEY"             # Your Samurai API key
)

# All existing code works unchanged ✓
// Before
const client = new Anthropic({ apiKey: "sk-ant-api03-..." });

// After — Samurai AI
const client = new Anthropic({
  baseURL: "https://www.samuraiapi.in/api",
  apiKey: process.env.SAMURAI_API_KEY!,
});
Your Samurai API key starts with sk-samurai- or a custom prefix. Get yours from the dashboard.