---
title: Nachrichten-Threads
url: https://platform.claude.com/docs/de/build-with-claude/message-threads
description: Verkürze bei lang laufenden Agenten die Zeit bis zum ersten Token, insbesondere in langen Konversationen, indem du bei jeder Anfrage nur die neuen Nachrichten sendest.
featureMetadata:
  status: beta
  betaHeader: message-threads-2026-08-12
  zdr:
    eligibility: not-eligible
    note: Die Inhalte eines Threads (die Unterhaltung, der System-Prompt und die Tools) werden im Arbeitsspeicher gehalten, mit einem serververwalteten Schlüssel verschlüsselt, nie in einen dauerhaften Speicher geschrieben und spätestens 1 Stunde nach der letzten Verwendung des Threads gelöscht. Die Nutzung dieser Funktion beeinträchtigt nicht deine Nutzung anderer für ZDR berechtigter Funktionen.
  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
---

Mit einem „message thread“ (Nachrichten-Thread) sind Anfragen kleiner, und die „time to first token“ (Zeit bis zum ersten Token) bleibt niedriger und stabiler, während die Konversation wächst. Threads helfen am meisten in langen Agent-Schleifen. Ohne Thread lädt jeder Turn die gesamte Konversation erneut hoch, und die API validiert und tokenisiert alles erneut. Mit einem Thread betrifft der Großteil dieser Arbeit nur den neuen Turn.

