Skip to content
View as Markdown

Messages

Generates a model response in the Anthropic Messages format. The gateway translates the request to Chat Completions, sends it to the model, and translates the response back. Each parameter below is marked with what the translation does with it today.

POST/messages
URL
https://api.bricksum.com/v1/messages

Authentication

Authentication is the same on every endpoint the gateway fronts, and is documented on the API Reference page.

Request body

Support status

supported
The gateway handles it, or a published measurement shows it works.
passed through
Forwarded to the model server; not verified by Kiln.
ignored
Accepted with 200, but not applied. The rest of the response is normal.
not supported
Rejected with an error, or not working on the models named in the description.

Common parameters

These are documented once on the API Reference page. Listed here with what this endpoint does differently.

  • modelstringsupported

    Optional here. When the field is empty or missing, the gateway uses its configured default model. An unknown ID — an Anthropic model ID included — is rejected with 404 (not_found_error).

    Full definition

  • messagesarrayrequiredsupported

    An empty or missing array is rejected with 400 (invalid_request_error). content is a string or an array of content blocks, in the shapes below. A message with any other role is treated as a user message.

    Full definition

    user message
    • rolestringrequiredsupported

      Set to "user".

      Allowed values
      user
    • content[].type= "text"objectsupported

      Text. Consecutive text blocks are joined into one string.

    • content[].type= "image"objectsupported

      Translated to an image_url part. A base64 source becomes a data: URL, and a url source is forwarded as sent. It works only on models whose input includes images; see the Models page.

    • content[].type= "tool_result"objectsupported

      Translated to a tool message whose tool_call_id is tool_use_id, in block order. content is a string or text blocks; blocks of other types inside it are dropped. is_error is not forwarded.

    • content[].type= "document"objectignored

      Dropped before the request reaches the model. The same applies to block types that are not listed here.

    assistant message
    • rolestringrequiredsupported

      Set to "assistant".

      Allowed values
      assistant
    • content[].type= "text"objectsupported

      An earlier model reply.

    • content[].type= "tool_use"objectsupported

      Translated to a tool_calls entry with the same id and name. input is sent as a compact JSON string.

    • content[].type= "thinking"objectignored

      thinking and redacted_thinking blocks are dropped. The model does not receive its earlier reasoning text.

    system message
    • rolestringrequiredsupported

      A message with role "system" inside messages becomes a system message at that position. Only its text is kept.

      Allowed values
      system
  • max_tokensintegersupported

    A value above 32,768 is lowered to 32,768 instead of being rejected, which keeps room for the prompt in the context window. When the field is missing or 0, it is not forwarded and the model server applies its own default.

    Full definition

  • streambooleansupported

    The stream is a sequence of Anthropic events, listed under Stream events below.

    Default
    false

    Full definition

  • toolsarraysupported

    A tool with a name and an input_schema is translated to a function definition.

    Full definition

    custom tool
    • namestringrequiredsupported

      The name the model uses in tool_use blocks.

    • descriptionstringsupported

      What the tool does. The model server rejects a function without a description with 400.

    • input_schemaobjectrequiredsupported

      JSON Schema of the tool input. It becomes the function parameters.

    built-in tool
    • typestringignored

      A tool without an input_schema, such as bash_20250124, is skipped. The model cannot run Anthropic server tools, so it does not see them.

  • tool_choice= {"type": "auto"}objectsupported

    Translated to tool_choice: "auto", and forwarded only when at least one custom tool is sent.

    Full definition

  • tool_choice= {"type": "any"} | {"type": "tool", ...}objectnot supported

    Forced tool choice. any is translated to tool_choice: "required", and tool to the named function. On qwen3-32b (measured 2026-09-26), forced tool choice fails without a clear error: tool_choice "required" returns HTTP 500 with a plain-text "Internal Server Error" body, and naming a function returns 200 with empty arguments (finish_reason "stop"). Neither is a 4xx, so do not retry it — send tool_choice "auto" only.

    Full definition

  • tool_choice= {"type": "none"}objectpassed through

    Translated to tool_choice: "none" and forwarded to the model server; not verified by Kiln.

    Full definition

Only on this endpoint

  • systemstring | arraysupported

    System prompt: a string, or an array of text blocks. Each text block becomes one system message at the start of the conversation, in order. Blocks of other types are dropped.

  • tool_choice.disable_parallel_tool_usebooleanpassed through

    true is translated to parallel_tool_calls: false and forwarded to the model server; this translation was not measured by Kiln. On qwen3-32b the parallel_tool_calls setting is not applied, which is not the same as replies holding one call: even with parallel_tool_calls: false, one reply can carry several tool calls. Answer every entry in tool_calls with its own tool message.

  • thinkingobjectsupported

    type "enabled" or "adaptive" is translated to reasoning_effort: "medium". budget_tokens is not used. With any other type, no reasoning_effort is sent.

  • output_config.effortstringsupported

    Translated to reasoning_effort, and takes precedence over thinking. max, xhigh and ultra are lowered to high. Other values are dropped.

    Allowed values
    low, medium, high
  • temperaturenumberpassed through

    Copied to the chat request and forwarded to the model server; not verified by Kiln.

  • top_pnumberpassed through

    Copied to the chat request and forwarded to the model server; not verified by Kiln.

  • top_kintegerignored

    Accepted, but dropped. The translation has no matching chat parameter.

  • stop_sequencesarrayignored

    Translated to stop, which is accepted but not applied today. Generation continues past the stop string, and stop_sequence in the response is null.

  • cache_controlobjectignored

    Accepted on any block, tool or system entry, and dropped. Prefix caching on the model server does not depend on it; see usage.cache_read_input_tokens.

  • metadataobjectignored

    Accepted, but dropped. The same applies to context_management.

