Messages
Generate a model response using the Anthropic Messages wire format. Use this endpoint with the Anthropic SDKs, Claude Code and any tool that has an "Anthropic base URL" setting; it serves the same Claud models and bills identically to Chat completions.
Claud is an independent service. This endpoint implements a request format for interoperability; it is not affiliated with Anthropic and every request is served by a Claud model.
Authentication#
Send your key as x-api-key: sk-... (what the Anthropic SDKs do) or Authorization: Bearer sk-.... The anthropic-version header is accepted and ignored.
Request body#
- modelstringrequired
- A Claud model slug or alias, for example
claud-5.1. - max_tokensintegerrequired
- Upper bound on generated tokens, including thinking tokens.
- messagesarrayrequired
- Alternating
user/assistantturns.contentis a string or an array of blocks:text,image(source.type=base64orurl),tool_use(assistant),tool_result(user) andthinking. Unknown block types are ignored. - systemstring | array
- System prompt, either a string or an array of
textblocks.cache_controlmarkers are accepted and ignored. - temperaturenumber
- Between
0and1. - top_pnumber
- Nucleus sampling threshold in
(0, 1]. - top_kinteger
- Accepted for compatibility; not applied.
- stop_sequencesstring[]
- Up to 16 sequences at which generation halts.
- streambooleandefault: false
- Stream the response as server-sent events (see below).
- toolsarray
- Tool definitions:
{ name, description?, input_schema }. Up to 128. - tool_choiceobject
{ type: "auto" },{ type: "any" },{ type: "none" }or{ type: "tool", name }.- thinkingobject
{ type: "enabled", budget_tokens? }turns on reasoning for reasoning-capable models;{ type: "disabled" }turns it off.budget_tokensis accepted but the model's own limits apply.- metadataobject
{ user_id }is recorded on usage records for your own attribution.
Response#
{
"id": "msg_01J9X3Q5K7M2N8P4R6T0V2W4Y6",
"type": "message",
"role": "assistant",
"model": "claud-5.1",
"content": [{ "type": "text", "text": "Rivers carve the stone..." }],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 18,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"output_tokens": 42,
"claud_tokens_debited": "102",
"claud_cost_usd": "0.000204"
}
}- contentarray
- Ordered blocks:
thinking(reasoning models with thinking enabled),text, andtool_use({ id, name, input }withinputalready parsed as an object). - stop_reasonstring
end_turn,max_tokensortool_use. Claud cannot distinguish a stop sequence from a natural end, sostop_sequenceis alwaysnulland such stops reportend_turn.- usage.input_tokensinteger
- Prompt tokens that were not served from cache.
cache_read_input_tokensholds the cached portion; the two sum to the total prompt size. - usage.output_tokensinteger
- Generated tokens, including thinking tokens.
- usage.claud_tokens_debitedstring
- Claud tokens charged for this request.
- usage.claud_cost_usdstring
- The same charge in USD.
The response also carries the x-request-id, x-claud-model, x-claud-tokens-debited, x-claud-balance and x-ratelimit-* headers described under Chat completions.
Streaming#
With "stream": true the response is a text/event-stream in the Messages event sequence:
event: message_start
data: {"type":"message_start","message":{"id":"msg_...","type":"message","role":"assistant","model":"claud-5.1","content":[],"stop_reason":null,"usage":{"input_tokens":0,"output_tokens":0}}}
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":"Rivers "}}
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":{"input_tokens":18,"cache_read_input_tokens":0,"output_tokens":42,"claud_tokens_debited":"102","claud_cost_usd":"0.000204","claud_balance_tokens":"1199400","claud_fallback_used":false}}
event: message_stop
data: {"type":"message_stop"}- Thinking arrives as a
thinkingblock withthinking_deltadeltas, before the text block. - Tool calls arrive as
tool_useblocks:content_block_startcarriesidandname;input_json_deltadeltas carrypartial_jsonfragments that concatenate to the arguments object. - Final token counts and billing are on
message_delta.claud_balance_tokensis your available balance after the request;claud_fallback_usedistrueif a fallback model served it. - Errors after the stream has started are sent as
event: errorwith an Anthropic-style error body, followed by the end of the stream.
Count tokens#
Accepts the same body as /v1/messages (max_tokens optional) and returns { "input_tokens": n } using the same estimator the gateway uses to reserve tokens before a request. Not billed and not rate limited against your token budget.
Examples#
curl https://api.claudkey.com/v1/messages \
-H "x-api-key: $CLAUD_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claud-5.1",
"max_tokens": 200,
"system": "You are a concise assistant.",
"messages": [{"role": "user", "content": "Write a haiku about rivers."}]
}'Tool use round trip#
{
"model": "claud-5.1",
"max_tokens": 400,
"tools": [{
"name": "get_weather",
"description": "Current weather for a city",
"input_schema": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] }
}],
"messages": [
{ "role": "user", "content": "What is the weather in Paris?" },
{ "role": "assistant", "content": [
{ "type": "tool_use", "id": "toolu_01", "name": "get_weather", "input": { "city": "Paris" } }
]},
{ "role": "user", "content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "18°C, cloudy" }
]}
]
}Errors#
Errors use the Messages envelope { "type": "error", "error": { "type", "message", "code", "request_id" } }. Codes are the same as for Chat completions; error.type is one of invalid_request_error, authentication_error, permission_error, not_found_error, rate_limit_error, request_too_large, overloaded_error or api_error.