Ein „message thread“ (Nachrichten-Thread) hält eine Konversation für kurze Zeit auf dem Server. Du sendest die vollständige Konversation einmal, zusammen mit deinem „system prompt“ (System-Prompt) und deinen Tools. Bei jedem späteren Turn sendest du nur die neuen Nachrichten und die `id` der vorherigen Antwort. Die API baut die Konversation neu auf, bevor sie das Modell aufruft. Du fügst einer [Messages API](https://platform.claude.com/docs/de/api/messages)-Anfrage einen Parameter hinzu, `thread`. Die Antwort ist die übliche Nachricht.

<Note>
  Nachrichten-Threads unterscheiden sich von [Session-Threads](https://platform.claude.com/docs/de/managed-agents/session-threads) in Claude Managed Agents.
</Note>

## Wie Nachrichten-Threads funktionieren

* **Erstellen.** Sende deine erste Anfrage wie bisher, mit der vollständigen Konversation, `system` und `tools`, und füge `"thread": {"type": "create"}` hinzu. Die API speichert die Konversation, einschließlich Claudes Antwort, unter der `id` der Antwort.
* **Fortsetzen.** Sende nur die Nachrichten seit der vorherigen Antwort und füge `"thread": {"type": "continue", "previous_message_id": "<previous id>"}` hinzu. Lass `system` und `tools` in der Anfrage weg. Der Thread behält die Werte aus der Create-Anfrage. Verwende jede neue `id` einer Antwort für den nächsten Turn.
* **Erneut senden.** Ein Thread ist Best-Effort. Er läuft 5 Minuten nach seiner letzten Anfrage ab, und die API löscht ihn spätestens 1 Stunde nach seiner letzten Verwendung. Jede Antwort, die die API speichert, startet die 5 Minuten neu. Wenn die API den Thread nicht mehr fortsetzen kann, gibt eine Continue-Anfrage einen 404-Fehler zurück. Sende die vollständige Konversation erneut in einer neuen Create-Anfrage und setze ab der `id` dieser Antwort fort. Der Thread-Helper des SDK übernimmt dieses erneute Senden für dich (siehe [Verhalten des SDK-Helpers](https://platform.claude.com/docs/de/build-with-claude/message-threads#sdk-helper-handles)). Nach einer Antwort von einem Fallback-Modell siehe [Fallbacks mit einem Thread verwenden](https://platform.claude.com/docs/de/build-with-claude/message-threads#fallbacks).

Deine Anwendung bleibt die maßgebliche Quelle („source of truth“) für die Konversation. Bewahre deine eigene Kopie jeder Nachricht auf und baue den [Replay-Pfad](https://platform.claude.com/docs/de/build-with-claude/message-threads#recover) von Anfang an. Keine Antwort, weder auf eine Create- noch auf eine Continue-Anfrage, gibt an, ob die API diesen Turn gespeichert hat. Das erfährst du erst bei der nächsten Continue-Anfrage. Der Thread-Helper des SDK hält diese Kopie im Speicher, solange das Helper-Objekt existiert, und speichert sie nirgendwo sonst. Wenn die Konversation deinen Prozess überdauern muss, bewahre deine eigene Kopie auf.

## Einen Thread mit einem SDK verwenden

Das SDK hat einen Thread-Helper, der die Thread-Anfragen für dich erstellt. Erstelle ihn mit denselben Feldern wie eine Messages-Anfrage und sende ihm dann einen Turn nach dem anderen. Der Helper hält die vollständige Konversation im Speicher.

Dieses Beispiel hat zwei Turns. Der Helper erstellt beim ersten Turn einen Thread und setzt ihn beim zweiten fort, und er fügt den Beta-Header für dich hinzu. Das `cache_control` auf oberster Ebene ist optional. Es fordert bei jedem Turn „prompt caching“ (Prompt-Caching) an (siehe [Prompt-Caching in einem Thread](https://platform.claude.com/docs/de/build-with-claude/message-threads#prompt-caching)). Ohne es sendet jeder spätere Turn trotzdem nur die neuen Nachrichten, aber nichts wird gecacht, es sei denn, du fügst selbst Cache-Breakpoints hinzu.

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

  # Erstelle den Helper. Dieser Aufruf sendet keine Anfrage.
  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: Der Helper erstellt einen Thread und sendet die gesamte Konversation
  thread.send({"role": "user", "content": "Hi! I have a question about an order."})

  # Turn 2: Der Helper setzt den Thread fort und sendet nur die neue Nachricht
  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();

  // Erstelle den Helper. Dieser Aufruf sendet keine Anfrage.
  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: Der Helper erstellt einen Thread und sendet die gesamte Konversation
  await thread.send({ role: "user", content: "Hi! I have a question about an order." });

  // Turn 2: Der Helper setzt den Thread fort und sendet nur die neue Nachricht
  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();

  // Erstelle den Helper. Dieser Aufruf sendet keine Anfrage.
  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: Der Helper erstellt einen Thread und sendet die gesamte Konversation
  await thread.Send(
      new BetaUserMessageParam { Content = "Hi! I have a question about an order." }
  );

  // Turn 2: Der Helper setzt den Thread fort und sendet nur die neue Nachricht
  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()

  // Erstelle den Helper. Dieser Aufruf sendet keine Anfrage.
  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: Der Helper erstellt einen Thread und sendet die gesamte Konversation
  _, 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: Der Helper setzt den Thread fort und sendet nur die neue Nachricht
  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();

  // Erstelle den Helper. Dieser Aufruf sendet keine Anfrage.
  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: Der Helper erstellt einen Thread und sendet die gesamte Konversation
  thread.send("Hi! I have a question about an order.");

  // Turn 2: Der Helper setzt den Thread fort und sendet nur die neue Nachricht
  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();

  // Erstelle den Helper. Dieser Aufruf sendet keine Anfrage.
  $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.',
  );

  // Runde 1: Der Helper erstellt einen Thread und sendet die gesamte Konversation
  $thread->send(['role' => 'user', 'content' => 'Hi! I have a question about an order.']);

  // Runde 2: Der Helper setzt den Thread fort und sendet nur die neue Nachricht
  $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

  # Erstelle den Helper. Dieser Aufruf sendet keine Anfrage.
  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: Der Helper erstellt einen Thread und sendet die gesamte Konversation
  thread.send_message({role: "user", content: "Hi! I have a question about an order."})

  # Turn 2: Der Helper setzt den Thread fort und sendet nur die neue Nachricht
  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>

## Das `thread`-Feld selbst senden

Um Thread-Anfragen selbst zu erstellen, zum Beispiel mit cURL, der CLI oder der üblichen `create`-Methode eines SDK, füge jeder Anfrage das `thread`-Feld hinzu.

Sende den Beta-Header `message-threads-2026-08-12` bei jeder Anfrage eines Threads.

Dieses Beispiel erstellt beim ersten Turn einen Thread und setzt ihn beim zweiten fort. Das `cache_control` auf oberster Ebene fordert bei jedem Turn Prompt-Caching an. Es wird wirksam, sobald die Konversation länger als die [minimale cachebare Länge](https://platform.claude.com/docs/de/build-with-claude/prompt-caching) ist.

<CodeGroup>
  ```bash cURL
  # Turn 1: Sende die vollständige Konversation und erstelle einen 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: Sende nur die neue Nachricht. Setze message_id auf die id der Antwort aus Turn 1.
  # Lass system und tools weg: Der Thread behält sie bei.
  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: Sende die vollständige Konversation und erstelle einen Thread
  ant beta:messages create --beta message-threads-2026-08-12 <<'YAML'
  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
  YAML

  # Turn 2: Sende nur die neue Nachricht. Setze message_id auf die id der Antwort aus Turn 1.
  # Lass system und tools weg: Der Thread behält sie bei.
  ant beta:messages create --beta message-threads-2026-08-12 <<YAML
  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
  YAML
  ```

  ```python Python
  client = anthropic.Anthropic()

  # Turn 1: Sende die vollständige Konversation und erstelle einen 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: Sende nur die neue Nachricht und die ID der Antwort aus Turn 1.
  # Lass system und tools weg: Der Thread behält sie bei.
  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)
  ```

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

  // Turn 1: Sende die vollständige Konversation und erstelle einen Thread
  const first = await 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: Sende nur die neue Nachricht und die ID der Antwort aus Turn 1.
  // Lass system und tools weg: Der Thread behält sie bei.
  const second = await 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 (const block of second.content) {
    if (block.type === "text") {
      console.log(block.text);
    }
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  // Turn 1: Sende die vollständige Konversation und erstelle einen Thread
  var first = await client.Beta.Messages.Create(
      new()
      {
          Model = Messages::Model.ClaudeOpus5_5,
          MaxTokens = 1024,
          CacheControl = new(),
          System = "You are a support agent for Acme. Keep replies short.",
          Messages =
          [
              new BetaUserMessageParam { Content = "Hi! I have a question about an order." },
          ],
          Thread = new BetaThreadCreateParams(),
          Betas = [AnthropicBeta.MessageThreads2026_08_12],
      }
  );

  // Turn 2: Sende nur die neue Nachricht und die ID der Antwort aus Turn 1.
  // Lass System und Tools weg: Der Thread behält sie bei.
  var second = await client.Beta.Messages.Create(
      new()
      {
          Model = Messages::Model.ClaudeOpus5_5,
          MaxTokens = 1024,
          CacheControl = new(),
          Messages =
          [
              new BetaUserMessageParam { Content = "How long does standard shipping usually take?" },
          ],
          Thread = new BetaThreadContinueParams(first.ID),
          Betas = [AnthropicBeta.MessageThreads2026_08_12],
      }
  );

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

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

  // Turn 1: Sende die vollständige Konversation und erstelle einen Thread
  threadCreate := anthropic.NewBetaThreadCreateParams()
  first, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:        anthropic.ModelClaudeOpus5_5,
  	MaxTokens:    1024,
  	CacheControl: anthropic.NewBetaCacheControlEphemeralParam(),
  	System: []anthropic.BetaTextBlockParam{
  		{Text: "You are a support agent for Acme. Keep replies short."},
  	},
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hi! I have a question about an order.")),
  	},
  	Thread: anthropic.BetaMessageThreadParamUnion{OfCreate: &threadCreate},
  	Betas:  []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageThreads2026_08_12},
  })
  if err != nil {
  	panic(err)
  }

  // Turn 2: Sende nur die neue Nachricht und die ID der Antwort aus Turn 1.
  // Lass System und Tools weg: Der Thread behält sie bei.
  second, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:        anthropic.ModelClaudeOpus5_5,
  	MaxTokens:    1024,
  	CacheControl: anthropic.NewBetaCacheControlEphemeralParam(),
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("How long does standard shipping usually take?")),
  	},
  	Thread: anthropic.BetaMessageThreadParamOfContinue(first.ID),
  	Betas:  []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageThreads2026_08_12},
  })
  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();

  // Turn 1: Sende die vollständige Konversation und erstelle einen Thread
  var first = client.beta().messages().create(
      MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024)
          .cacheControl(BetaCacheControlEphemeral.builder().build())
          .system("You are a support agent for Acme. Keep replies short.")
          .addUserMessage("Hi! I have a question about an order.")
          .thread(BetaThreadCreateParams.builder().build())
          .addBeta(AnthropicBeta.MESSAGE_THREADS_2026_08_12)
          .build()
  );

  // Turn 2: Sende nur die neue Nachricht und die ID der Antwort aus Turn 1.
  // Lass system und tools weg: Der Thread behält sie bei.
  var second = client.beta().messages().create(
      MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024)
          .cacheControl(BetaCacheControlEphemeral.builder().build())
          .addUserMessage("How long does standard shipping usually take?")
          .continueThread(first.id())
          .addBeta(AnthropicBeta.MESSAGE_THREADS_2026_08_12)
          .build()
  );

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

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

  // Turn 1: Sende die vollständige Konversation und erstelle einen Thread
  $first = $client->beta->messages->create(
      model: Model::CLAUDE_OPUS_5_5,
      maxTokens: 1024,
      cacheControl: new BetaCacheControlEphemeral,
      system: 'You are a support agent for Acme. Keep replies short.',
      messages: [
          ['role' => 'user', 'content' => 'Hi! I have a question about an order.'],
      ],
      thread: BetaThreadCreateParams::with(),
      betas: ['message-threads-2026-08-12'],
  );

  // Turn 2: Sende nur die neue Nachricht und die ID der Antwort aus Turn 1.
  // Lass system und tools weg: Der Thread behält sie bei.
  $second = $client->beta->messages->create(
      model: Model::CLAUDE_OPUS_5_5,
      maxTokens: 1024,
      cacheControl: new BetaCacheControlEphemeral,
      messages: [
          ['role' => 'user', 'content' => 'How long does standard shipping usually take?'],
      ],
      thread: BetaThreadContinueParams::with(previousMessageID: $first->id),
      betas: ['message-threads-2026-08-12'],
  );

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

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

  # Turn 1: Sende die vollständige Konversation und erstelle einen 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: Sende nur die neue Nachricht und die ID der Antwort aus Turn 1.
  # Lass system_ und tools weg: Der Thread behält sie bei.
  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"]
  )

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

