Follow Discord
Sweep 03 Nov 2026 · 22:27Z Build v2.1.318 536 read Stable v2.1.311 Latest v2.1.318 Next v2.1.318 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One capture · api

One read of Claude Developer Platformapi-20261102T190719Z

6 pages moved out of 846 read.

Pages moved 6 significant first
Pages read 846 in this capture
Captured 19:07 UTC
Corpus hash e0e421ad6ef9 corpus-hash

What this read moved

1-6 of 6

build-with-claude/message-threads New page · 852 lines, new page

## How message threads work ## Use a thread with an SDK ## Send the `thread` field yourself ## What to send on each request ## Prompt caching on a thread ## Streaming ## Recover when a thread can’t be continued ### After a refusal ### Use fallbacks with a thread ## Compact a conversation ## How the SDK helper behaves ### Other helper methods ## Errors ## Features that threads don’t support ## Limitations ## Pricing and rate limits ## Data retention ## See also ## Availability ### API support #### [Messages API](https://platform.claude.com/docs/en/build-with-claude/working-with-messages) ### Required beta headers ### Data handling

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: Message threads
url: https://platform.claude.com/docs/en/build-with-claude/message-threads
description: Give long-running agents a faster time to first token, especially in long conversations, by sending only the new messages on each request.
featureMetadata:
  status: beta
  betaHeader: message-threads-2026-08-12
  zdr:
    eligibility: not-eligible
    note: A thread's contents (the conversation, system prompt, and tools) are held in memory, encrypted under a server-managed key, never written to durable storage, and deleted no more than 1 hour after the thread's last use. Using this feature does not affect your use of other ZDR eligible features.
  supportedModels:
    - claude-fable-5-1
    - claude-mythos-5-1
    - claude-fable-5
    - claude-mythos-5
    - claude-mythos-preview
    - claude-opus-5-5
    - claude-opus-5
    - claude-sonnet-5-5
    - claude-sonnet-5
    - claude-haiku-5-5
    - claude-haiku-4-5-20251001
    - claude-opus-4-8
    - claude-opus-4-7
    - claude-opus-4-6
    - claude-sonnet-4-6
    - claude-opus-4-5-20251101
    - claude-sonnet-4-5-20250929
  supportedPlatforms:
    Claude API: beta
    Claude Platform on AWS: beta
    Claude Models on Google Cloud (Anthropic managed): beta
    Microsoft Foundry: beta
---

With a message thread, requests are smaller, and time to first token stays lower and steadier as the conversation grows. Threads help most in long agent loops. Without a thread, every turn uploads the whole conversation again, and the API validates and tokenizes all of it again. With a thread, most of that work covers only the new turn.

