# Messages > POST /messages のリファレンス(Anthropic Messages 形式)です。ヘッダー、リクエストパラメータごとの変換状況、レスポンスフィールド、ストリームイベント、エラー、制限、サンプルを説明します。 Source: https://kiln.bricksum.com/docs/ja/api-reference/messages `POST https://api.bricksum.com/v1/messages` Anthropic Messages 形式でモデルの応答を生成します。ゲートウェイはリクエストを Chat Completions に変換してモデルに送り、レスポンスを Messages 形式に戻します。以下の各パラメータには、現在この変換がその値をどう扱うかを示しています。 ## 認証 ゲートウェイが処理するエンドポイントの認証方法はすべて同じで、 [API リファレンス](https://kiln.bricksum.com/docs/ja/api-reference) ページで説明しています。 ## リクエストボディ | ステータス | 説明 | | --- | --- | | 対応 | ゲートウェイが処理するか、公開済みの実測で動作を確認した項目です。 | | 転送のみ | モデルサーバーに転送されます。Kiln は動作を検証していません。 | | 無視 | 200 で受け付けられますが、適用されません。レスポンスのその他の部分は通常どおりです。 | | 非対応 | エラーで拒否されるか、説明に記載したモデルでは動作しません。 | ### 共通パラメータ 以下のパラメータの定義は [API リファレンス](https://kiln.bricksum.com/docs/ja/api-reference) ページに一度だけ記載しています。ここには、このエンドポイントで異なる点だけを記載します。 | フィールド | 型 | 必須 | デフォルト | ステータス | 説明 | | --- | --- | --- | --- | --- | --- | | `model` | string | | | 対応 | ここでは任意です。このフィールドが空または未指定の場合は、ゲートウェイに設定された既定のモデルを使用します。カタログにない ID は、Anthropic のモデル ID も含めて 404(not_found_error)で拒否されます。 | | `messages` | array | 必須 | | 対応 | 配列が空または未指定の場合は 400(invalid_request_error)で拒否されます。content は文字列、または以下の形の content ブロックの配列です。それ以外の role を持つメッセージは user メッセージとして扱われます。 | | `messages[].role (user メッセージ)` | string | 必須 | | 対応 | "user" を指定します。 指定できる値: user | | `messages[].content[].type = "text" (user メッセージ)` | object | | | 対応 | テキストです。連続する text ブロックは 1 つの文字列に結合されます。 | | `messages[].content[].type = "image" (user メッセージ)` | object | | | 対応 | image_url パートに変換されます。base64 の source は data: URL になり、url の source は送信した値のまま転送されます。画像入力に対応するモデルでのみ動作します。モデルページを確認してください。 | | `messages[].content[].type = "tool_result" (user メッセージ)` | object | | | 対応 | tool_use_id を tool_call_id とする tool メッセージに変換され、ブロックの順序は保たれます。content は文字列または text ブロックで、その中の他の型のブロックは取り除かれます。is_error は転送されません。 | | `messages[].content[].type = "document" (user メッセージ)` | object | | | 無視 | モデルに届く前に取り除かれます。ここに記載のないブロック型も同様です。 | | `messages[].role (assistant メッセージ)` | string | 必須 | | 対応 | "assistant" を指定します。 指定できる値: assistant | | `messages[].content[].type = "text" (assistant メッセージ)` | object | | | 対応 | 以前のモデルの応答です。 | | `messages[].content[].type = "tool_use" (assistant メッセージ)` | object | | | 対応 | 同じ id と name を持つ tool_calls の項目に変換されます。input は空白を詰めた JSON 文字列として送られます。 | | `messages[].content[].type = "thinking" (assistant メッセージ)` | object | | | 無視 | thinking と redacted_thinking ブロックは取り除かれます。モデルは以前の reasoning テキストを受け取りません。 | | `messages[].role (system メッセージ)` | string | 必須 | | 対応 | messages 内で role が "system" のメッセージは、その位置の system メッセージになります。テキストのみが保持されます。 指定できる値: system | | `max_tokens` | integer | | | 対応 | 32,768 を超える値は拒否されず 32,768 に引き下げられ、その分コンテキスト内にプロンプトの余地が残ります。このフィールドが未指定または 0 の場合は転送されず、モデルサーバーのデフォルトが適用されます。 | | `stream` | boolean | | `false` | 対応 | ストリームは Anthropic のイベントの連続で、以下のストリームイベントに記載しています。 | | `tools` | array | | | 対応 | name と input_schema を持つツールは関数定義に変換されます。 | | `tools[].name (カスタムツール)` | string | 必須 | | 対応 | モデルが tool_use ブロックで使用する名前です。 | | `tools[].description (カスタムツール)` | string | | | 対応 | ツールの動作の説明です。モデルサーバーは description のない関数を 400 で拒否します。 | | `tools[].input_schema (カスタムツール)` | object | 必須 | | 対応 | ツール入力の JSON Schema です。関数の parameters になります。 | | `tools[].type (組み込みツール)` | string | | | 無視 | bash_20250124 のように input_schema のないツールはスキップされます。モデルは Anthropic のサーバーツールを実行できないため、これらのツールを受け取りません。 | | `tool_choice = {"type": "auto"}` | object | | | 対応 | tool_choice: "auto" に変換され、カスタムツールが 1 つ以上ある場合にのみ転送されます。 | | `tool_choice = {"type": "any"} \| {"type": "tool", ...}` | object | | | 非対応 | 強制的なツール選択です。any は tool_choice: "required" に、tool は指定した関数に変換されます。qwen3-32b では、強制的なツール選択が明確なエラーなしに失敗します(2026-09-26 実測)。tool_choice を "required" にすると本文が平文 "Internal Server Error" の HTTP 500 が返り、関数を指定すると arguments が空の 200(finish_reason "stop")が返ります。どちらも 4xx ではないため、再試行では解決しません。tool_choice は "auto" のみを送ってください。 | | `tool_choice = {"type": "none"}` | object | | | 転送のみ | tool_choice: "none" に変換され、モデルサーバーに転送されます。Kiln は動作を検証していません。 | ### このエンドポイント固有のパラメータ | フィールド | 型 | 必須 | デフォルト | ステータス | 説明 | | --- | --- | --- | --- | --- | --- | | `system` | string \| array | | | 対応 | システムプロンプトです。文字列、または text ブロックの配列で送信します。各 text ブロックは会話の先頭の system メッセージになり、順序は保たれます。他の型のブロックは取り除かれます。 | | `tool_choice.disable_parallel_tool_use` | boolean | | | 転送のみ | true は parallel_tool_calls: false に変換され、モデルサーバーに転送されます。この変換経路は Kiln が測定していません。qwen3-32b では parallel_tool_calls の設定が適用されません。これは応答のツール呼び出しが 1 つだけという意味ではありません。parallel_tool_calls: false を送っても、1 つの応答に複数のツール呼び出しが含まれることがあります。tool_calls のすべての項目に、それぞれ tool メッセージで応答してください。 | | `thinking` | object | | | 対応 | type が "enabled" または "adaptive" の場合、reasoning_effort: "medium" に変換されます。budget_tokens は使用されません。それ以外の type の場合、reasoning_effort は送られません。 | | `output_config.effort` | string | | | 対応 | reasoning_effort に変換され、thinking より優先されます。max、xhigh、ultra は high に引き下げられます。それ以外の値は取り除かれます。 指定できる値: low, medium, high | | `temperature` | number | | | 転送のみ | chat リクエストにコピーされ、モデルサーバーに転送されます。Kiln は動作を検証していません。 | | `top_p` | number | | | 転送のみ | chat リクエストにコピーされ、モデルサーバーに転送されます。Kiln は動作を検証していません。 | | `top_k` | integer | | | 無視 | 受け付けられますが、取り除かれます。この変換には対応する chat パラメータがありません。 | | `stop_sequences` | array | | | 無視 | stop に変換されますが、stop は現在、受け付けられるだけで適用されません。stop 文字列の後も生成が続き、レスポンスの stop_sequence は null です。 | | `cache_control` | object | | | 無視 | ブロック、ツール、system の項目のどこにあっても受け付けられ、取り除かれます。モデルサーバーのプレフィックスキャッシュはこの値に関係なく動作します。usage.cache_read_input_tokens を確認してください。 | | `metadata` | object | | | 無視 | 受け付けられますが、取り除かれます。context_management も同様です。 | ここに記載のないフィールドは、リクエストがモデルサーバーに届く前に取り除かれます。エラーにはなりません。 ## レスポンスボディ | フィールド | 型 | 説明 | | --- | --- | --- | | `id` | string | "msg_" の後に、内部の chat completion の ID が続きます。 | | `type` | string | "message" です。 | | `role` | string | "assistant" です。 | | `model` | string | リクエストで指定したモデル ID です。 | | `content[]` | array | 出力ブロックです。モデルが reasoning テキストを返した場合は thinking ブロックが 1 つ、続いて text ブロックが 1 つ、その後にツール呼び出しごとの tool_use ブロックがこの順で並びます。content[0] が text であると想定しないでください。 | | `content[].thinking` | string | thinking ブロックの reasoning テキストです。このブロックに signature はありません。 | | `content[].text` | string | text ブロックの生成されたテキストです。 | | `content[].input` | object | tool_use ブロックの引数です。id、name とともに返されます。JSON オブジェクトでない引数は、_malformed_arguments の下に文字列として保持されます。 | | `stop_reason` | string | "end_turn"(finish_reason stop)、"max_tokens"(length)、"tool_use"(tool_calls、またはツール呼び出しを含む応答)のいずれかです。それ以外の finish_reason は "end_turn" になります。 | | `stop_sequence` | null | すべてのレスポンスで null です。 | | `usage.input_tokens` | integer | 入力トークン数です。chat completion の prompt_tokens をそのまま写した値です。 | | `usage.output_tokens` | integer | 出力トークン数です。reasoning トークンを含みます。 | | `usage.cache_read_input_tokens` | integer | プレフィックスキャッシュから処理された入力トークン数です。モデルサーバーが報告しない場合は 0 です。 | | `X-Neocloud-Generation-Id` | header | このリクエストの usage イベント ID を含むレスポンスヘッダーです。ログと一緒に保存してください。Messages の usage オブジェクトに cost フィールドはありません。 | ## ストリームイベント stream: true の場合、各イベントは、名前を示す event: 行と、同じ type の JSON オブジェクトを含む data: 行で構成されます。順序は message_start、ブロックごとの content_block_start、content_block_delta、content_block_stop、その後 message_delta、message_stop です。同時に開くブロックは 1 つだけです。data: [DONE] 行はありません。 | フィールド | 型 | 説明 | | --- | --- | --- | | `message_start` | event | メッセージを開始します。id、model、空の content を含みます。モデルサーバーは usage を最後にのみ報告するため、このイベントの usage は input_tokens: 0、output_tokens: 0 です。 | | `content_block_start` | event | index の位置のブロックを開きます。content_block.type は thinking、text、tool_use のいずれかで、tool_use ブロックは id と name を含みます。 | | `content_block_delta` | event | 開いているブロックの新しい内容です。delta.type は text_delta(text)、thinking_delta(thinking)、input_json_delta(partial_json)のいずれかです。partial_json はブロックごとに連結してからパースしてください。 | | `content_block_stop` | event | index の位置のブロックを閉じます。 | | `message_delta` | event | delta.stop_reason と usage.output_tokens を含みます。モデルサーバーは finish_reason を含むチャンクの次のチャンクで usage を送るため、ゲートウェイはストリームを最後まで読んでからこのイベントを書き込みます。ストリームは入力トークン数を報告しません。 | | `message_stop` | event | 完了したメッセージの最後のイベントです。 | | `ping` | event | モデルサーバーから 15 秒間データが届かない場合に送信されます(長い reasoning の間など)。message_start の前を含め、どの時点でも届くことがあります。無視してください。 | | `error` | event | 失敗したストリームの最後のイベントで、Anthropic のエラー形式を使用します。モデルサーバーのエラー、読み取りの失敗、完了前に終了したストリームは api_error になります。その後に message_stop は届きません。 | ## エラー 認証を通過した後のエラーは、Anthropic の形式({"type": "error", "error": {"type", "message"}})で返されます。メッセージの文言ではなく、HTTP ステータスと error.type で分岐してください。error.type の欄が空の行は、リクエストがこのエンドポイントに届く前にゲートウェイが返すエラーで、表の下に示すボディ形式を使用します。 | ステータス | error.type | 原因 | 対処 | | --- | --- | --- | --- | | 400 | `invalid_request_error` | ボディが有効な JSON でない、messages が空または未指定、あるいはメッセージの content が文字列でもブロック配列でもありません。 | リクエスト内容を修正してください。そのまま再試行しないでください。 | | 400 | `invalid_request_error` | モデルサーバーが変換後のリクエストを拒否しました(モデルページに記載のモデル別コンテキスト長を超えるコンテキストなど)。error.message にモデルサーバーのメッセージが入ります。 | 会話を短くするか、パラメータを修正してください。 | | 404 | `not_found_error` | モデル ID がカタログにありません。 | GET /models で ID を確認してください。 | | 405 | `invalid_request_error` | メソッドが POST ではありません。 | POST でリクエストしてください。 | | 429 | `rate_limit_error` | 組織ですでに 8 件のリクエストが処理中です。レート制限ヘッダーは付きません。 | 指数バックオフで再試行してください。 | | 502 | `api_error` | モデルバックエンドがエラーを返したか、到達できなかったか、レスポンスを変換できませんでした。 | 指数バックオフで再試行してください。 | | 503 | `api_error` | 利用可能なモデルバックエンドがありません。 | 指数バックオフで再試行してください。 | 401、402、403、429 は、リクエストがこのエンドポイントに届く前にゲートウェイが返します。これらは [API リファレンス](https://kiln.bricksum.com/docs/ja/api-reference) ページに一度だけ記載しています。 認証、クレジット、予算、レート制限(1 分あたりのリクエスト数、トークン数)のエラーは、Anthropic 形式への変換より前にゲートウェイが返します。ボディは Anthropic の形式ではありません。 ```json { "error": { "message": "invalid API key", "type": "authorization" } } ``` すべてのステータスコードは [エラー](https://kiln.bricksum.com/docs/ja/errors) ページにあります。 ## 制限 - 出力:max_tokens の上限は 32,768 です。それより大きい値は拒否されず、引き下げられます。 - 計測:Messages リクエストは chat completion 1 件として計測され、課金されます。トークン数と、組織ごとの同時リクエスト 8 件の制限も同じように適用されます。 コンテキスト長、リクエストボディのサイズ、タイムアウト、組織ごとのレート制限もここに適用され、 [API リファレンス](https://kiln.bricksum.com/docs/ja/api-reference) ページに一度だけ記載しています。 429 のヘッダーと再試行の方法は [レート制限](https://kiln.bricksum.com/docs/ja/rate-limits) ページにあります。 ## サンプル ### リクエスト **cURL** ```bash curl https://api.bricksum.com/v1/messages \ -H "x-api-key: $KILN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3-32b", "max_tokens": 800, "system": "Answer briefly.", "messages": [ {"role": "user", "content": "Hello!"} ] }' ``` **Python** ```python import os from anthropic import Anthropic # base_url is the API origin without /v1: the SDK appends /v1/messages. # api_key is sent as x-api-key. Use auth_token=... to send a Bearer token. client = Anthropic( base_url="https://api.bricksum.com", api_key=os.environ["KILN_API_KEY"], ) message = client.messages.create( model="qwen3-32b", max_tokens=800, system="Answer briefly.", messages=[{"role": "user", "content": "Hello!"}], ) for block in message.content: if block.type == "text": print(block.text) print(message.usage) ``` **TypeScript** ```typescript import Anthropic from "@anthropic-ai/sdk"; // baseURL is the API origin without /v1: the SDK appends /v1/messages. // apiKey is sent as x-api-key. Use authToken to send a Bearer token. const client = new Anthropic({ baseURL: "https://api.bricksum.com", apiKey: process.env.KILN_API_KEY, }); const message = await client.messages.create({ model: "qwen3-32b", max_tokens: 800, system: "Answer briefly.", messages: [{ role: "user", content: "Hello!" }], }); for (const block of message.content) { if (block.type === "text") console.log(block.text); } console.log(message.usage); ``` ### レスポンス **200 OK** ```json { "id": "msg_7c1f0b9e2a", "type": "message", "role": "assistant", "model": "qwen3-32b", "content": [ {"type": "thinking", "thinking": "The user said hello. Reply briefly."}, {"type": "text", "text": "Hello! How can I help you today?"} ], "stop_reason": "end_turn", "stop_sequence": null, "usage": { "input_tokens": 21, "output_tokens": 34, "cache_read_input_tokens": 0 } } ``` **text/event-stream** ```text event: message_start data: {"message":{"content":[],"id":"msg_7c1f0b9e2a","model":"qwen3-32b","role":"assistant","stop_reason":null,"stop_sequence":null,"type":"message","usage":{"input_tokens":0,"output_tokens":0}},"type":"message_start"} event: ping data: {"type":"ping"} event: content_block_start data: {"content_block":{"text":"","type":"text"},"index":0,"type":"content_block_start"} event: content_block_delta data: {"delta":{"text":"Hello","type":"text_delta"},"index":0,"type":"content_block_delta"} event: content_block_delta data: {"delta":{"text":"! How can I help you today?","type":"text_delta"},"index":0,"type":"content_block_delta"} event: content_block_stop data: {"index":0,"type":"content_block_stop"} event: message_delta data: {"delta":{"stop_reason":"end_turn","stop_sequence":null},"type":"message_delta","usage":{"output_tokens":34}} event: message_stop data: {"type":"message_stop"} ``` **400 Bad Request** ```json { "type": "error", "error": { "type": "invalid_request_error", "message": "messages must contain at least one message" } } ```