Anthropic-compatible streaming
Endpoint: POST /api/anthropic/v1/messages
This endpoint accepts Anthropic Messages API payloads and streams Anthropic SSE events (message_start, content_block_start, content_block_delta, message_delta, message_stop). It is compatible with tools like Claude Code.
Note: You can also call OpenAI models through this Anthropic-compatible surface; the request must still follow Anthropic message shapes. See Cross‑provider compatibility.
Request schema
model(string) – requiredmessages(array) – required, Anthropic-style content blocks are supported (text, image, tool_use, tool_result)stream(boolean) – optional, must be booleanmax_tokens(int > 0) – required by Anthropic modelstemperature(0..1),top_p(0..1),top_k(int > 0)stop_sequences(string[]),metadata(object)thinking(object),cache_control(object)tool_choice(string | object),tools(array)parallel_tool_calls(boolean)
Media sources
- Images:
{ type: "image", source: { type: "base64", media_type, data } }is preferred. We also acceptsource: { type: "url", url }and will embed as base64 internally when needed. - PDFs:
{ type: "document", source: { type: "base64", media_type: "application/pdf", data } }is supported. Ifsource.urlis provided, we fetch-and-embed the PDF as base64. - Text documents:
{ type: "document", source: { type: "text", media_type: "text/plain", data } }is supported. Ifsource.urlpoints to text, we fetch-and-embed it as inline text. - Files API references:
{ type: "document", source: { type: "file", file_id } }is supported. See Files API below.
Invalid shapes or incompatible values return HTTP 400 with a descriptive error.
Headers
x-api-key: $API_KEYorAuthorization: Bearer $API_KEYanthropic-version: 2023-06-01- Optional betas: set
anthropic-beta: token1, token2and/or body{"betas":["token1","token2"]}.
cURL (streaming)
curl -N -X POST "https://api.kushrouter.com/api/anthropic/v1/messages" \
-H "x-api-key: $API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"messages": [{"role":"user","content":[{"type":"text","text":"Write a haiku about routers"}]}],
"max_tokens": 256,
"stream": true
}'Streaming frames
Events are emitted with explicit event: names per Anthropic spec. Example sequence:
event: message_start
data: {"type":"message_start","message":{...}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"..."}}
event: message_delta
data: {"type":"message_delta","delta":{}}
event: message_stop
data: {"type":"message_stop"}Tool streaming examples
Server tool use streams as content blocks. Tool arguments may be delivered incrementally via input_json_delta.
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"server_tool_use","id":"srvtoolu_01","name":"get_weather"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"city\":\"Bos"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"ton\"}"}}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: content_block_start
data: {"type":"content_block_start","index":2,"content_block":{"type":"tool_result","tool_use_id":"srvtoolu_01","content":[{"type":"text","text":"{\"tempC\": 23}"}]}}
event: content_block_stop
data: {"type":"content_block_stop","index":2}Tool controls
tool_choice:'auto' | 'none' | { type: "tool", name } | { type: "function", function: { name } }parallel_tool_calls(boolean): whenfalse, we disable parallel tool use upstream.pause_on_call_tools_start(boolean): causes the assistant to pause before tool execution so you can approve; resume by sendingtool_resultcontent.
Errors
- 400 – invalid JSON or unknown/unsupported parameters
- 401 – missing or invalid API key
- 413 – payload too large
- 429 – rate limit exceeded (key or IP)
- 5xx – transient errors
Post-stream usage
After a stream finishes, fetch token usage and metadata by generation ID (the message.id from message_start).