Skip to content
TutujinAPI

API reference

Claude Messages API

Headers, parameters, request and response examples, SSE stream events and prompt caching for POST /v1/messages. Same format as the Anthropic Messages API; the official SDK works after changing base_url. Verified on this site.

POST /v1/messages is Anthropic's native API format. Code written with the official Anthropic SDK runs once you set the base URL to https://www.tutujin.com and use a key from this site; native parameters such as thinking, tool use and cache_control are passed to the model unchanged. We have verified this endpoint on this site.

POSThttps://www.tutujin.com/v1/messages

Headers

HeaderRequiredDescription
x-api-keyOne of the twoAn API key from the console (sk-...). The Anthropic SDK uses this header by default
AuthorizationOne of the twoBearer sk-..., as an alternative to x-api-key
anthropic-versionYesAPI version: 2023-06-01
content-typeYesapplication/json
anthropic-betaNoTurns on Anthropic beta features; relayed as-is, effect depends on the model

Request body

ParameterTypeRequiredDescription
modelstringYesModel name, e.g. claude-sonnet-5-5
max_tokensintegerYesMost tokens to generate. Required; leaving it out returns a 400
messagesarrayYesThe conversation. role is user or assistant, and the first message must be user
systemstring or arrayNoSystem prompt, at the top level rather than inside messages
temperaturenumberNo0 to 1, default 1. Lower values give steadier answers
top_pnumberNoNucleus sampling; tune this or temperature, not both
top_kintegerNoSample only from the K most likely tokens
stop_sequencesarrayNoStop generating when one of these strings appears
streambooleanNotrue returns server-sent events
toolsarrayNoTool definitions, each with name, description and input_schema (JSON Schema)
tool_choiceobjectNo{"type": "auto"}, {"type": "any"}, or {"type": "tool", "name": "get_weather"} for a specific tool
thinkingobjectNoExtended thinking, e.g. {"type": "enabled", "budget_tokens": 2048}; budget_tokens must be below max_tokens. Supported forms per model follow Anthropic's documentation
metadataobjectNoe.g. {"user_id": "u_123"}, your end-user identifier for abuse investigations

The messages array

content is a string or an array of content blocks. Common block types are text, image, tool_use (a tool call from the model) and tool_result (the result you send back). Image plus text looks like this:

JSON
{
  "role": "user",
  "content": [
    {
      "type": "image",
      "source": { "type": "base64", "media_type": "image/png", "data": "iVBORw0KGgo..." }
    },
    { "type": "text", "text": "How many rows does the table in this image have?" }
  ]
}

Request example

curl https://www.tutujin.com/v1/messages \
  -H "x-api-key: $TUTUJIN_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5-5",
    "max_tokens": 1024,
    "system": "You are a careful legal assistant. Cite the contract clause numbers you rely on.",
    "messages": [
      {"role": "user", "content": "The penalty is set at 30% of the contract value. What are the risks?"}
    ]
  }'

The Anthropic SDK sends x-api-key and anthropic-version for you and appends /v1/messages to the base URL, so the base URL is just the site root.

Response example

JSON
{
  "id": "msg_...",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-5-5",
  "content": [
    { "type": "text", "text": "A 30% penalty is high and a court may treat it as excessive..." }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 52,
    "output_tokens": 210,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0
  }
}
FieldDescription
contentContent blocks: text, thinking (with extended thinking on) and tool_use
stop_reasonend_turn finished normally; max_tokens hit the limit; stop_sequence hit a stop string; tool_use wants you to run a tool
usage.input_tokensInput tokens not served from cache, billed at the input price
usage.output_tokensOutput tokens including thinking, billed at the output price
usage.cache_creation_input_tokensInput tokens written to the cache, billed at the cache-write price
usage.cache_read_input_tokensInput tokens read from the cache, billed at the cache-read price

Streaming

With "stream": true the server returns Anthropic's SSE events. New text is in delta.text of content_block_delta events, and message_delta carries the stop reason and final output tokens:

Text
event: message_start
data: {"type":"message_start","message":{"id":"msg_...","type":"message","role":"assistant","content":[],"usage":{"input_tokens":52,"output_tokens":1}}}

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

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"A 30% penalty"}}

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":210}}

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

The SDKs wrap these events, so you can read the text stream directly:

with client.messages.stream(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a 60-word product description"}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
    print("\n", stream.get_final_message().usage)

Prompt caching

Long prefixes you send every time, such as a system prompt or a product manual, can be marked with cache_control so the model caches them. Later requests that hit the cache pay the cache-read price for that part:

JSON
{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "system": [
    { "type": "text", "text": "You are an after-sales agent. Answer only from the return policy below." },
    { "type": "text", "text": "(the full, long return policy goes here)", "cache_control": { "type": "ephemeral" } }
  ],
  "messages": [{ "role": "user", "content": "Can I return an opened item?" }]
}

cache_control is relayed to the model as-is. Cache writes and cache reads are each billed at their own price in the price list; check cache_read_input_tokens in the response usage to see whether you hit the cache. How caching works and when it pays off: What context caching is and how it saves money.

Notes

  • max_tokens is required. Put the system prompt in the top-level system, not as a message in messages.
  • messages must start with user, and user and assistant must alternate.
  • Extended thinking counts as output tokens; a larger budget_tokens raises the most a single call can cost.
  • Claude groups differ in line source and price — see Choosing a group.
  • To switch between vendors, use Chat Completions; Claude models the catalog lists for that endpoint work there too. For native features such as extended thinking and prompt caching, this endpoint is the more direct route.

Models that support this endpoint

ModelVendorCheapest groupInput ¥/1MOutput ¥/1MPer request ¥
Claude Haiku 5.5AnthropicClaude Plus¥0.4¥2—
Claude Sonnet 5.5AnthropicClaude Lite¥3.2¥16—
Claude Opus 5.5AnthropicClaude Lite¥8¥40—
claude-3-5-sonnet-allAnthropicEconomy (per token)——¥0.128
Claude Haiku 5.5AnthropicClaude Plus¥0.4¥2—
claude-haiku-4-5-20251001AnthropicClaude Lite¥1.6¥8—
claude-haiku-4-5-20251001-thinkingAnthropicClaude Lite¥1.6¥8—
claude-3-haiku-20240307AnthropicClaude Direct¥1.88¥9.38—

Prices in CNY, cheapest group for each model; updated Nov 13, 2026, 6:13 PM.

49 models support this endpoint; the table shows some of them. See them all in the model hub

Still stuck? Add our WeChat support JsnonoChat and send the request id from the error message, and we will look into it.