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, /v1/messages/count_tokens, /v1/models and /v1/models/{model}.
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.
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 messagecontent value can be a string or an array of supported blocks.
qwen3-8-27b and ornith-1-5-35b list image input. Check current availability and accepted input on each model’s page in the Model Library before sending images.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 asstrict, defer_loading, cache_control, and input_examples are accepted inside a tool definition and ignored.
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
Setthinking.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 X-RunInfra-Hint-Warnings says thinking cannot be disabled on this model. The documented behavior for GLM 5.3 Flash and Qwen3.8 2.4T A95B follows this rule. Check current availability before selecting either model.
thinking.budget_tokens is accepted and ignored. Reasoning spends the same max_tokens budget as the final answer.
Use output_config.effort with none, minimal, low, medium, high, xhigh, or max to select the reasoning effort. A value the model does not support can be moved to the nearest one it does, and X-RunInfra-Hint-Warnings then carries reasoning_effort_clamped. 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
Thecontent array preserves this order when the parts exist: a thinking block, a text block, then tool_use blocks.
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
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
Setstream: 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_deltafragments, then onesignature_delta. - A text block emits
text_deltafragments. - A tool-use block opens with
input: {}, then emitsinput_json_deltafragments. Concatenate eachpartial_jsonvalue to recover the full input object.
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
Every4xx and 5xx on the two Anthropic-compatible routes uses this envelope:
error.type, not the message text. A prompt longer than the model’s context window is the exception: its invalid_request_error message starts prompt is too long, the wording Claude Code compacts on.
Coding plan funding
A covered Messages request follows the same plan, credits, and Standby order as chat completions. Funding headers identify the request’s admission decision. When the plan or Standby pays, Messages success usage also carriesusage.cost (always 0) and usage.runinfra with cost_microcents, plan_value_microcents and paid_from, in the JSON body and in the final message_delta of a stream. Credit-funded and pay-as-you-go Messages usage carries the four token counters only, so read x-runinfra-funding to see that credits paid after a limit.
A plan limit returns HTTP 402, x-should-retry: false, and no Retry-After. The error type is billing_error. Only the message text survives from the detailed plan refusal, so it carries the product, limit, reset time, Standby condition, and next step with its Billing URL. The envelope does not carry error.code, standby_blocker, credit counters, or fixes.
In Messages clients such as Claude Code, read the message for the reason and next step. The CLI’s connection check preserves that self-contained refusal text even when the envelope has no error code. Display the message and read the funding headers. Use GET /v1/usage for structured current plan state. Do not try to read the OpenAI-compatible plan limit fields from a Messages error.
Related
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.