On this page

Long agent loops on the Claude Messages API often grow a large conversation: system instructions, tool definitions, tool results, and many turns of dialogue. Without message threads, each new request typically uploads that whole history again. Message threads, a beta feature first documented on November 2, 2026, store the conversation on the server after a create turn so later continue turns send only the new messages.

This is an API integration guide for the Messages API thread field. It is not the same as Managed Agents session threads—those are a different product surface. A message thread also does not replace prompt caching: the server keeps conversation state for continue turns, but it does not automatically cache prompts for you; set cache_control yourself when you need caching. The examples below are frozen from Anthropic’s documentation and marked not executed here.

What changes between create and continue

Create looks like a normal Messages request. You send the full conversation so far, plus system and tools when you use them, and add:

json
"thread": {"type": "create"}

The API stores the conversation—including Claude’s reply—under that response’s id. There is no separate field that confirms storage succeeded; you learn whether the thread is usable on the next continue.

Continue sends only messages that appeared since the previous response, plus:

json
"thread": {
  "type": "continue",
  "previous_message_id": "<id of the previous response>"
}

Leave system and tools out of continue requests. The thread keeps the values from create. Sending either field again—even as null—returns a 400 error.

Every request in a thread must include the beta header message-threads-2026-08-12 (in cURL: anthropic-beta: message-threads-2026-08-12; in the Python SDK example: betas=["message-threads-2026-08-12"]).

Fields that stay fixed, and fields that can move

Anthropic groups request fields into create-only, fixed, and free:

GroupFieldsRule
Create-onlysystem, toolsSend on create only. Continue must omit them.
Fixedmodel, tool_choice, thinking, mcp_servers (except each server’s authorization token), context_management, output_config, skills inside container, top-level cache_control, and the set of anthropic-beta valuesSame values on every turn of the thread. A mismatch returns 400 thread_fingerprint_mismatch.
Freemax_tokens, stop_sequences, stream, metadata, service_tier, and other fields not listed as fixed or create-onlyMay change turn to turn.

The API does not store MCP server URLs, MCP authorization tokens, or the container id. If you use those, send mcp_servers and container again on each request that needs them. To change a create-only or fixed field, start a new thread with a create that includes the full conversation and the new values.

A thread is append-only. Each response id can be continued once, so always continue from the latest response id. To edit or branch earlier history, create a new thread.

Your app keeps the full history

While a thread is valid, continue sends only new messages—not the full history each time. New messages usually start with a user turn, or with tool_result blocks that answer a tool_use from the previous response. Do not resend messages the API already has: a duplicate can appear twice or the request can error. If a response stops with stop_reason: "pause_turn", resume with a continue from that response’s id and an empty messages list ("messages": []); if that returns 404, replay the full conversation—including the paused response—in a new create.

Your application remains the source of truth: keep a complete copy of every message, and plan a replay path from the start. If the conversation must outlive the process, persist that copy yourself. Anthropic’s SDK thread helper can keep an in-memory copy while the helper object exists and can replay on failure; it does not replace durable storage you may need outside the process.

When continue fails because the thread is gone (typically 404 thread_not_found), send the full conversation again in a new create—including system and tools—then continue from the new response id.

Expiry, deletion, and what you cannot look up

  • Idle expiry: 5 minutes after the last request. Each response the API successfully stores restarts that 5-minute window.
  • Deletion: the API deletes a thread no more than 1 hour after its last use.
  • There is no API to list, read, or delete a thread.

Threads are held in memory, encrypted under a server-managed key, and are not written to durable storage. They are not ZDR eligible. Using threads does not, by itself, change how you use other ZDR-eligible features; check Anthropic’s retention documentation for your organization.

Common continue failures before the model runs include thread_not_found (replay with create), thread_fingerprint_mismatch (fixed fields drifted), thread_already_continued (that id was already continued), thread_continue_in_flight (another continue from the same id is still running), and thread_unsupported_request (feature or org setting not allowed with threads).

