Claude Message Threads API ガイド
会話は最初の1回だけ送り、以降は新しいメッセージだけを送ります。
このページの内容
Claude message threads API を使うと、長い会話を最初の1回だけ送り、以降のターンでは新しいメッセージだけを送れます。最初の Messages リクエストに "thread": {"type": "create"} と message-threads-2026-08-12 ベータヘッダーを付けると、API が会話をメモリに保持します(Anthropic の Message threads ページ、2026年11月4日確認)。次のリクエストで送る量が減ります。
全モデルでベータです。使えるモデル ID は 17 個あり、下のコードで呼ぶ Claude Opus 5.5 も含まれます。ベータヘッダーはスレッドのすべてのリクエストに付けます。
スレッドが省くもの
スレッドを使わない場合、毎ターン会話全体を送ります。システムプロンプト、ツール定義、それまでのメッセージ、ツールの結果すべてです。スレッドはこの会話を Claude の返信ごとレスポンスの id の下に保存し、continue リクエストは前回以降に起きたことだけを送ります(Message threads ページ、2026年11月4日確認)。毎ターンの送信量が減ります。
プロンプトキャッシュは別の方向から同じ会話を助けます。キャッシュヒットすると、繰り返す入力の単価が下がります。Opus 5.5 では 100 万トークンあたり 0.20 ドル、新規入力は 4 ドルです(Anthropic の料金ページ、2026年11月4日確認)。ただしリクエストはその入力を運び続けます。スレッドは送る量を減らし、キャッシュは繰り返し部分の値段を下げます。長いセッションでは両方を使います。コンテキスト側の話は Claude Code のトークン消費を減らす方法 で扱っています。
スレッドは料金もレート制限も変えません(Message threads ページ、2026年11月4日確認)。現在の料金は料金ページにあります。
キャッシュは自分で付けます。毎回のリクエストのトップレベルに cache_control を送ると、API はそのリクエストの messages の最後のキャッシュ可能なブロックに適用します。ブレークポイントは 4 つまでというのがプロンプトキャッシュ全体の規則で、自動キャッシュが 1 つを使います(Anthropic のプロンプトキャッシュページ、2026年11月4日確認)。次のように配分します。
- トップレベルの
cache_control。スレッドの各リクエストで 1 つ。 systemに 1 つ。create リクエストで送ります。toolsに 1 つ。これも create で送ります。- いちばん新しいメッセージに 1 つ。
それ以前の保存済みメッセージ上のブレークポイントは、この 4 つに含まれません。continue リクエストは新しいメッセージだけを送るためです。一度送ったブレークポイントはその場に残ります。会話を再送するときは、以前のメッセージからブレークポイントを外し、最後のブロックに 1 つだけ残します(Message threads ページ、2026年11月4日確認)。
最初のターンを作り、続きを送る
手順は 3 つです。
- Anthropic のキーを
ANTHROPIC_API_KEYに入れます。 systemとtoolsを使うならそれも含めて会話全体を送り、"thread": {"type": "create"}を付けます。- 前回のレスポンス以降のメッセージだけを
"thread": {"type": "continue", "previous_message_id": "<previous id>"}と一緒に送ります。systemとtoolsは付けません。
どのリクエストにもベータヘッダーと anthropic-version: 2026-10-21 を付けます。これが現在のバージョンです(Anthropic の API バージョンのページ、2026年11月4日確認)。
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2026-10-21" \
-H "anthropic-beta: message-threads-2026-08-12" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"system": "You are a careful backend reviewer.",
"messages": [
{"role": "user", "content": "Read this design and list the risks."}
],
"thread": {"type": "create"}
}'
レスポンスの id を保存します。次のリクエストは新しいメッセージだけを送ります。
PREVIOUS_ID="<id from the previous response>"
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2026-10-21" \
-H "anthropic-beta: message-threads-2026-08-12" \
-H "content-type: application/json" \
-d @- <<JSON
{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Turn those risks into a checklist."}
],
"thread": {"type": "continue", "previous_message_id": "$PREVIOUS_ID"}
}
JSON
毎回の返信で最新の id を残します。スレッドは追記だけを受け付け、各レスポンスの id は 1 回だけ続けられ、次のリクエストには最新のものを使います(Message threads ページ、2026年11月4日確認)。
API キーを別の方法で用意したい場合、OmniaKey は同じモデル ID の Claude API を提供しているので、リクエストの body はそのまま使えます。スレッドは Anthropic 側ではベータです。本番で頼る前に、使う中継サービスが thread 項目をそのまま通すか確認してください。
Python SDK は id を代わりに保持します。client.beta.messages.thread(...) でヘルパーを作ると、呼び出しの準備だけを行い、各ターンは thread.send() で送ります。ヘルパーはベータヘッダーを付け、最初のターンで create し、以降は新しいメッセージだけで続けます。continue が thread_not_found、thread_already_continued、thread_continue_in_flight を返すと、新しい create リクエストで会話全体を 1 回だけ送り直します(Message threads ページ、2026年11月4日確認)。
import anthropic
client = anthropic.Anthropic() # ANTHROPIC_API_KEY を読み取ります
# この時点では何も送信しません。毎ターン使う項目を保持するだけです。
thread = client.beta.messages.thread(
model="claude-opus-5-5",
max_tokens=1024,
system="You are a careful backend reviewer.",
)
first = thread.send({"role": "user", "content": "Read this design and list the risks."})
print(first.id, first.stop_reason)
second = thread.send({"role": "user", "content": "Turn those risks into a checklist."})
print(second.id) # 次回はこの id から続けます
これらのリクエストは Anthropic の API に対して実行していません。形は Anthropic の Message threads ページに基づきます。ストリーミングでは thread.stream(...) と stream.get_final_message() で同じ流れになります。id を自分で管理したいときは thread.previous_message_id が返ります。
再送する項目と、送ってはいけない項目
Claude message threads API では、固定の項目は毎回同じ値で送ります。system と tools は create リクエストだけで送ります。自由な項目はターンごとに変えてかまいません。
| 区分 | 項目 | ルール |
|---|---|---|
| create のみ | system、tools | create リクエストだけ。continue リクエストでどちらかを送ると、null でも 400 になります。 |
| 固定 | model、tool_choice、thinking、各サーバーの認証トークンを除く mcp_servers、context_management、output_config、container 内の skills、トップレベルの cache_control、anthropic-beta の値の集合 | 毎回同じ値。違う値は 400 になり、違う項目名が示されます。 |
| 自由 | max_tokens、stop_sequences、stream、metadata、service_tier、名前のない項目 | いつ変えてもかまいません。 |
固定項目を変えたときの 400 には thread_fingerprint_mismatch が付き、メッセージに違う項目が並びます。値を変えたいときは、会話全体と新しい値で新しいスレッドを始めます。
previous_message_id を省くと、continue は 400 を返し、body に message はありますが error_code はありません。system や tools を付けた場合も同じです。continue は前回のレスポンス以降のメッセージだけを運びます。
mcp_servers は固定ですが、サーバーの URL と認証トークンはリクエストの中にしかありません。MCP を使うリクエストでは毎回このリストを送ります。トークンはリクエスト間で変わることがあります。コンテナの id もリクエストの中だけにあるので、container は毎回送ります(Message threads ページ、2026年11月4日確認)。
サーバー側のフォールバックは create の時点で決まります。fallbacks はスレッドの全リクエストで送るか、まったく送らないかのどちらかです。値はターンごとに変わってかまいませんが、項目を足したり外したりすると thread_fingerprint_mismatch が返ります。
有効期限、再送、404 のとき
Claude message threads API のスレッドは、最後のリクエストから 5 分で期限切れになり、最後に使われてから 1 時間以内に API が削除します。レスポンスを保存するたびに 5 分が延びます。スレッドはゼロデータ保持の対象外です。会話、システムプロンプト、ツールは暗号化してメモリに置かれ、永続ストレージには書き込まれません(Message threads ページ、2026年11月4日確認)。
レスポンスを見ても、そのターンが保存されたかはわかりません。create でも continue でも同じです。わかるのは次の continue のときです。アプリ側がすべてのメッセージの写しを持ち、正とします(Message threads ページ、2026年11月4日確認)。
continue が 404 thread_not_found を返したら、会話全体を新しい create リクエストで送り、そのレスポンスの id から続けます。次のどれでも API は同じ 404 を返します。
- スレッドの期限が切れた
- 前のターンが処理されたあと破棄された(
max_tokensで切れたツール呼び出しなど) - フォールバックのモデルが前のレスポンスを書いた
- 前のレスポンスがまだ生成中
- 別の組織、ワークスペース、ユーザー、ワークスペースキーからのリクエスト
- 新しいメッセージに、保存済みの会話にない内容が加わった(画像が 1 枚もなかった会話の最初の画像など)
会話全体を再送すれば、どの場合も直ります。
ストリーミングには追加のルールがあります。message_stop のあとでレスポンスの id から続けます。それより早い continue は 404 になることがあります。continue のストリームが message_stop の前に切れたら、同じ continue リクエストをもう一度送ります。そこで thread_already_continued か thread_continue_in_flight が返ったら再送します。ストリームが途中で切れたときの再試行は、SDK のヘルパーは行いません。自分で送り直します。
ほかに 3 つの場合があります。
pause_turn:そのレスポンスのidから"messages": []で続けます。404 なら、一時停止したレスポンスを含めて再送します。stop_reason: "refusal":原因になったターンを除いて新しいスレッドを始めます。API は拒否したターンをすでに保持していることがあります。usage.iterationsか、ストリームの最後のmessage_deltaにfallback_messageの項目があれば、フォールバックの回答です。再送します。
エラー
スレッドの 5 つのエラーはすべてモデルが動く前に返ります。リクエストはトークンを使わず、スレッドの期限も変わりません。400 の error.type は invalid_request_error、404 は not_found_error です(Message threads ページ、2026年11月4日確認)。
- 404、
thread_not_found:API がこのスレッドを続けられません。会話全体を新しい create リクエストで送ります。 - 400、
thread_fingerprint_mismatch:固定項目がスレッド作成時に保存した値と違います。同じ値に戻すか、新しいスレッドを始めます。 - 400、
thread_already_continued:そのレスポンス id はすでに一度使われています。最新の id から続け、受け取れていなければ再送します。 - 400、
thread_continue_in_flight:同じ id からの continue がまだ実行中です。多くは自分の前の試行です。終わるのを待つか、再送します。 - 400、
thread_unsupported_request:スレッドが対応していない機能か組織設定を使っています。error.details.unsupportedにcontext_management、cache_control、fallbacks、hipaa、inference_hooksのどれかが入ります。この一覧は増えることがあるので、知らない値ならthreadなしで会話全体を送ります。
Message Batches は thread 項目を受け付けません。付けたバッチ項目は invalid_request_error で失敗します。トークン数の計算と圧縮は 400 を返します。clear_thinking_20251015 に keep: "all" を付けた場合以外のコンテキスト編集も 400 です。HIPAA 対応の組織と、Inference hooks を有効にした組織も対象外です。スレッドの一覧、読み取り、削除は API にありません。
よくある質問
Claude message threads API とは何ですか?
会話を Anthropic 側に保存し、以降のターンで新しいメッセージだけを送れるようにする、Messages API のベータ機能です。ベータヘッダーは message-threads-2026-08-12 で、各リクエストに thread オブジェクトを足し、type を create か continue にします。
プロンプトキャッシュと併用できますか?
はい。スレッドはプロンプトをキャッシュしません。毎回のリクエストでトップレベルに cache_control を送り、ブレークポイントを 4 つまでにします。保存済みメッセージ上のブレークポイントはこの数に入りません。トップレベルの 1 つと、system や tools 上のものは数に入ります。
スレッドの途中でモデルを変えられますか?
モデルを変えるときは新しいスレッドを始めます。model は固定項目なので、違う値では 400 thread_fingerprint_mismatch が返ります。会話全体と新しいモデルで新しいスレッドを始めてください。
continue が error_code なしの 400 を返すのはなぜですか?
continue に previous_message_id がないか、system や tools が付いています。null でも同じです。この 400 は message だけを返し、error_code は付きません。本文を読んでください。
スレッドはどのくらい残り、期限が切れるとどうなりますか?
最後のリクエストから 5 分で期限切れになり、最後の使用から 1 時間以内に削除されます。そのあとの continue は 404 thread_not_found を返します。会話全体を新しい create リクエストで送り、その id から続けます。