Skip to main content
POST /v1/messages accepts the Anthropic Messages request and response grammar. It is served by the same models, under the same rules, as POST /v1/chat/completions. Billing, credits, idempotency, rate limits, request-size limits, and cached-input pricing follow the same rules as chat completions. The envelope, content blocks, tool loop, thinking controls, and stream events follow the Anthropic-compatible contract on this page.
This is an Anthropic-compatible API for RunInfra hosted models. It does not claim parity with Anthropic models or every Anthropic platform feature.

Authentication and headers

Send your RunInfra API key in either authentication header on /v1/messages and /v1/messages/count_tokens. The response carries both request-id and x-request-id. Quote either value when you contact support. Idempotency-Key protects a /v1/messages retry from duplicate inference and billing. x-session-id uses the same routing-affinity behavior as the OpenAI-compatible routes.
x-api-key does not authenticate GET /v1/models or any route outside /v1/messages and its subpaths. An Anthropic SDK models.list() call therefore does not authenticate. List models with Bearer auth:

Create a message

Give the Anthropic SDK the bare host, https://api.runinfra.ai. The SDK appends /v1 itself. OpenAI clients use https://api.runinfra.ai/v1.

Request fields

Unknown top-level fields are ignored. This keeps newer Anthropic client request shapes usable without forwarding unsupported controls to the model.

Message content blocks

A message content value can be a string or an array of supported blocks.
Today glm-5-3-flash, qwen3-8-27b, ornith-1-5-35b, and qwen3-8-flash-next list image input. Treat each model page as authoritative because that set can change.
An image source with type: "url" or type: "file" returns 400 invalid_request_error. A document block or another unsupported Anthropic-only block also returns 400 and names the block type.

Tool use

Declare client tools with JSON Schema input. Fields such as strict, defer_loading, cache_control, and input_examples are accepted inside a tool definition and ignored.
A tool call returns a tool_use content block and stop_reason: "tool_use". Send the result in the next user message before any text or image blocks.
tool_choice accepts these forms: Add "disable_parallel_tool_use": true inside tool_choice when the model must request at most one tool in that turn. Anthropic server tools, including bash, text editor, web search, and computer use, are refused. This route supports client tools that your application executes.

Thinking and structured output

Set thinking.type to enabled or adaptive to keep model reasoning on. On deepseek-v4-pro, either value turns reasoning on. Set it to disabled to turn reasoning off on a model that supports disabling it. Some models cannot disable reasoning. The request still succeeds, the setting is ignored, and the response includes a hint header. Today this applies to glm-5-3-flash and qwen3-8-2-4t-a95b. thinking.budget_tokens is accepted and ignored. Reasoning spends the same max_tokens budget as the final answer. Use output_config.effort with low, medium, high, xhigh, or max to select the reasoning effort when the model accepts that value. Use output_config.format with type: "json_schema" to request structured output.

Accepted compatibility fields

These Anthropic-only fields are accepted and ignored: cache_control, service_tier, container, mcp_servers, context_management, inference_geo, and speed. They do not change routing, billing, or model behavior.

Response

The content array preserves this order when the parts exist: a thinking block, a text block, then tool_use blocks.
The thinking signature is opaque. It is not an Anthropic attestation. You may send it back in a prior assistant turn, where it is accepted and dropped. Your billed prompt count is input_tokens + cache_read_input_tokens.

Count input tokens

Use the same body as POST /v1/messages. max_tokens is optional for this operation. The endpoint estimates input tokens without running the model, so the call is not billed. The per-key request rate limit still applies.

Streaming

Set stream: true to receive event-named Server-Sent Events. There is no data: [DONE] sentinel. Blocks open only when their first output arrives:
  • A thinking block emits thinking_delta fragments, then one signature_delta.
  • A text block emits text_delta fragments.
  • A tool-use block opens with input: {}, then emits input_json_delta fragments. Concatenate each partial_json value to recover the full input object.
The stream order is message_start, lazily opened content blocks, message_delta, then message_stop. The server emits ping every 15 seconds while the model is silent.
message_start reports zero usage. The cumulative four-field usage on message_delta is authoritative. The official SDK stream helpers work unchanged, including Python messages.stream() and get_final_message(), and TypeScript messages.stream() and finalMessage(). If a failure happens after the stream opens, the final frame is an error event and there is no message_stop:

Errors

Every 4xx and 5xx on the two Anthropic-compatible routes uses this envelope:
Messages match the corresponding chat-completions errors. Branch on error.type, not the message text.

Claude Code

Configure Claude Code against the Anthropic-compatible routes.

Authentication

Choose the correct header and base URL.

OpenAI compatibility

Use chat completions or Responses with OpenAI clients.