# Claude Message Threads API ガイド

> Claude API の message threads を解説。ベータヘッダー、create と continue の送り方、再送する項目、有効期限、404 のあとの直し方。

- Canonical HTML: https://omniakey.com/ja/blog/claude-message-threads-api-guide
- Markdown: https://omniakey.com/ja/blog/claude-message-threads-api-guide.md
- Published: 2026-11-04 (updated 2026-11-04)
- Author: Kiki, COO at OmniaKey
- Language: ja
- Category: API setup
- Reading time: 9 min
- All posts: https://omniakey.com/blog/llms.txt

---

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](https://omniakey.com/ja/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 のトークン消費を減らす方法](https://omniakey.com/ja/blog/reduce-claude-code-token-usage) で扱っています。

スレッドは料金もレート制限も変えません（Message threads ページ、2026年11月4日確認）。現在の料金は[料金ページ](https://omniakey.com/ja/pricing)にあります。

キャッシュは自分で付けます。毎回のリクエストのトップレベルに `cache_control` を送ると、API はそのリクエストの `messages` の最後のキャッシュ可能なブロックに適用します。ブレークポイントは 4 つまでというのがプロンプトキャッシュ全体の規則で、自動キャッシュが 1 つを使います（Anthropic のプロンプトキャッシュページ、2026年11月4日確認）。次のように配分します。

1. トップレベルの `cache_control`。スレッドの各リクエストで 1 つ。
2. `system` に 1 つ。create リクエストで送ります。
3. `tools` に 1 つ。これも create で送ります。
4. いちばん新しいメッセージに 1 つ。

それ以前の保存済みメッセージ上のブレークポイントは、この 4 つに含まれません。continue リクエストは新しいメッセージだけを送るためです。一度送ったブレークポイントはその場に残ります。会話を再送するときは、以前のメッセージからブレークポイントを外し、最後のブロックに 1 つだけ残します（Message threads ページ、2026年11月4日確認）。

## 最初のターンを作り、続きを送る

手順は 3 つです。

1. Anthropic のキーを `ANTHROPIC_API_KEY` に入れます。
2. `system` と `tools` を使うならそれも含めて会話全体を送り、`"thread": {"type": "create"}` を付けます。
3. 前回のレスポンス以降のメッセージだけを `"thread": {"type": "continue", "previous_message_id": "<previous id>"}` と一緒に送ります。`system` と `tools` は付けません。

どのリクエストにもベータヘッダーと `anthropic-version: 2026-10-21` を付けます。これが現在のバージョンです（Anthropic の API バージョンのページ、2026年11月4日確認）。

```bash
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` を保存します。次のリクエストは新しいメッセージだけを送ります。

```bash
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日確認）。

```python
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` から続けます。

## 確認した出典

- [Anthropic: message threads](https://platform.claude.com/docs/en/build-with-claude/message-threads)
- [Anthropic: プロンプトキャッシュ](https://platform.claude.com/docs/en/build-with-claude/prompt-caching)
- [Anthropic: Claude API の料金](https://platform.claude.com/docs/en/about-claude/pricing)
- [Anthropic: API のバージョン](https://platform.claude.com/docs/en/api/versioning)