Fields that are not listed here are dropped before the request reaches the model server. They do not cause an error.

Response body

FieldTypeDescription
idstring"msg_" followed by the ID of the underlying chat completion.
typestring"message".
rolestring"assistant".
modelstringThe model ID of the request.
content[]arrayOutput blocks in this order: one thinking block when the model returned reasoning text, one text block, then one tool_use block per tool call. Do not assume content[0] is text.
content[].thinkingstringReasoning text of a thinking block. The block carries no signature.
content[].textstringGenerated text of a text block.
content[].inputobjectArguments of a tool_use block, next to id and name. Arguments that are not a JSON object are kept as a string under _malformed_arguments.
stop_reasonstring"end_turn" (finish_reason stop), "max_tokens" (length) or "tool_use" (tool_calls, or any reply that has tool calls). Other finish reasons map to "end_turn".
stop_sequencenullnull in every response.
usage.input_tokensintegerInput tokens, copied from prompt_tokens of the chat completion.
usage.output_tokensintegerOutput tokens, including reasoning tokens.
usage.cache_read_input_tokensintegerInput tokens served from the prefix cache. 0 when the model server reports none.
X-Neocloud-Generation-IdheaderResponse header with the ID of the usage event for this request. Store it with your logs. The Messages usage object has no cost field.

Stream events

With stream: true, each event has an event: line with its name and a data: line with a JSON object of the same type. The order is message_start, then content_block_start, content_block_delta and content_block_stop for each block, then message_delta and message_stop. One block is open at a time. There is no data: [DONE] line.

FieldTypeDescription
message_starteventOpens the message: id, model, empty content. Its usage holds input_tokens: 0 and output_tokens: 0, because the model server reports usage only at the end.
content_block_starteventOpens the block at index. content_block.type is thinking, text or tool_use; a tool_use block carries id and name.
content_block_deltaeventNew content of the open block. delta.type is text_delta (text), thinking_delta (thinking) or input_json_delta (partial_json). Concatenate partial_json per block, then parse it.
content_block_stopeventCloses the block at index.
message_deltaeventdelta.stop_reason and usage.output_tokens. The model server sends usage in a chunk after the one with finish_reason, so the gateway reads the stream to its end before it writes this event. The stream does not report input tokens.
message_stopeventThe last event of a complete message.
pingeventSent after 15 seconds without data from the model server, for example during a long reasoning pause. It can arrive at any point, including before message_start. Ignore it.
erroreventThe last event of a failed stream, in the Anthropic error envelope. A model server error, a read failure or a stream that ends before completion gives api_error. No message_stop follows.

Errors

After authentication, errors use the Anthropic envelope: {"type": "error", "error": {"type", "message"}}. Branch on the HTTP status and error.type, not on the message text. Rows with an empty error.type cell come from the gateway before the request reaches this endpoint, and use the body shown under the table.

Every status code is listed on the Errors page.

Status · error.typeCauseWhat to do
400invalid_request_errorThe body is not valid JSON, messages is empty or missing, or a message content is neither a string nor an array of blocks.Fix the payload. Do not retry as sent.
400invalid_request_errorThe model server rejected the translated request, for example more than the model's context window (the Models page lists it per model). error.message carries the model server's message.Shorten the conversation or fix the parameters.
404not_found_errorThe model ID is not in the catalog.Check the ID against GET /models.
405invalid_request_errorThe method is not POST.Send the request with POST.
429rate_limit_errorThe organization already has 8 requests in flight. No rate-limit headers are sent.Back off exponentially and retry.
502api_errorThe model backend returned an error or was unreachable, or its response could not be translated.Retry with exponential backoff.
503api_errorNo model backend is available.Retry with exponential backoff.

401, 402, 403 and 429 come from the gateway before the request reaches this endpoint. They are listed once on the API Reference page.

Authentication, credit, budget and rate-limit (requests/min, tokens/min) errors are returned by the gateway before the Anthropic translation. Their body is not the Anthropic envelope:

json
{
  "error": {
    "message": "invalid API key",
    "type": "authorization"
  }
}

Limits

  • Output: max_tokens is capped at 32,768. A larger value is lowered, not rejected.
  • Metering: a Messages request is metered and billed as one chat completion, with the same token counts and the same per-organization limit of 8 concurrent requests.

Context length, request body size, timeouts and the per-organization rate limits apply here as well; they are listed once on the API Reference page.

Headers and retry guidance for 429 are on the Rate limits page.