A message thread keeps a conversation on the server for a short time. You send the full conversation once, with your system prompt and tools. On each later turn, you send only the new messages and the `id` of the previous response. The API rebuilds the conversation before it calls the model. You add one parameter, `thread`, to a [Messages API](https://platform.claude.com/docs/en/api/messages) request. The response is the usual message.

<Note>
  Message threads are different from [session threads](https://platform.claude.com/docs/en/managed-agents/session-threads) in Claude Managed Agents.
</Note>

## How message threads work

* **Create.** Send your first request as you do today, with the full conversation, `system`, and `tools`, and add `"thread": {"type": "create"}`. The API stores the conversation, including Claude’s reply, under the response `id`.
* **Continue.** Send only the messages since the previous response, and add `"thread": {"type": "continue", "previous_message_id": "<previous id>"}`. Leave `system` and `tools` out of the request. The thread keeps the values from the create request. Use each new response `id` for the next turn.
* **Replay.** A thread is best-effort. It expires 5 minutes after its last request, and the API deletes it no more than 1 hour after its last use. Each response that the API stores restarts the 5 minutes. If the API can no longer continue the thread, a continue request returns a 404 error. Send the full conversation again in a new create request, and continue from that response’s `id`. The SDK thread helper does this replay for you (see [How the SDK helper behaves](https://platform.claude.com/docs/en/build-with-claude/message-threads#sdk-helper-handles)). After a response from a fallback model, see [Use fallbacks with a thread](https://platform.claude.com/docs/en/build-with-claude/message-threads#fallbacks).

Your application stays the source of truth for the conversation. Keep your own copy of every message, and build the [replay path](https://platform.claude.com/docs/en/build-with-claude/message-threads#recover) from the start. No response, to a create or a continue request, says whether the API stored that turn. You find out on the next continue request. The SDK thread helper keeps this copy in memory while the helper object exists, and saves it nowhere else. If the conversation has to outlive your process, keep your own copy.

## Use a thread with an SDK

The SDK has a thread helper that builds the thread requests for you. Create it with the same fields as a Messages request, then send it one turn at a time. The helper keeps the full conversation in memory.

This example has two turns. The helper creates a thread on the first turn and continues it on the second, and it adds the beta header for you. The top-level `cache_control` is optional. It asks for prompt caching on each turn (see [Prompt caching on a thread](https://platform.claude.com/docs/en/build-with-claude/message-threads#prompt-caching)). Without it, each later turn still sends only the new messages, but nothing is cached unless you add cache breakpoints yourself.

<CodeGroup exclude="shell">
  ```python Python
  client = anthropic.Anthropic()

  # Create the helper. This call sends no request.
  thread = client.beta.messages.thread(
      model="claude-opus-5-5",
      max_tokens=1024,
      cache_control={"type": "ephemeral"},
      system="You are a support agent for Acme. Keep replies short.",
  )

  # Turn 1: the helper creates a thread and sends the full conversation
  thread.send({"role": "user", "content": "Hi! I have a question about an order."})

  # Turn 2: the helper continues the thread and sends only the new message
  second = thread.send(
      {"role": "user", "content": "How long does standard shipping usually take?"}
  )

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

  ```typescript TypeScript
  const client = new Anthropic();

  // Create the helper. This call sends no request.
  const thread = client.beta.messages.thread({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    cache_control: { type: "ephemeral" },
    system: "You are a support agent for Acme. Keep replies short."
  });

  // Turn 1: the helper creates a thread and sends the full conversation
  await thread.send({ role: "user", content: "Hi! I have a question about an order." });

  // Turn 2: the helper continues the thread and sends only the new message
  const second = await thread.send({
    role: "user",
    content: "How long does standard shipping usually take?"
  });

  for (const block of second.content) {
    if (block.type === "text") {
      console.log(block.text);
    }
  }
  ```

  ```csharp C#
  using Anthropic.Helpers.Beta;

  AnthropicClient client = new();

  // Create the helper. This call sends no request.
  var thread = client.Beta.Messages.Thread(
      new ThreadCreateParams
      {
          Model = Messages::Model.ClaudeOpus5_5,
          MaxTokens = 1024,
          Messages = [],
          CacheControl = new(),
          System = "You are a support agent for Acme. Keep replies short.",
      }
  );

  // Turn 1: the helper creates a thread and sends the full conversation
  await thread.Send(
      new BetaUserMessageParam { Content = "Hi! I have a question about an order." }
  );

  // Turn 2: the helper continues the thread and sends only the new message
  var second = await thread.Send(
      new BetaUserMessageParam { Content = "How long does standard shipping usually take?" }
  );

  foreach (var block in second.Content)
  {
      if (block.TryPickText(out var textBlock))
      {
          Console.WriteLine(textBlock.Text);
      }
  }
  ```

  ```go Go
  client := anthropic.NewClient()
  ctx := context.Background()

  // Create the helper. This call sends no request.
  thread := client.Beta.Messages.NewThread(anthropic.BetaMessageThreadCreateParams{
  	Model:        anthropic.ModelClaudeOpus5_5,
  	MaxTokens:    1024,
  	CacheControl: anthropic.NewBetaCacheControlEphemeralParam(),
  	System: []anthropic.BetaTextBlockParam{
  		{Text: "You are a support agent for Acme. Keep replies short."},
  	},
  })

  // Turn 1: the helper creates a thread and sends the full conversation
  _, err := thread.Send(ctx, anthropic.BetaMessageThreadSendParams{
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hi! I have a question about an order.")),
  	},
  })
  if err != nil {
  	panic(err)
  }

  // Turn 2: the helper continues the thread and sends only the new message
  second, err := thread.Send(ctx, anthropic.BetaMessageThreadSendParams{
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("How long does standard shipping usually take?")),
  	},
  })
  if err != nil {
  	panic(err)
  }

  for _, block := range second.Content {
  	if textBlock, ok := block.AsAny().(anthropic.BetaTextBlock); ok {
  		fmt.Println(textBlock.Text)
  	}
  }
  ```

  ```java Java
  var client = AnthropicOkHttpClient.fromEnv();

  // Create the helper. This call sends no request.
  var thread = client.beta().messages().thread(
      ThreadCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024)
          .cacheControl(BetaCacheControlEphemeral.builder().build())
          .system("You are a support agent for Acme. Keep replies short.")
          .build()
  );

  // Turn 1: the helper creates a thread and sends the full conversation
  thread.send("Hi! I have a question about an order.");

  // Turn 2: the helper continues the thread and sends only the new message
  var second = thread.send("How long does standard shipping usually take?");

  second.content().stream()
      .flatMap(block -> block.text().stream())
      .forEach(textBlock -> IO.println(textBlock.text()));
  ```

  ```php PHP
  $client = new Client();

  // Create the helper. This call sends no request.
  $thread = $client->beta->messages->thread(
      maxTokens: 1024,
      model: Model::CLAUDE_OPUS_5_5,
      cacheControl: new BetaCacheControlEphemeral,
      system: 'You are a support agent for Acme. Keep replies short.',
  );

  // Turn 1: the helper creates a thread and sends the full conversation
  $thread->send(['role' => 'user', 'content' => 'Hi! I have a question about an order.']);

  // Turn 2: the helper continues the thread and sends only the new message
  $second = $thread->send(['role' => 'user', 'content' => 'How long does standard shipping usually take?']);

  foreach ($second->content as $block) {
      if ($block instanceof BetaTextBlock) {
          echo $block->text, PHP_EOL;
      }
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  # Create the helper. This call sends no request.
  thread = client.beta.messages.thread(
    model: :"claude-opus-5-5",
    max_tokens: 1024,
    cache_control: {type: "ephemeral"},
    system_: "You are a support agent for Acme. Keep replies short."
  )

  # Turn 1: the helper creates a thread and sends the full conversation
  thread.send_message({role: "user", content: "Hi! I have a question about an order."})

  # Turn 2: the helper continues the thread and sends only the new message
  second = thread.send_message({role: "user", content: "How long does standard shipping usually take?"})

  second.content.each do |block|
    puts block.text if block.type == :text
  end
  ```
</CodeGroup>

## Send the `thread` field yourself

To build thread requests yourself, for example with cURL, the CLI, or an SDK’s usual `create` method, add the `thread` field to each request.

Send the `message-threads-2026-08-12` beta header on every request of a thread.

This example creates a thread on the first turn and continues it on the second. The top-level `cache_control` asks for prompt caching on each turn. It takes effect once the conversation is longer than the [minimum cacheable length](https://platform.claude.com/docs/en/build-with-claude/prompt-caching).

<CodeGroup>
  ```bash cURL
  # 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: 2023-06-01" \
    -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: 2023-06-01" \
    -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"'"}
    }'
  ```

  ```bash CLI
  # Turn 1: send the full conversation and create a thread

Cut at 300 lines. The page has the rest.

manage-claude/api-and-data-retention Changed · +10 / -9 lines

from line 202
202202 
203203### Messages API features
204204 
205| Feature | Endpoint | ZDR eligible | HIPAA eligible | Details |
206| :----------------------------------------------------------------------------------------------------------------------- | :---------------------------------------- | :----------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- |
207| [Bash tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/bash-tool) | `/v1/messages` with `bash` tool | Yes | Yes | Client-side tool run in your environment. |
208| [Code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool) | `/v1/messages` with `code_execution` tool | No | No | Container data retained up to 30 days. [Learn more](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#data-retention) |
209| [Context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing) | `/v1/messages` with `context_management` | Yes | No | Context edits (tool use clearing and thinking clearing) are applied in real time. |
210| [Fine-grained tool streaming](https://platform.claude.com/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming) | `/v1/messages` | Yes | Yes | |
211| [Memory tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool) | `/v1/messages` with `memory` tool | Yes | Yes | Client-side memory storage where you control data retention. |
212| [Messages API](https://platform.claude.com/docs/en/build-with-claude/working-with-messages) | `/v1/messages` | Yes | Yes | Standard API calls for generating Claude responses. |
213| [Text editor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/text-editor-tool) | `/v1/messages` with `text_editor` tool | Yes | Yes | Client-side tool run in your environment. |
205| Feature | Endpoint | ZDR eligible | HIPAA eligible | Details |
206| :----------------------------------------------------------------------------------------------------------------------- | :---------------------------------------- | :----------- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
207| [Bash tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/bash-tool) | `/v1/messages` with `bash` tool | Yes | Yes | Client-side tool run in your environment. |
208| [Code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool) | `/v1/messages` with `code_execution` tool | No | No | Container data retained up to 30 days. [Learn more](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#data-retention) |
209| [Context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing) | `/v1/messages` with `context_management` | Yes | No | Context edits (tool use clearing and thinking clearing) are applied in real time. |
210| [Fine-grained tool streaming](https://platform.claude.com/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming) | `/v1/messages` | Yes | Yes | |
211| [Memory tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool) | `/v1/messages` with `memory` tool | Yes | Yes | Client-side memory storage where you control data retention. |
212| [Message threads](https://platform.claude.com/docs/en/build-with-claude/message-threads) | `/v1/messages` with `thread` | No | No | A thread’s contents (the conversation, system prompt, and tools) are held in memory, encrypted under a server-managed key, never written to durable storage, and deleted no more than 1 hour after the thread’s last use. Using this feature does not affect your use of other ZDR eligible features. [Learn more](https://platform.claude.com/docs/en/build-with-claude/message-threads#data-retention) |
213| [Messages API](https://platform.claude.com/docs/en/build-with-claude/working-with-messages) | `/v1/messages` | Yes | Yes | Standard API calls for generating Claude responses. |
214| [Text editor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/text-editor-tool) | `/v1/messages` with `text_editor` tool | Yes | Yes | Client-side tool run in your environment. |
214215 
215216### Managed Agents features
216217 

release-notes/overview Changed · +4 / -0 lines

### November 2, 2026

from line 12
1212 For updates to Claude Code, see the [complete CHANGELOG.md](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md) in the `claude-code` repository.
1313</Tip>
1414 
15### November 2, 2026
16 
17* Long conversations and agent loops on the Messages API can now send smaller requests and get a lower time to first token with [message threads](https://platform.claude.com/docs/en/build-with-claude/message-threads), in beta with the `message-threads-2026-08-12` beta header. The API keeps the conversation on the server, so each later request sends only the new messages. A thread expires 5 minutes after its last request and is deleted no more than 1 hour after its last use. Message threads are available on the Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), Claude Models on Google Cloud (Anthropic managed), and [Claude in Microsoft Foundry](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry).
18 
1519### October 30, 2026
1620 
1721* We’ve deprecated [fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode) for Claude Opus 4.8, with removal on November 30, 2026. After removal, requests to `claude-opus-4-8` with `speed: "fast"` will return an error. To continue using fast mode, migrate to [Claude Opus 5.5](https://platform.claude.com/docs/en/models/opus-5-5/migration-guide#migrating-from-claude-opus-4-8). Read more in [Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode#supported-models).

build-with-claude/overview Changed · +1 / -0 lines

from line 89
8989| ↳ [Memory tool helpers](https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool#implement-the-memory-handler) | SDK helpers that handle the memory tool’s interface and tool-use loop, so your code supplies only the storage. |
9090| [Message streaming](https://platform.claude.com/docs/en/build-with-claude/streaming) | Receiving a Messages API response incrementally, as server-sent events, while it is generated. |
9191| ↳ [Fine-grained tool streaming](https://platform.claude.com/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming) | Streams a tool’s input to your client as Claude writes it, without the server first buffering and checking the JSON. |
92| [Message threads](https://platform.claude.com/docs/en/build-with-claude/message-threads) | Give long-running agents a faster time to first token, especially in long conversations, by sending only the new messages on each request. |
9293| [On-demand compaction](https://platform.claude.com/docs/en/build-with-claude/compaction-on-demand) | Replaces the earlier messages of a conversation with a summary that Claude writes when your application asks for it. |
9394| ↳ [Background compaction](https://platform.claude.com/docs/en/build-with-claude/compaction-background) | Runs the on-demand compaction request while the conversation continues on its full history, then swaps in the summary when it arrives. |
9495| ↳ [Compaction and preserved thinking](https://platform.claude.com/docs/en/build-with-claude/compaction-thinking-blocks) | Thinking blocks in the turns you keep after on-demand compaction can stay valid, under stated conditions, on models with preserved thinking. |

build-with-claude/working-with-messages Changed · +2 / -0 lines

from line 187
187187 
188188The Messages API is stateless, which means that you always send the full conversational history to the API. You can use this pattern to build up a conversation over time. Earlier conversational turns don’t necessarily need to actually originate from Claude. You can use synthetic `assistant` messages.
189189 
190With [message threads](https://platform.claude.com/docs/en/build-with-claude/message-threads), in beta, the API can keep the conversation for a few minutes, so that each later request sends only the new messages.
191 
190192<CodeGroup>
191193 ```bash cURL
192194 #!/bin/sh

claude_api_primer Changed · +2 / -0 lines

from line 69
6969 
7070The Messages API is stateless, which means that you always send the full conversational history to the API. You can use this pattern to build up a conversation over time. Earlier conversational turns don’t necessarily need to actually originate from Claude. You can use synthetic `assistant` messages.
7171 
72With [message threads](https://platform.claude.com/docs/en/build-with-claude/message-threads), in beta, the API can keep the conversation for a few minutes, so that each later request sends only the new messages.
73 
7274<CodeGroup exclude="shell:cURL, typescript, csharp, go, java, php, ruby">
7375 ```bash CLI
7476 ant messages create <<'YAML'
Feedback