Platforms, pricing, and unsupported combinations

Message threads are available on the Claude API, Claude Platform on AWS, Claude Models on Google Cloud (Anthropic managed), and Claude in Microsoft Foundry. Documentation lists the beta as available on every model; treat the model id in samples as an example from the docs page of the day, not a permanent pin.

Threads do not change pricing or rate limits. Anthropic also states that token usage stays the same: even when each HTTP request is smaller, Claude still reads the full conversation each turn.

Unsupported combinations include Message Batches with thread, token counting requests that include thread, on-demand compaction with threads, most context editing options, organizations with HIPAA readiness enabled, and organizations with Inference hooks turned on. Many of these return 400 thread_unsupported_request.

Official create and continue examples

The following samples are copied from the Claude Platform docs page on message threads. They require an API key and spend quota if you run them. Samples below are marked not executed here. The documented sample uses anthropic-version: 2026-10-21 and model id claude-opus-5-5 as shown in that page.

cURL

bash
# Turn 1: send the full conversation and create a thread
curl -sS --fail-with-body 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,
    "cache_control": {"type": "ephemeral"},
    "system": "You are a support agent for Acme. Keep replies short.",
    "messages": [{"role": "user", "content": "Hi! I have a question about an order."}],
    "thread": {"type": "create"}
  }'

# Turn 2: send only the new message. Set message_id to the id of the turn 1 response.
# Leave out system and tools: the thread keeps them.
curl -sS --fail-with-body 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,
    "cache_control": {"type": "ephemeral"},
    "messages": [{"role": "user", "content": "How long does standard shipping usually take?"}],
    "thread": {"type": "continue", "previous_message_id": "'"$message_id"'"}
  }'

Python (beta Messages create)

python
client = anthropic.Anthropic()

# Turn 1: send the full conversation and create a thread
first = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},
    system="You are a support agent for Acme. Keep replies short.",
    messages=[{"role": "user", "content": "Hi! I have a question about an order."}],
    thread={"type": "create"},
    betas=["message-threads-2026-08-12"],
)

# Turn 2: send only the new message and the id of the turn 1 response.
# Leave out system and tools: the thread keeps them.
second = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},
    messages=[
        {"role": "user", "content": "How long does standard shipping usually take?"}
    ],
    thread={"type": "continue", "previous_message_id": first.id},
    betas=["message-threads-2026-08-12"],
)

for block in second.content:
    if block.type == "text":
        print(block.text)

Use the Anthropic Python SDK’s beta Messages path as documented on the same page. This guide does not pin a minimum SDK version beyond “follow the current docs.”

Time-to-first-token claim (vendor conditions)

Anthropic’s product article states: with message threads on by default for most Claude Code users, requests with 500k to 1M tokens see median TTFT drop by about 35%. The same article notes that token usage stays the same. Treat that as a vendor claim under those conditions—not a promise of lower spend, and not a guarantee for every workload.

If you are debugging Messages API request fields more broadly, Claude API temperature 400 errors on the 2026-10-21 version covers a different 400 class (temperature / API version), not threads. For list prices and limits, Claude API pricing (October 2026) is a separate snapshot; threads do not rewrite that price table.

Practical checklist

  1. Put message-threads-2026-08-12 on every create and continue.
  2. Create with full messages plus system / tools; save the response id.
  3. Continue with only new messages and previous_message_id; never resend system / tools on continue.
  4. Keep fixed fields identical across the thread.
  5. Persist the full conversation yourself; on 404, replay with a new create.
  6. Expect 5-minute idle expiry and deletion within an hour; there is no list/read/delete API.
  7. Do not mix threads with unsupported features such as Message Batches or token counting that includes thread.

Follow the live Claude Platform docs for any field added after this write-up. The beta header and create / continue shape above are the stable starting point for wiring long agent loops without re-uploading the entire history on every turn.