## Was bei jeder Anfrage gesendet wird

| Gruppe         | Felder                                                                                                                                                                                                                                                   | Regel                                                                                                                                                                                                                                         |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Nur bei Create | `system`, `tools`                                                                                                                                                                                                                                        | Sende sie nur bei der Create-Anfrage, mit allen `cache_control`-Breakpoints darauf. Wenn du eines davon bei einer Continue-Anfrage sendest, selbst als `null`, wird ein 400-Fehler zurückgegeben.                                             |
| Fest           | `model`, `tool_choice`, `thinking`, `mcp_servers` (abgesehen vom Autorisierungstoken jedes Servers), `context_management`, `output_config`, die `skills` in `container`, das `cache_control` auf oberster Ebene und die Menge der `anthropic-beta`-Werte | Sende sie bei jeder Anfrage des Threads, mit denselben Werten wie bei der Create-Anfrage. Ein abweichender Wert gibt einen 400-Fehler mit dem Code `thread_fingerprint_mismatch` zurück, und die Fehlermeldung nennt die abweichenden Felder. |
| Frei           | `max_tokens`, `stop_sequences`, `stream`, `metadata`, `service_tier` und andere Felder, die auf dieser Seite nicht genannt werden                                                                                                                        | Diese können sich von Turn zu Turn ändern.                                                                                                                                                                                                    |

Die API speichert keine MCP-Server-URLs, keine MCP-Autorisierungstoken und nicht die Container-`id`. Sende `mcp_servers` und `container` bei jeder Anfrage, die sie verwendet. Ein MCP-Autorisierungstoken kann sich zwischen Anfragen ändern.

Der Thread-Helper des SDK lässt `system` und `tools` für dich aus Continue-Anfragen weg und sendet die festen Felder bei jedem Turn erneut.

Wenn du [serverseitigen Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#server-side-fallback) verwendest, sende das `fallbacks`-Feld bei jeder Anfrage eines Threads oder bei keiner. Siehe [Fallbacks mit einem Thread verwenden](https://platform.claude.com/docs/de/build-with-claude/message-threads#fallbacks).

Um ein Nur-Create- oder festes Feld zu ändern, starte einen neuen Thread: Sende die vollständige Konversation in einer Create-Anfrage mit den neuen Werten.

Bei Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5.5, Claude Sonnet 5.5 und Claude Haiku 5.5 macht eine Änderung an `system` oder `tools` die bereits in der Konversation enthaltenen `thinking`- und `redacted_thinking`-Blöcke ungültig, und die Create-Anfrage kann einen 400-Fehler zurückgeben. Um das zu vermeiden, lass jeden `thinking`- und `redacted_thinking`-Block aus der Konversation weg, die du sendest. Das Modell antwortet dann ohne diese früheren Überlegungen. Siehe [Was als Bearbeitung zählt](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#what-counts-as-an-edit), [Wenn `prefix_mismatch_behavior` nicht gesetzt ist](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#enforcement) und [Was die API mit einem ungültigen Block macht](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#mismatch-behavior).

Sende bei einer Continue-Anfrage nur die neuen Nachrichten. Die API gleicht sie nicht mit den Nachrichten ab, die sie bereits hat. Eine Nachricht, die du erneut sendest, kann doppelt in der Konversation erscheinen, oder die Anfrage kann einen Fehler zurückgeben. Zum Beispiel gibt eine Continue-Anfrage, die mit der vorherigen Antwort beginnt, einen Fehler zurück.

Die neuen Nachrichten beginnen normalerweise mit einer `user`-Nachricht: deinem nächsten User-Turn oder den `tool_result`-Blöcken, die einen `tool_use` in der vorherigen Antwort beantworten. Wenn eine Antwort mit [`stop_reason: "pause_turn"`](https://platform.claude.com/docs/de/build-with-claude/handling-stop-reasons#pause-turn) stoppt, setze sie mit einer Continue-Anfrage ab der `id` dieser Antwort und einer leeren `messages`-Liste (`"messages": []`) fort. Wenn diese Anfrage einen 404-Fehler zurückgibt, sende die vollständige Konversation, einschließlich der pausierten Antwort, erneut in einer neuen Create-Anfrage. Sende keine neue `user`-Nachricht, während der Turn pausiert ist: Die API lehnt sie ab. Rufe mit dem Thread-Helper des SDK `send()` (go, csharp: `Send()`; ruby: `send_message()`) ohne Nachrichten auf: Der Helper sendet diese Anfrage und sendet bei einem 404-Fehler erneut.

Ein Thread ist nur erweiterbar (append-only), und jede Antwort-`id` kann einmal fortgesetzt werden. Setze immer von der neuesten Antwort-`id` des Threads aus fort. Um eine frühere Nachricht zu bearbeiten oder abzuzweigen, starte einen neuen Thread mit einer Create-Anfrage. Um frühere Turns durch eine Zusammenfassung zu ersetzen, siehe [Eine Konversation komprimieren](https://platform.claude.com/docs/de/build-with-claude/message-threads#compaction).

## Prompt-Caching in einem Thread

Ein Thread cacht deinen Prompt nicht für dich. [Prompt-Caching](https://platform.claude.com/docs/de/build-with-claude/prompt-caching) funktioniert wie ohne Thread: Du wählst, wo die Cache-Breakpoints platziert werden.

Um jeden Turn zu cachen, sende bei jeder Anfrage des Threads ein `cache_control` auf oberster Ebene, wie im vorherigen Beispiel. Die API wendet es auf den letzten cachebaren Block der `messages` jeder Anfrage an. Jeder Turn liest dann die frühere Konversation aus dem Cache und schreibt den neuen Turn hinein. Das `cache_control` auf oberster Ebene ist ein festes Feld: Sende bei jeder Anfrage denselben Wert.

Du kannst `cache_control`-Breakpoints auch selbst auf Blöcken platzieren:

* Breakpoints, die du bei der Create-Anfrage sendest, funktionieren bei jedem späteren Turn weiter, wenn sie auf `tools`, auf `system` oder auf einem Nachrichtenblock vor dem letzten liegen. Ein Breakpoint auf dem letzten Block der `messages` einer Anfrage schreibt den Cache bei dieser Anfrage. Um jeden neuen Turn zu cachen, sende bei jeder Anfrage einen Breakpoint. Eine Anfrage ohne Breakpoint kann trotzdem einen Teil der Konversation aus dem Cache lesen.
* Du kannst einen Breakpoint nicht verschieben oder entfernen, nachdem du ihn gesendet hast, da eine Continue-Anfrage eine frühere Nachricht nicht erneut senden kann.
* Eine Anfrage mit `thread` kann höchstens 4 `cache_control`-Breakpoints enthalten. Das `cache_control` auf oberster Ebene zählt als einer. Breakpoints auf `system` und `tools` der Create-Anfrage zählen bei jeder Continue-Anfrage erneut. Breakpoints auf früheren gespeicherten Nachrichten zählen nicht. Ein Breakpoint zu viel gibt einen 400-Fehler mit dem Code `thread_unsupported_request` zurück.
* Wenn du selbst Breakpoints auf Nachrichtenblöcke setzt, entferne sie aus früheren Nachrichten, wenn du die Konversation in einer neuen Create-Anfrage erneut abspielst, und behalte einen auf dem letzten Block, damit die Anfrage innerhalb des Limits von 4 bleibt.

## Streaming

Threads funktionieren mit [Streaming](https://platform.claude.com/docs/de/build-with-claude/streaming). Die Antwort-`id` kommt im `message_start`-Event an, aber setze erst von ihr aus fort, nachdem du das `message_stop`-Event erhalten hast. Eine früher gesendete Continue-Anfrage kann einen 404-Fehler zurückgeben.

Wenn der Stream einer Continue-Anfrage vor `message_stop` abbricht, sende dieselbe Continue-Anfrage erneut. Wenn diese Anfrage einen `thread_already_continued`- oder `thread_continue_in_flight`-Fehler zurückgibt, sende die vollständige Konversation erneut in einer neuen Create-Anfrage.

Deine Verbindung ist möglicherweise abgebrochen, während der Server die Antwort noch generierte, oder nachdem der Server sie gespeichert hatte. Deshalb kann die API die Wiederholung ablehnen. Erneutes Senden ist immer sicher.

Der Thread-Helper des SDK wiederholt die Continue-Anfrage nach einem abgebrochenen Stream nicht. Siehe [Verhalten des SDK-Helpers](https://platform.claude.com/docs/de/build-with-claude/message-threads#sdk-helper-handles).

## Wiederherstellen, wenn ein Thread nicht fortgesetzt werden kann

Eine Continue-Anfrage gibt einen 404-Fehler zurück, bei dem `error.details.error_code` auf `thread_not_found` gesetzt ist, wenn die API den Thread nicht fortsetzen kann. Die Antwort sagt nicht, warum. Zu den Ursachen gehören die folgenden:

* Der Thread ist abgelaufen.
* Die API hat den vorherigen Turn ausgeliefert, ihn aber nicht gespeichert. Zum Beispiel speichert die API keine Antwort, die mit einem durch `max_tokens` abgeschnittenen Tool-Aufruf endet.
* Ein Fallback-Modell hat die vorherige Antwort geschrieben. Siehe [Fallbacks mit einem Thread verwenden](https://platform.claude.com/docs/de/build-with-claude/message-threads#fallbacks).
* Die vorherige Antwort wird noch generiert.
* Die Anfrage stammt von einer anderen Organisation oder einem anderen Workspace.
* Die Anfrage stammt von einem anderen Benutzer oder Dienstkonto als dem, das den Thread erstellt hat. Ein Thread, der mit einem [Workspace-Key (veraltet)](https://platform.claude.com/docs/de/manage-claude/authentication#key-types) erstellt wurde, bleibt an diesen Key gebunden, also verwende denselben Key für den gesamten Thread.
* Die neuen Nachrichten fügen etwas hinzu, das die gespeicherte Konversation nicht aufnehmen kann. Zum Beispiel kann das erste Bild in einer Konversation, die bisher keines hatte, diesen Fehler zurückgeben.

Zur Wiederherstellung sende die vollständige Konversation aus deiner eigenen Kopie in einer neuen Create-Anfrage, mit `system` und `tools`. Der Thread-Helper des SDK sendet diese Create-Anfrage einmal von selbst und lässt dabei die `cache_control`-Breakpoints früherer Turns weg. Wenn frühere Nachrichten in deiner Kopie `cache_control`-Breakpoints enthalten, entferne sie zuerst (siehe [Prompt-Caching in einem Thread](https://platform.claude.com/docs/de/build-with-claude/message-threads#prompt-caching)). Setze dann ab der neuen Antwort-`id` fort. Wenn ein Fallback-Modell die vorherige Antwort geschrieben hat, siehe [Fallbacks mit einem Thread verwenden](https://platform.claude.com/docs/de/build-with-claude/message-threads#fallbacks). Um die Ursachen im Zusammenhang mit der Eigentümerschaft auszuschließen, verwende für jede Anfrage eines Threads denselben API-Key und denselben Workspace. Auf Claude Platform on AWS signiere jede Anfrage eines Threads mit Anmeldedaten für die IAM-Rolle oder den IAM-Benutzer, die bzw. der ihn erstellt hat.

Eine Anfrage für ein Modell, das nicht existiert, gibt ebenfalls einen 404-Fehler zurück, also prüfe `error.details.error_code`, bevor du erneut sendest.

Wenn eine Continue-Anfrage direkt nach deinem Replay weiterhin einen 404-Fehler zurückgibt, kann die API diese Konversation möglicherweise nicht speichern, zum Beispiel eine sehr große. Sende sie ohne `thread`. Der SDK-Thread-Helper tut dies, wenn du ihn mit `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`), gesetzt auf `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`), erstellst. Andernfalls führt er bei jedem Turn ein Replay durch.

### Nach einer Ablehnung

Wenn eine Antwort `stop_reason: "refusal"` enthält, setze den Thread nicht fort. Die API hält den abgelehnten Turn möglicherweise bereits, und eine Continue-Anfrage kann ihn nicht entfernen. Starte einen neuen Thread mit einer Create-Anfrage, die den Turn, der zur Ablehnung geführt hat, weglässt oder umformuliert. Siehe [Ablehnungen und Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback). Der SDK-Thread-Helper erledigt das für dich: Er behält den abgelehnten Turn nicht, und sein nächster Turn startet einen neuen Thread.

### Fallbacks mit einem Thread verwenden

[Serverseitiger Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#server-side-fallback) ist mit Threads auf der Claude API verfügbar. Entscheide beim Erstellen des Threads: Sende `fallbacks` bei jeder Anfrage des Threads oder bei keiner. Der Wert von `fallbacks` kann sich zwischen Anfragen ändern. Eine Continue-Anfrage, die `fallbacks` hinzufügt oder weglässt, gibt einen 400-Fehler mit dem Code `thread_fingerprint_mismatch` zurück.

Ein Thread behält ein Modell, daher speichert die API keinen Turn, den ein Fallback-Modell geschrieben hat. Du erhältst die Antwort wie gewohnt, kannst aber nicht von ihrer `id` aus fortsetzen. Befolge nach jeder Antwort diese Schritte:

1. Wenn `stop_reason` den Wert `"refusal"` hat, folge [Nach einer Ablehnung](https://platform.claude.com/docs/de/build-with-claude/message-threads#after-a-refusal).

2. Andernfalls suche nach einem `fallback_message`-Eintrag in `usage.iterations`. Bei einem Stream liest du ihn aus dem letzten `message_delta`-Event. Wenn es keinen gibt, setze den Thread wie üblich fort.

3. Wenn es einen gibt, hat ein Fallback-Modell die Antwort geschrieben. Sende die vollständige Konversation, einschließlich dieser Antwort und deiner nächsten Nachricht, in einer neuen Create-Anfrage. Behalte den Beta-Header `server-side-fallback-2026-07-01` darauf bei. Wähle eine dieser beiden Anfragen:

   * **Dieselbe Anfrage erneut.** Behalte `model`, `fallbacks` und deine anderen Parameter so bei, wie sie waren. Wenn das von dir angeforderte Modell antwortet, speichert die API den neuen Thread. Wenn ein Fallback-Modell antwortet, enthält die Antwort erneut einen `fallback_message`-Eintrag und die API speichert sie nicht, also wiederhole diesen Schritt beim nächsten Turn. [Sticky Routing](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#sticky-routing) könnte diese Anfragen direkt an das Fallback-Modell senden, sodass jeder Turn möglicherweise die vollständige Konversation sendet. Der Thread-Helper des SDK funktioniert auf diese Weise.
   * **Ein neuer Thread auf dem Fallback-Modell.** Setze `model` auf das `model` in diesem `fallback_message`-Eintrag, lass `fallbacks` weg und verwende Parameter, die dieses Modell akzeptiert. Die API speichert diesen Thread sofort, und er bleibt auf dem Fallback-Modell. Der Fallback-Versuch lief möglicherweise mit anderen Einstellungen als denen, die du gesendet hast, daher lehnt die API aus deiner ersten Anfrage kopierte Werte möglicherweise ab.

4. Kehre mit der Antwort auf diese Anfrage zu Schritt 1 zurück. Wenn sie keinen `fallback_message`-Eintrag hat, setze den neuen Thread ab ihrer `id` fort.

[Sticky Routing](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#sticky-routing) beginnt, nachdem eine Anfrage auf ein Fallback zurückgegriffen hat (eine Create-Anfrage oder eine Anfrage ohne `thread`). Für etwa eine Stunde könnte es spätere Create-Anfragen für dieselbe Konversation, die `fallbacks` enthalten, direkt an das Fallback-Modell senden, ohne das von dir angeforderte Modell zu versuchen. Die API speichert keinen dieser Turns, und jeder beantwortete Turn startet die Stunde neu. Eine Continue-Anfrage startet dieses Routing nie und verwendet es nie. Sticky Routing gilt nicht, wenn deine Organisation oder dein Workspace Zero Data Retention oder kundenverwaltete Verschlüsselungsschlüssel verwendet.

## Eine Konversation komprimieren

Ein Thread ist nur erweiterbar (append-only), daher kannst du seine früheren Turns nicht durch eine Zusammenfassung ersetzen. Um eine Konversation zu komprimieren, starte einen neuen Thread aus der Zusammenfassung. Schreibe die Zusammenfassung in deinem Code und sende sie als gewöhnliche Nachricht in einer neuen Create-Anfrage, mit `system` und `tools`. [Komprimierung auf Anfrage](https://platform.claude.com/docs/de/build-with-claude/compaction-on-demand) ist mit Threads nicht verfügbar (siehe [Funktionen, die Threads nicht unterstützen](https://platform.claude.com/docs/de/build-with-claude/message-threads#unsupported)).

## Verhalten des SDK-Helpers

Was der Helper für dich erledigt:

* Fügt den Beta-Header `message-threads-2026-08-12` zu jeder Anfrage hinzu, die den Thread verwendet.
* Erstellt beim ersten Turn einen Thread und setzt ihn danach fort, wobei nur die neuen Nachrichten gesendet und `system` und `tools` weggelassen werden.
* Spielt die vollständige Konversation einmal in einer neuen Create-Anfrage erneut ab, wenn eine Continue-Anfrage `thread_not_found`, `thread_already_continued` oder `thread_continue_in_flight` zurückgibt.
* Setzt eine `pause_turn`-Antwort fort, wenn du `send()` (go, csharp: `Send()`; ruby: `send_message()`) ohne Nachrichten aufrufst.
* Startet nach einer Ablehnung einen neuen Thread. Du erhältst die Antwort mit `stop_reason: "refusal"` wie gewohnt, aber der Helper behält diesen Turn nicht: Er nimmt die Nachrichten zurück, die du diesem Aufruf übergeben hast. Nachrichten, die du mit `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`) hinzugefügt oder beim Erstellen des Helpers übergeben hast, bleiben vorgemerkt. Dein nächster Turn sendet sie zusammen mit der Konversation von vor dem abgelehnten Turn in einer neuen Create-Anfrage. Sende eine umformulierte Nachricht oder, falls eine vorgemerkte Nachricht zur Ablehnung geführt hat, starte einen neuen Thread aus den Params ohne diese Nachricht.
* Sendet nach einer Antwort von einem Fallback-Modell eine neue Create-Anfrage. Wenn eine Antwort einen `fallback_message`-Eintrag in `usage.iterations` hat, behält der Helper die Antwort und sendet im nächsten Turn die vollständige Konversation in einer neuen Create-Anfrage. Er wartet nicht auf einen 404-Fehler. Diese Anfrage behält das `model` und die `fallbacks`, die du festgelegt hast.
* Lässt die `cache_control`-Breakpoints früherer Turns weg, wann immer er diese erneut sendet, zum Beispiel bei einem Replay oder im ersten Turn eines Forks. Deine neuesten Nachrichten, `system`, `tools` und das `cache_control` auf oberster Ebene werden so gesendet, wie du sie übergeben hast.

Was du selbst übernimmst:

* **Fallbacks.** Solange die API weiterhin von einem Fallback-Modell antwortet, sendet der Helper in jedem Turn die vollständige Konversation in einer neuen Create-Anfrage, weil die API keinen dieser Turns speichert. Nach einer Antwort von dem Modell, das du angefordert hast, kehrt er zu Continue-Anfragen zurück. Um die Konversation stattdessen auf das Fallback-Modell zu verlagern, starte einen neuen Thread aus den Params mit diesem `model` und ohne `fallbacks`, wie in [Fallbacks mit einem Thread verwenden](https://platform.claude.com/docs/de/build-with-claude/message-threads#fallbacks).
* **Abgebrochene Streams.** Wenn ein Stream mitten in einer Antwort endet, behält der Helper die fertigen Blöcke und jeglichen bereits eingetroffenen Text, und der nächste Turn sendet die vollständige Konversation in einer neuen Create-Anfrage. Der Helper wiederholt nicht von selbst: Um stattdessen den unterbrochenen Turn erneut zu senden, rufe `send()` (go, csharp: `Send()`; ruby: `send_message()`) ohne Nachrichten auf. Wenn der behaltene Teil mit Tool-Aufrufen endet, beantworte sie in deiner nächsten Nachricht. Wenn du das Lesen eines Streams beendest, nachdem er `stop_reason: "refusal"` angezeigt hat, behandelt der Helper diesen Turn als Ablehnung.
* **Andere Fehler.** Die Fehler `thread_fingerprint_mismatch` und `thread_unsupported_request` erreichen deinen Code. Um nach einem `thread_unsupported_request`-Fehler ohne `thread` weiterzumachen, erstelle den Helper mit `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`), gesetzt auf `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`). Mit dieser Einstellung hört der Helper auch dann auf, `thread` zu verwenden, wenn die erste Continue-Anfrage nach einem Replay erneut `thread_not_found` zurückgibt. Die API kann diese Konversation möglicherweise nicht speichern. Ohne diese Einstellung führt der Helper bei jedem Turn ein Replay durch. Ein Tool-Runner, der seinen eigenen Thread erstellt, verwendet diese Einstellung standardmäßig.

Der Beta-Tool-Runner des SDK verwendet ebenfalls standardmäßig einen Thread, den du beim Erstellen des Runners deaktivieren kannst.

### Weitere Helper-Methoden

| Um dies zu tun                                              | Verwende                                                                                                                                                                                                                                                                                                                             |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Einen Turn streamen                                         | `thread.stream(...)` (csharp: `thread.SendStreaming(...)`; go: `thread.SendStreaming(ctx, params)`; java: `thread.sendStreaming(...)`; php: `$thread->sendStream(...)`)                                                                                                                                                              |
| Fertige Antwort eines gestreamten Turns                     | `stream.get_final_message()` (typescript: `stream.finalMessage()`; csharp: `thread.LastMessage`; go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`; ruby: `stream.accumulated_message`)                                                                                                        |
| Vollständige Konversation                                   | `thread.messages` (csharp: `thread.Messages`; go: `thread.Messages()`; java: `thread.messages()`; php: `$thread->messages()`)                                                                                                                                                                                                        |
| Antwort-`id`, von der aus der nächste Turn fortgesetzt wird | `thread.previous_message_id` (typescript: `thread.previousMessageId`; csharp: `thread.PreviousMessageID`; go: `thread.PreviousMessageID()`; java: `thread.previousMessageId()`; php: `$thread->previousMessageId()`)                                                                                                                 |
| Nachrichten hinzufügen, ohne sie zu senden                  | `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`)                                                                                                                                                                                                                                                 |
| Felder für spätere Turns ändern                             | `thread.update(...)` (csharp: `thread.Update(p => p with { ... })`; go: `thread.Params.MaxTokens = ...`; java: `thread.update(b -> ...)`; php: `$thread->update([...])`)                                                                                                                                                             |
| Den Thread kopieren                                         | `thread.fork()` (csharp, go: `thread.Fork()`; php: `$thread->fork()`; ruby: `thread.fork`)                                                                                                                                                                                                                                           |
| Felder und Konversation, um einen neuen Thread zu starten   | `thread.params` (csharp, go: `thread.Params`; java: `thread.params()`; php: `$thread->params()`)                                                                                                                                                                                                                                     |
| Tool-Runner auf diesem Thread                               | `thread.tool_runner()` (typescript, java: `thread.toolRunner()`; csharp: `thread.ToolRunner(tools)`; go: `thread.NewToolRunner(tools)`; php: `$thread->toolRunner()`; ruby: `thread.tool_runner`)                                                                                                                                    |
| Tool-Runner ohne Thread                                     | `tool_runner(..., thread=False)` (typescript: `toolRunner({ ..., thread: false })`; csharp: `ToolRunner(parameters, tools, thread: false)`; go: `BetaToolRunnerParams{DisableThread: true}`; java: `ToolRunnerCreateParams.builder().thread(false)`; php: `toolRunner(..., thread: false)`; ruby: `tool_runner(..., thread: false)`) |

**Streaming.** Der Helper zeichnet die Antwort auf, wenn der Stream `message_stop` erreicht, also lies den Stream bis zu seinem Ende. Wenn du früher aufhörst zu lesen, beende den Stream, damit der Thread für den nächsten Turn frei ist:

* Python: Verlasse den `with`-Block.
* TypeScript: Verlasse die Schleife oder rufe `abort()` auf.
* Go: Rufe `Close` auf.
* Java und Ruby: Rufe `close()` auf.
* C#: Gib den Enumerator frei. Das Verlassen von `await foreach` erledigt das.
* PHP: Rufe `close()` auf.

In C# wird die Anfrage gesendet, wenn du beginnst, den Stream zu lesen.

In C#, Go, Java und PHP gibt `thread.LastMessage` (go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`) nach einer Ablehnung weiterhin die Antwort des vorherigen Turns zurück, oder nichts bei einem ersten Turn. Lies die Ablehnung aus den Events des Streams.

**Felder ändern.** Ein Update sendet nichts und gilt für jeden späteren Turn. Sobald ein Thread eine Antwort hat, verweigert der Helper einen Turn, der `system` oder `tools` ändert, und die API lehnt eine Änderung an jedem anderen festen Feld ab (siehe [Was bei jeder Anfrage gesendet wird](https://platform.claude.com/docs/de/build-with-claude/message-threads#what-to-send)). Um eines dieser Felder zu ändern, starte einen neuen Thread aus den Params, oder forke den Thread und aktualisiere den Fork vor seinem ersten Turn.

**Forken.** Ein Fork kopiert die Konversation, die Felder und die Anfrageoptionen und sendet nichts. Sein erster Turn sendet die vollständige Konversation in einer neuen Create-Anfrage, und die beiden Threads sind danach unabhängig. Ein Fork beginnt immer mit der gesamten Konversation, nicht mit einer früheren Antwort.

**Params.** Die Params enthalten die Felder des Helpers und die vollständige Konversation. Übergib sie an die Methode, die einen Helper erstellt, um einen neuen Thread zu starten, zum Beispiel mit einem anderen `system` (siehe [Was bei jeder Anfrage gesendet wird](https://platform.claude.com/docs/de/build-with-claude/message-threads#what-to-send)) oder mit gekürzten `messages`, um spätere Turns zu verwerfen. Ein Thread, den du aus den Params startest, sendet jede Nachricht so, wie du sie übergeben hast, einschließlich der `cache_control`-Breakpoints, also halte dich an das Limit von 4 (siehe [Prompt-Caching in einem Thread](https://platform.claude.com/docs/de/build-with-claude/message-threads#prompt-caching)). Außer in Ruby lassen die Params die Anfrageoptionen weg, übergib diese also erneut.

**Strukturierte Ausgabe.** Gib das Ausgabeformat an, wenn du den Helper erstellst. Ein späterer Turn kann es nicht ändern. Wie du das geparste Ergebnis erhältst, hängt vom SDK ab:

* Python und TypeScript: Rufe `thread.parse(...)` auf.
* C#: Erstelle den Helper mit `client.Beta.Messages.Thread<T>(...)`.
* Go: `Send` deserialisiert in die Struct, auf die `Params.OutputConfig.Format.Schema` zeigt.
* Java: Erstelle den Helper mit `thread(...)` und `outputConfig(MyClass.class)`.
* PHP: `send()` setzt `parsed` auf den Textblöcken, wenn `outputConfig` eine Modellklasse angibt.
* Ruby: Übergib `output_config: {format: MyModel}` an `thread(...)` und lies dann `reply.parsed_output`.

## Fehler

Die API gibt die Fehler in dieser Tabelle zurück, bevor das Modell läuft. Die Anfrage verbraucht keine Token, und der Thread und seine Ablaufzeit ändern sich nicht. `error.type` ist `invalid_request_error` für die 400-Fehler und `not_found_error` für den 404-Fehler.

| Status | `error_code`                  | Bedeutung                                                                                                                                                       | Was zu tun ist                                                                                                           |
| ------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| 404    | `thread_not_found`            | Die API kann den Thread nicht fortsetzen.                                                                                                                       | Sende die vollständige Konversation in einer neuen Create-Anfrage.                                                       |
| 400    | `thread_fingerprint_mismatch` | Ein festes Feld weicht von dem mit dem Thread gespeicherten Wert ab. Die Fehlermeldung nennt die Felder.                                                        | Halte die festen Felder gleich, oder starte einen neuen Thread, um eines zu ändern.                                      |
| 400    | `thread_already_continued`    | Jede Antwort-`id` kann einmal fortgesetzt werden.                                                                                                               | Setze von der neuesten Antwort-`id` des Threads aus fort. Wenn dein Client diese Antwort nie erhalten hat, sende erneut. |
| 400    | `thread_continue_in_flight`   | Eine andere Continue-Anfrage von dieser Antwort-`id` aus läuft noch. Das ist normalerweise dein eigener früherer Versuch.                                       | Lass sie abschließen und setze von ihrer Antwort-`id` aus fort, oder sende erneut.                                       |
| 400    | `thread_unsupported_request`  | Die Anfrage verwendet eine Funktion oder eine Organisationseinstellung, die Threads nicht unterstützen. `error.details.unsupported` nennt sie, falls vorhanden. | Entferne diese Funktion aus der Anfrage, oder sende die vollständige Konversation ohne `thread`.                         |

Einige 400-Fehler für Thread-Anfragen tragen keinen `error_code`, zum Beispiel eine Continue-Anfrage ohne `previous_message_id` oder eine, die `system` oder `tools` enthält.

Das folgende Beispiel zeigt einen Fehler-Body:

```json
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "thread: a maximum of 4 blocks with cache_control may be provided when `thread` is set. Found 5.",
    "details": {
      "error_code": "thread_unsupported_request",
      "unsupported": ["cache_control"]
    }
  },
  "request_id": "req_011CSHoEeqs5C35K2UUqR7Fy"
}
```

## Funktionen, die Threads nicht unterstützen

Threads unterstützen diese Funktionen nicht:

* [Message Batches](https://platform.claude.com/docs/de/build-with-claude/batch-processing). Ein Anfrageelement, das `thread` enthält, endet mit einem `invalid_request_error` in den Batch-Ergebnissen.
* [Token-Zählung](https://platform.claude.com/docs/de/build-with-claude/token-counting). Eine Token-Zählungsanfrage, die `thread` enthält, gibt einen 400-Fehler zurück. Zähle stattdessen die vollständige Konversation, mit `system` und `tools`.
* [Compaction](https://platform.claude.com/docs/de/build-with-claude/compaction). [Komprimierung auf Anfrage](https://platform.claude.com/docs/de/build-with-claude/compaction-on-demand) ist mit Threads nicht verfügbar. Eine Anfrage, die `thread` enthält, gibt einen 400-Fehler zurück, wenn sie den `compaction`-Parameter setzt oder wenn sie einen `compaction`-Block mit dem Beta-Header `compact-2026-09-04` sendet. Siehe [Eine Konversation komprimieren](https://platform.claude.com/docs/de/build-with-claude/message-threads#compaction).
* [Kontextbearbeitung](https://platform.claude.com/docs/de/build-with-claude/context-editing), außer `clear_thinking_20251015` mit `keep: "all"`.
* Organisationen, bei denen [HIPAA-Bereitschaft](https://platform.claude.com/docs/de/manage-claude/api-and-data-retention#hipaa-readiness) aktiviert ist.
* Organisationen, bei denen [Inference Hooks](https://platform.claude.com/docs/de/manage-claude/inference-hooks) eingeschaltet sind.

Die API lehnt die meisten Anfragen, die Threads nicht unterstützen, mit einem 400-Fehler und dem Code `thread_unsupported_request` ab. Wenn `error.details.unsupported` vorhanden ist, enthält es einen dieser Werte:

| Wert                 | Bedeutung                                                                                                                                                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `context_management` | Die Anfrage verwendet Kontextverwaltung oder Compaction, die Threads nicht unterstützen.                                                                                              |
| `cache_control`      | Die Anfrage hat mehr als 4 `cache_control`-Breakpoints. Siehe [Prompt-Caching in einem Thread](https://platform.claude.com/docs/de/build-with-claude/message-threads#prompt-caching). |
| `fallbacks`          | Die Anfrage setzt `fallbacks`, und deine Organisation kann `fallbacks` nicht mit Threads verwenden.                                                                                   |
| `hipaa`              | Bei deiner Organisation ist HIPAA-Bereitschaft aktiviert.                                                                                                                             |
| `inference_hooks`    | Bei deiner Organisation sind Inference Hooks eingeschaltet.                                                                                                                           |

Die API kann dieser Liste Werte hinzufügen. Wenn du einen Wert erhältst, den du nicht kennst, sende die vollständige Konversation ohne `thread`. Eine Anfrage, die mehrere dieser Bedingungen erfüllt, erhält einen Fehler, der nur eine davon nennt.

## Einschränkungen

* Es gibt keine API, um einen Thread aufzulisten, zu lesen oder zu löschen.
* Threads sind auf der Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/de/build-with-claude/claude-platform-on-aws), Claude Models on Google Cloud (Anthropic managed), und [Claude in Microsoft Foundry](https://platform.claude.com/docs/de/build-with-claude/claude-in-microsoft-foundry) verfügbar.

## Preise und Ratenlimits

Threads ändern weder die Preise noch die [Ratenlimits](https://platform.claude.com/docs/de/api/rate-limits).

## Datenaufbewahrung

Nachrichten-Threads sind nicht ZDR-berechtigt. Die Verwendung dieser Funktion wirkt sich nicht auf deine Verwendung anderer ZDR-berechtigter Funktionen aus. Die API hält einen Thread im Arbeitsspeicher, verschlüsselt mit einem serververwalteten Schlüssel, schreibt ihn nie in dauerhaften Speicher und löscht ihn spätestens 1 Stunde nach seiner letzten Verwendung.

Ein Thread enthält die Konversation, die die API an das Modell sendet, `system` und `tools` aus der Create-Anfrage sowie einen Fingerprint der festen Felder, den sie zur Prüfung späterer Anfragen verwendet. Er enthält Dateien per Referenz, also halte jede Datei, die die Konversation verwendet, verfügbar, solange du den Thread verwendest.

Informationen zur ZDR-Berechtigung aller Funktionen findest du unter [API und Datenaufbewahrung](https://platform.claude.com/docs/de/manage-claude/api-and-data-retention).

## Siehe auch

* [Prompt-Caching](https://platform.claude.com/docs/de/build-with-claude/prompt-caching)
* [Streaming](https://platform.claude.com/docs/de/build-with-claude/streaming)
* [Fehler](https://platform.claude.com/docs/de/api/errors)

## Verfügbarkeit

Nachrichten-Threads sind auf allen Modellen in der Beta.

### API-Unterstützung

#### [Messages API](https://platform.claude.com/docs/de/build-with-claude/working-with-messages)

* Verfügbarkeit: Verfügbar

| Status | Cloud-Plattformen                                                                                                                                                                                                                                                                                                                                                                      |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Beta   | Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/de/build-with-claude/claude-platform-on-aws), [Claude Models on Google Cloud (Anthropic managed)](https://platform.claude.com/docs/de/build-with-claude/claude-models-on-google-cloud/anthropic-managed), [Microsoft Foundry](https://platform.claude.com/docs/de/build-with-claude/claude-in-microsoft-foundry) |

### Erforderliche Beta-Header

[Übersicht über Beta-Header](https://platform.claude.com/docs/de/api/beta-headers)

Mit Beta-Headern kannst du auf experimentelle Funktionen und neue Modellfähigkeiten zugreifen, bevor sie Teil der Standard-API werden.

* `message-threads-2026-08-12`

### Datenverarbeitung

[Übersicht über die Datenverarbeitung](https://platform.claude.com/docs/de/manage-claude/api-and-data-retention#feature-eligibility)

| Element | Zero Data Retention                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | HIPAA            |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- |
| Status  | Nicht berechtigt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Nicht berechtigt |
| Details | Die Inhalte eines Threads (die Unterhaltung, der System-Prompt und die Tools) werden im Arbeitsspeicher gehalten, mit einem serververwalteten Schlüssel verschlüsselt, nie in einen dauerhaften Speicher geschrieben und spätestens 1 Stunde nach der letzten Verwendung des Threads gelöscht. Die Nutzung dieser Funktion beeinträchtigt nicht deine Nutzung anderer für ZDR berechtigter Funktionen. [Mehr erfahren](https://platform.claude.com/docs/de/build-with-claude/message-threads#data-retention) | —                |

Zutreffende Endpunkte:

* `/v1/messages` mit `thread`
