---
title: Threads de mensagens
url: https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads
description: Ofereça aos agentes de longa duração um tempo até o primeiro token mais rápido, especialmente em conversas longas, enviando apenas as novas mensagens em cada requisição.
featureMetadata:
  status: beta
  betaHeader: message-threads-2026-08-12
  zdr:
    eligibility: not-eligible
    note: O conteúdo de uma thread (a conversa, o prompt do sistema e as ferramentas) é mantido na memória, criptografado com uma chave gerenciada pelo servidor, nunca é gravado em armazenamento durável e é excluído no máximo 1 hora após o último uso da thread. O uso deste recurso não afeta o seu uso de outros recursos elegíveis para ZDR.
  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
---

Com uma “message thread” (thread de mensagens), as requisições são menores, e o “time to first token” (tempo até o primeiro token) permanece mais baixo e mais estável à medida que a conversa cresce. As threads ajudam mais em loops longos de agentes. Sem uma thread, cada turno envia a conversa inteira novamente, e a API valida e tokeniza tudo de novo. Com uma thread, a maior parte desse trabalho cobre apenas o novo turno.

Uma “message thread” (thread de mensagens) mantém uma conversa no servidor por um curto período. Você envia a conversa completa uma vez, com seu prompt do sistema e suas ferramentas. Em cada turno posterior, você envia apenas as novas mensagens e o `id` da resposta anterior. A API reconstrói a conversa antes de chamar o modelo. Você adiciona um parâmetro, `thread`, a uma requisição da [Messages API](https://platform.claude.com/docs/pt-BR/api/messages). A resposta é a mensagem habitual.

<Note>
  Threads de mensagens são diferentes das [threads de sessão](https://platform.claude.com/docs/pt-BR/managed-agents/session-threads) no Claude Managed Agents.
</Note>

## Como as threads de mensagens funcionam

* **Criar.** Envie sua primeira solicitação como você faz hoje, com a conversa completa, `system` e `tools`, e adicione `"thread": {"type": "create"}`. A API armazena a conversa, incluindo a resposta de Claude, sob o `id` da resposta.
* **Continuar.** Envie apenas as mensagens desde a resposta anterior e adicione `"thread": {"type": "continue", "previous_message_id": "<previous id>"}`. Deixe `system` e `tools` fora da solicitação. A thread mantém os valores da solicitação de criação. Use cada novo `id` de resposta para o próximo turno.
* **Reenviar.** Uma thread funciona no modelo de melhor esforço. Ela expira 5 minutos após sua última requisição, e a API a exclui no máximo 1 hora após seu último uso. Cada resposta que a API armazena reinicia os 5 minutos. Se a API não puder mais continuar a thread, uma solicitação de continuação retorna um erro 404. Envie a conversa completa novamente em uma nova solicitação de criação e continue a partir do `id` dessa resposta. O helper de thread do SDK faz esse reenvio para você (consulte [Como o helper do SDK se comporta](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#sdk-helper-handles)). Após uma resposta de um modelo de fallback, consulte [Usar fallbacks com uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#fallbacks).

Sua aplicação continua sendo a fonte da verdade para a conversa. Mantenha sua própria cópia de cada mensagem e construa o [caminho de reenvio](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#recover) desde o início. Nenhuma resposta, seja a uma solicitação de criação ou de continuação, informa se a API armazenou aquele turno. Você descobre isso na próxima solicitação de continuação. O helper de thread do SDK mantém essa cópia na memória enquanto o objeto helper existir, e não a salva em nenhum outro lugar. Se a conversa precisar sobreviver ao seu processo, mantenha sua própria cópia.

## Usar uma thread com um SDK

O SDK tem um helper de thread que monta as solicitações de thread para você. Crie-o com os mesmos campos de uma solicitação da Messages API e, em seguida, envie um turno de cada vez. O helper mantém a conversa completa na memória.

Este exemplo tem dois turnos. O helper cria uma thread no primeiro turno e a continua no segundo, e adiciona o cabeçalho beta para você. O `cache_control` de nível superior é opcional. Ele solicita cache de prompt em cada turno (consulte [Cache de prompt em uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#prompt-caching)). Sem ele, cada turno posterior ainda envia apenas as novas mensagens, mas nada é armazenado em cache, a menos que você mesmo adicione pontos de interrupção de cache.

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

  # Cria o helper. Esta chamada não envia nenhuma requisição.
  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.",
  )

  # Turno 1: o helper cria uma thread e envia a conversa completa
  thread.send({"role": "user", "content": "Hi! I have a question about an order."})

  # Turno 2: o helper continua a thread e envia apenas a nova mensagem
  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();

  // Cria o helper. Esta chamada não envia nenhuma requisição.
  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."
  });

  // Turno 1: o helper cria uma thread e envia a conversa completa
  await thread.send({ role: "user", content: "Hi! I have a question about an order." });

  // Turno 2: o helper continua a thread e envia apenas a nova mensagem
  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();

  // Cria o helper. Esta chamada não envia nenhuma requisição.
  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.",
      }
  );

  // Turno 1: o helper cria uma thread e envia a conversa completa
  await thread.Send(
      new BetaUserMessageParam { Content = "Hi! I have a question about an order." }
  );

  // Turno 2: o helper continua a thread e envia apenas a nova mensagem
  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()

  // Cria o helper. Esta chamada não envia nenhuma requisição.
  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."},
  	},
  })

  // Turno 1: o helper cria uma thread e envia a conversa completa
  _, 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)
  }

  // Turno 2: o helper continua a thread e envia apenas a nova mensagem
  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();

  // Cria o helper. Esta chamada não envia nenhuma requisição.
  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()
  );

  // Turno 1: o helper cria uma thread e envia a conversa completa
  thread.send("Hi! I have a question about an order.");

  // Turno 2: o helper continua a thread e envia apenas a nova mensagem
  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();

  // Cria o helper. Esta chamada não envia nenhuma requisição.
  $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.',
  );

  // Turno 1: o helper cria uma thread e envia a conversa completa
  $thread->send(['role' => 'user', 'content' => 'Hi! I have a question about an order.']);

  // Turno 2: o helper continua a thread e envia apenas a nova mensagem
  $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

  # Cria o helper. Esta chamada não envia nenhuma requisição.
  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."
  )

  # Turno 1: o helper cria uma thread e envia a conversa completa
  thread.send_message({role: "user", content: "Hi! I have a question about an order."})

  # Turno 2: o helper continua a thread e envia apenas a nova mensagem
  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>

## Enviar o campo `thread` você mesmo

Para construir as requisições de thread você mesmo, por exemplo com cURL, a CLI ou o método `create` habitual de um SDK, adicione o campo `thread` a cada requisição.

Envie o cabeçalho beta `message-threads-2026-08-12` em todas as requisições de uma thread.

Este exemplo cria uma thread no primeiro turno e a continua no segundo. O `cache_control` de nível superior solicita cache de prompt em cada turno. Ele entra em vigor quando a conversa ultrapassa o [comprimento mínimo armazenável em cache](https://platform.claude.com/docs/pt-BR/build-with-claude/prompt-caching).

<CodeGroup>
  ```bash cURL
  # Turno 1: envie a conversa completa e crie uma 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"}
    }'

  # Turno 2: envie apenas a nova mensagem. Defina message_id como o id da resposta do turno 1.
  # Omita system e tools: a thread os mantém.
  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
  # Turno 1: envie a conversa completa e crie uma 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

  # Turno 2: envie apenas a nova mensagem. Defina message_id como o id da resposta do turno 1.
  # Omita system e tools: a thread os mantém.
  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()

  # Turno 1: envie a conversa completa e crie uma 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"],
  )

  # Turno 2: envie apenas a nova mensagem e o id da resposta do turno 1.
  # Omita system e tools: a thread os mantém.
  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();

  // Turno 1: envie a conversa completa e crie uma 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"]
  });

  // Turno 2: envie apenas a nova mensagem e o id da resposta do turno 1.
  // Omita system e tools: a thread os mantém.
  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();

  // Turno 1: envie a conversa completa e crie uma 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],
      }
  );

  // Turno 2: envie apenas a nova mensagem e o id da resposta do turno 1.
  // Omita System e Tools: a thread os mantém.
  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()

  // Turno 1: envie a conversa completa e crie uma 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)
  }

  // Turno 2: envie apenas a nova mensagem e o id da resposta do turno 1.
  // Omita System e Tools: a thread os mantém.
  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();

  // Turno 1: envie a conversa completa e crie uma 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()
  );

  // Turno 2: envie apenas a nova mensagem e o id da resposta do turno 1.
  // Omita system e tools: a thread os mantém.
  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();

  // Turno 1: envie a conversa completa e crie uma 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'],
  );

  // Turno 2: envie apenas a nova mensagem e o id da resposta do turno 1.
  // Omita system e tools: a thread os mantém.
  $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

  # Turno 1: envie a conversa completa e crie uma 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"]
  )

  # Turno 2: envie apenas a nova mensagem e o id da resposta do turno 1.
  # Omita system_ e tools: a thread os mantém.
  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>

## O que enviar em cada requisição

| Grupo              | Campos                                                                                                                                                                                                                                                 | Regra                                                                                                                                                                                                                             |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Somente na criação | `system`, `tools`                                                                                                                                                                                                                                      | Envie-os apenas na requisição de criação, com quaisquer pontos de interrupção `cache_control` neles. Enviar qualquer um deles em uma requisição de continuação, mesmo como `null`, retorna um erro 400.                           |
| Fixos              | `model`, `tool_choice`, `thinking`, `mcp_servers` (exceto o token de autorização de cada servidor), `context_management`, `output_config`, as `skills` em `container`, o `cache_control` de nível superior e o conjunto de valores de `anthropic-beta` | Envie-os em todas as requisições da thread, com os mesmos valores da requisição de criação. Um valor diferente retorna um erro 400 com o código `thread_fingerprint_mismatch`, e a mensagem de erro nomeia os campos que diferem. |
| Livres             | `max_tokens`, `stop_sequences`, `stream`, `metadata`, `service_tier` e outros campos não mencionados nesta página                                                                                                                                      | Estes podem mudar de um turno para outro.                                                                                                                                                                                         |

A API não armazena URLs de servidores MCP, tokens de autorização MCP nem o `id` do container. Envie `mcp_servers` e `container` em todas as requisições que os utilizam. Um token de autorização MCP pode mudar entre requisições.

O helper de thread do SDK deixa `system` e `tools` fora das solicitações de continuação para você e envia os campos fixos novamente a cada turno.

Se você usa [fallback no lado do servidor](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback#server-side-fallback), envie o campo `fallbacks` em todas as requisições de uma thread ou em nenhuma. Consulte [Usar fallbacks com uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#fallbacks).

Para alterar um campo somente de criação ou fixo, inicie uma nova thread: envie a conversa completa em uma requisição de criação com os novos valores.

No Claude Fable 5.1, no Claude Mythos 5.1, no Claude Opus 5.5, no Claude Sonnet 5.5 e no Claude Haiku 5.5, alterar `system` ou `tools` torna inválidos os blocos `thinking` e `redacted_thinking` que já estão na conversa, e a requisição de criação pode retornar um erro 400. Para evitar isso, deixe todos os blocos `thinking` e `redacted_thinking` de fora da conversa que você envia. O modelo então responde sem esse raciocínio anterior. Consulte [O que conta como edição](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#what-counts-as-an-edit), [Quando `prefix_mismatch_behavior` não está definido](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#enforcement) e [O que a API faz com um bloco inválido](https://platform.claude.com/docs/pt-BR/build-with-claude/preserved-thinking#mismatch-behavior).

Envie apenas as novas mensagens em uma requisição de continuação. A API não as compara com as mensagens que já possui. Uma mensagem que você envia novamente pode aparecer duas vezes na conversa, ou a requisição pode retornar um erro. Por exemplo, uma requisição de continuação que começa com a resposta anterior retorna um erro.

As novas mensagens geralmente começam com uma mensagem `user`: seu próximo turno de usuário ou os blocos `tool_result` que respondem a um `tool_use` na resposta anterior. Se uma resposta parar com [`stop_reason: "pause_turn"`](https://platform.claude.com/docs/pt-BR/build-with-claude/handling-stop-reasons#pause-turn), retome-a com uma solicitação de continuação a partir do `id` dessa resposta e uma lista `messages` vazia (`"messages": []`). Se essa solicitação retornar um erro 404, reenvie a conversa completa, incluindo a resposta pausada, em uma nova solicitação de criação. Não envie uma nova mensagem `user` enquanto o turno estiver pausado: a API a rejeita. Com o helper de thread do SDK, chame `send()` (go, csharp: `Send()`; ruby: `send_message()`) sem mensagens: o helper envia essa solicitação e reenvia a conversa em caso de erro 404.

Uma thread é somente de acréscimo, e cada `id` de resposta pode ser continuado uma vez. Sempre continue a partir do `id` de resposta mais recente da thread. Para editar ou ramificar uma mensagem anterior, inicie uma nova thread com uma requisição de criação. Para substituir turnos anteriores por um resumo, consulte [Compactar uma conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#compaction).

## Cache de prompt em uma thread

Uma thread não armazena seu prompt em cache por você. O [cache de prompt](https://platform.claude.com/docs/pt-BR/build-with-claude/prompt-caching) funciona como funciona sem uma thread: você escolhe onde ficam os pontos de interrupção de cache.

Para armazenar cada turno em cache, envie um `cache_control` de nível superior em todas as requisições da thread, como no exemplo anterior. A API o aplica ao último bloco de `messages` de cada requisição que pode ser armazenado em cache. Cada turno então lê a conversa anterior do cache e grava o novo turno nele. O `cache_control` de nível superior é um campo fixo: envie o mesmo valor em todas as requisições.

Você também pode colocar pontos de interrupção `cache_control` em blocos você mesmo:

* Os breakpoints que você envia na requisição de criação continuam funcionando em todos os turnos posteriores se estiverem em `tools`, em `system` ou em um bloco de mensagem anterior ao último. Um breakpoint no último bloco de `messages` de uma requisição grava o cache nessa requisição. Para armazenar em cache cada novo turno, envie um breakpoint em todas as requisições. Uma requisição sem breakpoint ainda pode ler parte da conversa do cache.
* Você não pode mover nem remover um breakpoint depois de enviá-lo, porque uma solicitação de continuação não pode enviar novamente uma mensagem anterior.
* Uma solicitação com `thread` pode conter no máximo 4 breakpoints de `cache_control`. O `cache_control` de nível superior conta como um. Os breakpoints em `system` e `tools` da solicitação de criação contam novamente em cada solicitação de continuação. Os breakpoints em mensagens armazenadas anteriormente não contam. Um breakpoint a mais retorna um erro 400 com o código `thread_unsupported_request`.
* Se você mesmo colocar breakpoints em blocos de mensagem, remova-os das mensagens anteriores ao reenviar a conversa em uma nova solicitação de criação e mantenha um no último bloco, para que a solicitação permaneça dentro do limite de 4.

## Streaming

As threads funcionam com [streaming](https://platform.claude.com/docs/pt-BR/build-with-claude/streaming). O `id` da resposta chega no evento `message_start`, mas continue a partir dele somente depois de receber o evento `message_stop`. Uma requisição de continuação enviada antes disso pode retornar um erro 404.

Se o stream de uma requisição de continuação cair antes de `message_stop`, envie a mesma requisição de continuação novamente. Se essa requisição retornar um erro `thread_already_continued` ou `thread_continue_in_flight`, reenvie a conversa completa em uma nova requisição de criação.

Sua conexão pode ter caído enquanto o servidor ainda estava gerando a resposta, ou depois que o servidor a salvou. É por isso que a API pode rejeitar a nova tentativa. Reenviar é sempre seguro.

O helper de thread do SDK não tenta novamente a solicitação de continuação após um stream interrompido. Consulte [Como o helper do SDK se comporta](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#sdk-helper-handles).

## Recuperar quando uma thread não pode ser continuada

Uma requisição de continuação retorna um erro 404 com `error.details.error_code` definido como `thread_not_found` quando a API não consegue continuar a thread. A resposta não informa o motivo. As causas incluem as seguintes:

* A thread expirou.
* A API atendeu o turno anterior, mas não o armazenou. Por exemplo, a API não armazena uma resposta que termina em uma chamada de ferramenta cortada por `max_tokens`.
* Um modelo de fallback escreveu a resposta anterior. Consulte [Usar fallbacks com uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#fallbacks).
* A resposta anterior ainda está sendo gerada.
* A requisição vem de uma organização ou workspace diferente.
* A requisição vem de um usuário ou conta de serviço diferente daquele que criou a thread. Uma thread criada com uma [chave de workspace (legado)](https://platform.claude.com/docs/pt-BR/manage-claude/authentication#key-types) permanece vinculada a essa chave, então use a mesma chave para a thread inteira.
* As novas mensagens adicionam algo que a conversa armazenada não comporta. Por exemplo, a primeira imagem em uma conversa que não tinha nenhuma pode retornar esse erro.

Para se recuperar, envie a conversa completa a partir da sua própria cópia em uma nova requisição de criação, com `system` e `tools`. O helper de thread do SDK envia essa requisição de criação uma vez por conta própria e, ao fazê-lo, deixa de fora os breakpoints `cache_control` de turnos anteriores. Se mensagens anteriores na sua cópia tiverem breakpoints `cache_control`, remova-os primeiro (consulte [Cache de prompt em uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#prompt-caching)). Em seguida, continue a partir do `id` da nova resposta. Se um modelo de fallback escreveu a resposta anterior, consulte [Usar fallbacks com uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#fallbacks). Para descartar as causas relacionadas à propriedade, use a mesma chave de API e o mesmo workspace para cada requisição de uma thread. No Claude Platform on AWS, assine cada requisição de uma thread com credenciais da função do IAM ou do usuário do IAM que a criou.

Uma requisição para um modelo que não existe também retorna um erro 404, então verifique `error.details.error_code` antes de reenviar.

Se uma requisição de continuação ainda retornar um erro 404 logo após a reprodução, a API pode não conseguir armazenar essa conversa, por exemplo uma muito grande. Envie-a sem `thread`. O helper de thread do SDK faz isso quando você o cria com `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`) definido como `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`). Caso contrário, ele reproduz a conversa a cada turno.

### Após uma recusa

Quando uma resposta tiver `stop_reason: "refusal"`, não continue a thread. A API pode já conter o turno recusado, e uma requisição de continuação não pode removê-lo. Inicie uma nova thread com uma requisição de criação que deixe de fora ou reformule o turno que levou à recusa. Consulte [Recusas e fallback](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback). O helper de thread do SDK faz isso para você: ele não mantém o turno recusado, e seu próximo turno inicia uma nova thread.

### Usar fallbacks com uma thread

O [fallback no lado do servidor](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback#server-side-fallback) está disponível com threads na Claude API. Decida ao criar a thread: envie `fallbacks` em todas as requisições da thread, ou em nenhuma. O valor de `fallbacks` pode mudar entre requisições. Uma requisição de continuação que adiciona ou remove `fallbacks` retorna um erro 400 com o código `thread_fingerprint_mismatch`.

Uma thread mantém um único modelo, então a API não armazena um turno escrito por um modelo de fallback. Você recebe a resposta normalmente, mas não pode continuar a partir do seu `id`. Após cada resposta, siga estas etapas:

1. Se `stop_reason` for `"refusal"`, siga [Após uma recusa](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#after-a-refusal).

2. Caso contrário, procure uma entrada `fallback_message` em `usage.iterations`. Em um stream, leia-a a partir do evento `message_delta` final. Se não houver nenhuma, continue a thread normalmente.

3. Se houver uma, um modelo de fallback escreveu a resposta. Envie a conversa completa, incluindo essa resposta e sua próxima mensagem, em uma nova requisição de criação. Mantenha o cabeçalho beta `server-side-fallback-2026-07-01` nela. Escolha uma destas duas requisições:

   * **A mesma requisição novamente.** Mantenha `model`, `fallbacks` e seus outros parâmetros como estavam. Se o modelo que você solicitou responder, a API armazena a nova thread. Se um modelo de fallback responder, a resposta terá novamente uma entrada `fallback_message` e a API não a armazenará, então repita esta etapa no próximo turno. O [roteamento persistente](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback#sticky-routing) pode enviar essas requisições diretamente ao modelo de fallback, então cada turno pode enviar a conversa completa. O helper de thread do SDK funciona dessa forma.
   * **Uma nova thread no modelo de fallback.** Defina `model` como o `model` nessa entrada `fallback_message`, deixe `fallbacks` de fora e use parâmetros que esse modelo aceite. A API armazena essa thread imediatamente, e ela permanece no modelo de fallback. A tentativa de fallback pode ter sido executada com configurações diferentes das que você enviou, então a API pode rejeitar valores copiados da sua primeira requisição.

4. Volte à etapa 1 com a resposta a essa requisição. Quando ela não tiver nenhuma entrada `fallback_message`, continue a nova thread a partir do `id` dessa resposta.

O [roteamento persistente](https://platform.claude.com/docs/pt-BR/build-with-claude/refusals-and-fallback#sticky-routing) começa depois que uma requisição recorre ao fallback (uma requisição de criação, ou uma requisição sem `thread`). Por cerca de uma hora, ele pode enviar requisições de criação posteriores para a mesma conversa que incluam `fallbacks` diretamente ao modelo de fallback, sem tentar o modelo que você solicitou. A API não armazena nenhum desses turnos, e cada um que recebe resposta reinicia a contagem de uma hora. Uma requisição de continuação nunca inicia esse roteamento e nunca o utiliza. O roteamento persistente não se aplica se sua organização ou workspace usar retenção zero de dados ou chaves de criptografia gerenciadas pelo cliente.

## Compactar uma conversa

Uma thread é somente de acréscimo, então você não pode substituir seus turnos anteriores por um resumo. Para compactar uma conversa, inicie uma nova thread a partir do resumo. Escreva o resumo no seu código e envie-o como uma mensagem comum em uma nova requisição de criação, com `system` e `tools`. A [compactação sob demanda](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-on-demand) não está disponível com threads (consulte [Recursos que as threads não suportam](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#unsupported)).

## Como o helper do SDK se comporta

O que o helper faz por você:

* Adiciona o cabeçalho beta `message-threads-2026-08-12` a cada requisição que usa a thread.
* Cria uma thread no primeiro turno e a continua depois disso, enviando apenas as novas mensagens e deixando de fora `system` e `tools`.
* Reproduz a conversa completa uma vez em uma nova requisição de criação quando uma requisição de continuação retorna `thread_not_found`, `thread_already_continued` ou `thread_continue_in_flight`.
* Retoma uma resposta `pause_turn` quando você chama `send()` (go, csharp: `Send()`; ruby: `send_message()`) sem mensagens.
* Inicia uma nova thread após uma recusa. Você recebe a resposta `stop_reason: "refusal"` normalmente, mas o helper não mantém esse turno: ele retira as mensagens que você passou para essa chamada. As mensagens que você adicionou com `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`), ou que passou ao criar o helper, permanecem preparadas. Seu próximo turno as envia com a conversa anterior ao turno recusado, em uma nova requisição de criação. Envie uma mensagem reformulada ou, se uma mensagem preparada levou à recusa, inicie uma nova thread a partir dos params sem ela.
* Envia uma nova requisição de criação após uma resposta de um modelo de fallback. Quando uma resposta tem uma entrada `fallback_message` em `usage.iterations`, o helper mantém a resposta e envia a conversa completa em uma nova requisição de criação no próximo turno. Ele não espera por um erro 404. Essa requisição mantém o `model` e os `fallbacks` que você definiu.
* Deixa de fora os breakpoints `cache_control` de turnos anteriores sempre que os envia novamente, por exemplo em uma reprodução ou no primeiro turno de um fork. Suas mensagens mais recentes, `system`, `tools` e o `cache_control` de nível superior são enviados como você os forneceu.

O que você mesmo precisa tratar:

* **Fallbacks.** Enquanto a API continuar respondendo a partir de um modelo de fallback, o helper envia a conversa completa em uma nova requisição de criação a cada turno, porque a API não armazena nenhum desses turnos. Ele volta às requisições de continuação após uma resposta do modelo que você solicitou. Para mover a conversa para o modelo de fallback em vez disso, inicie uma nova thread a partir dos params com esse `model` e sem `fallbacks`, como em [Usar fallbacks com uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#fallbacks).
* **Streams interrompidos.** Se um stream terminar no meio de uma resposta, o helper mantém os blocos concluídos e qualquer texto que tenha chegado, e o próximo turno envia a conversa completa em uma nova requisição de criação. O helper não tenta novamente por conta própria: para reenviar o turno interrompido, chame `send()` (go, csharp: `Send()`; ruby: `send_message()`) sem mensagens. Se a parte mantida terminar em chamadas de ferramentas, responda a elas na sua próxima mensagem. Se você parar de ler um stream depois que ele mostrar `stop_reason: "refusal"`, o helper trata esse turno como uma recusa.
* **Outros erros.** Os erros `thread_fingerprint_mismatch` e `thread_unsupported_request` chegam ao seu código. Para prosseguir sem `thread` após um erro `thread_unsupported_request`, crie o helper com `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`) definido como `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`). Com essa configuração, o helper também para de usar `thread` quando a primeira requisição de continuação após uma reprodução retorna `thread_not_found` novamente. A API pode não conseguir armazenar essa conversa. Sem essa configuração, o helper reproduz a conversa a cada turno. Um tool runner que cria sua própria thread usa essa configuração por padrão.

O executor de ferramentas beta do SDK também usa uma thread por padrão, o que você pode desativar ao criar o executor.

### Outros métodos do helper

| Para fazer isto                                            | Use                                                                                                                                                                                                                                                                                                                                  |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Fazer streaming de um turno                                | `thread.stream(...)` (csharp: `thread.SendStreaming(...)`; go: `thread.SendStreaming(ctx, params)`; java: `thread.sendStreaming(...)`; php: `$thread->sendStream(...)`)                                                                                                                                                              |
| Resposta finalizada de um turno com streaming              | `stream.get_final_message()` (typescript: `stream.finalMessage()`; csharp: `thread.LastMessage`; go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`; ruby: `stream.accumulated_message`)                                                                                                        |
| Conversa completa                                          | `thread.messages` (csharp: `thread.Messages`; go: `thread.Messages()`; java: `thread.messages()`; php: `$thread->messages()`)                                                                                                                                                                                                        |
| `id` da resposta a partir da qual o próximo turno continua | `thread.previous_message_id` (typescript: `thread.previousMessageId`; csharp: `thread.PreviousMessageID`; go: `thread.PreviousMessageID()`; java: `thread.previousMessageId()`; php: `$thread->previousMessageId()`)                                                                                                                 |
| Adicionar mensagens sem enviar                             | `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`)                                                                                                                                                                                                                                                 |
| Alterar campos para turnos posteriores                     | `thread.update(...)` (csharp: `thread.Update(p => p with { ... })`; go: `thread.Params.MaxTokens = ...`; java: `thread.update(b -> ...)`; php: `$thread->update([...])`)                                                                                                                                                             |
| Copiar a thread                                            | `thread.fork()` (csharp, go: `thread.Fork()`; php: `$thread->fork()`; ruby: `thread.fork`)                                                                                                                                                                                                                                           |
| Campos e conversa, para iniciar uma nova thread            | `thread.params` (csharp, go: `thread.Params`; java: `thread.params()`; php: `$thread->params()`)                                                                                                                                                                                                                                     |
| Tool runner nesta 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 sem uma 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.** O helper registra a resposta quando o stream chega a `message_stop`, então leia o stream até o fim. Se você parar de ler antes, encerre o stream para que a thread fique livre para o próximo turno:

* Python: saia do bloco `with`.
* TypeScript: saia do loop ou chame `abort()`.
* Go: chame `Close`.
* Java e Ruby: chame `close()`.
* C#: descarte o enumerador. Sair de `await foreach` faz isso.
* PHP: chame `close()`.

Em C#, a requisição é enviada quando você começa a ler o stream.

Em C#, Go, Java e PHP, após uma recusa, `thread.LastMessage` (go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`) ainda retorna a resposta do turno anterior, ou nada em um primeiro turno. Leia a recusa a partir dos eventos do stream.

**Alterar campos.** Uma atualização não envia nada e se aplica a todos os turnos posteriores. Depois que uma thread tem uma resposta, o helper recusa um turno que altere `system` ou `tools`, e a API rejeita uma alteração em qualquer outro campo fixo (consulte [O que enviar em cada requisição](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#what-to-send)). Para alterar um desses campos, inicie uma nova thread a partir dos params, ou faça um fork da thread e atualize o fork antes do seu primeiro turno.

**Fork.** Um fork copia a conversa, os campos e as opções de requisição, e não envia nada. Seu primeiro turno envia a conversa completa em uma nova requisição de criação, e as duas threads são independentes depois disso. Um fork sempre começa a partir da conversa inteira, não de uma resposta anterior.

**Params.** Os params contêm os campos do helper e a conversa completa. Passe-os para o método que cria um helper para iniciar uma nova thread, por exemplo com um `system` diferente (consulte [O que enviar em cada requisição](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#what-to-send)), ou com `messages` reduzido para descartar turnos posteriores. Uma thread que você inicia a partir dos params envia cada mensagem como você a forneceu, incluindo os breakpoints de `cache_control`, portanto mantenha-se dentro do limite de 4 (consulte [Cache de prompt em uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#prompt-caching)). Exceto em Ruby, os params omitem as opções de requisição, portanto passe-as novamente.

**Saída estruturada.** Informe o formato de saída ao criar o helper. Um turno posterior não pode alterá-lo. A forma de obter o resultado analisado depende do SDK:

* Python e TypeScript: chame `thread.parse(...)`.
* C#: crie o helper com `client.Beta.Messages.Thread<T>(...)`.
* Go: `Send` desserializa na struct para a qual `Params.OutputConfig.Format.Schema` aponta.
* Java: crie o helper com `thread(...)` e `outputConfig(MyClass.class)`.
* PHP: `send()` define `parsed` nos blocos de texto quando `outputConfig` nomeia uma classe de modelo.
* Ruby: passe `output_config: {format: MyModel}` para `thread(...)` e, em seguida, leia `reply.parsed_output`.

## Erros

A API retorna os erros desta tabela antes de o modelo ser executado. A requisição não usa tokens, e a thread e seu tempo de expiração não mudam. `error.type` é `invalid_request_error` para os erros 400 e `not_found_error` para o erro 404.

| Status | `error_code`                  | Significado                                                                                                                                       | O que fazer                                                                                                               |
| ------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| 404    | `thread_not_found`            | A API não consegue continuar a thread.                                                                                                            | Envie a conversa completa em uma nova requisição de criação.                                                              |
| 400    | `thread_fingerprint_mismatch` | Um campo fixo difere do valor armazenado com a thread. A mensagem de erro nomeia os campos.                                                       | Mantenha os campos fixos iguais, ou inicie uma nova thread para alterar um deles.                                         |
| 400    | `thread_already_continued`    | Cada `id` de resposta pode ser continuado uma vez.                                                                                                | Continue a partir do `id` de resposta mais recente da thread. Se seu cliente nunca recebeu essa resposta, faça o reenvio. |
| 400    | `thread_continue_in_flight`   | Outra requisição de continuação a partir deste `id` de resposta ainda está em execução. Geralmente é a sua própria tentativa anterior.            | Deixe-a terminar e continue a partir do seu `id` de resposta, ou faça o reenvio.                                          |
| 400    | `thread_unsupported_request`  | A requisição usa um recurso ou uma configuração da organização que as threads não suportam. `error.details.unsupported` o nomeia quando presente. | Remova esse recurso da requisição, ou envie a conversa completa sem `thread`.                                             |

Alguns erros 400 para requisições de thread não têm `error_code`, por exemplo uma requisição de continuação sem `previous_message_id`, ou uma que inclui `system` ou `tools`.

O exemplo a seguir mostra um corpo de erro:

```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"
}
```

## Recursos que as threads não suportam

As threads não suportam estes recursos:

* [Message Batches](https://platform.claude.com/docs/pt-BR/build-with-claude/batch-processing). Um item de requisição que inclui `thread` termina com um `invalid_request_error` nos resultados do lote.
* [Contagem de tokens](https://platform.claude.com/docs/pt-BR/build-with-claude/token-counting). Uma requisição de contagem de tokens que inclui `thread` retorna um erro 400. Em vez disso, conte a conversa completa, com `system` e `tools`.
* [Compactação](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction). A [compactação sob demanda](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-on-demand) não está disponível com threads. Uma requisição que inclui `thread` retorna um erro 400 se definir o parâmetro `compaction`, ou se enviar um bloco `compaction` com o cabeçalho beta `compact-2026-09-04`. Consulte [Compactar uma conversa](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#compaction).
* [Edição de contexto](https://platform.claude.com/docs/pt-BR/build-with-claude/context-editing), exceto `clear_thinking_20251015` com `keep: "all"`.
* Organizações que têm a [prontidão para HIPAA](https://platform.claude.com/docs/pt-BR/manage-claude/api-and-data-retention#hipaa-readiness) habilitada.
* Organizações que têm [Inference hooks](https://platform.claude.com/docs/pt-BR/manage-claude/inference-hooks) ativados.

A API rejeita a maioria das requisições que as threads não suportam com um erro 400 e o código `thread_unsupported_request`. Quando `error.details.unsupported` está presente, ele contém um destes valores:

| Valor                | Significado                                                                                                                                                                                          |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `context_management` | A requisição usa gerenciamento de contexto ou compactação que as threads não suportam.                                                                                                               |
| `cache_control`      | A requisição tem mais de 4 pontos de interrupção `cache_control`. Consulte [Cache de prompt em uma thread](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#prompt-caching). |
| `fallbacks`          | A requisição define `fallbacks`, e sua organização não pode usar `fallbacks` com threads.                                                                                                            |
| `hipaa`              | Sua organização tem a prontidão para HIPAA habilitada.                                                                                                                                               |
| `inference_hooks`    | Sua organização tem Inference hooks ativados.                                                                                                                                                        |

A API pode adicionar valores a esta lista. Se você receber um valor que não reconhece, envie a conversa completa sem `thread`. Uma requisição que atende a várias dessas condições recebe um erro que nomeia apenas uma.

## Limitações

* Não há API para listar, ler ou excluir uma thread.
* As threads estão disponíveis na Claude API, no [Claude Platform on AWS](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-platform-on-aws), no Claude Models on Google Cloud (Anthropic managed), e no [Claude in Microsoft Foundry](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-in-microsoft-foundry).

## Preços e limites de taxa

As threads não alteram os preços nem os [limites de taxa](https://platform.claude.com/docs/pt-BR/api/rate-limits).

## Retenção de dados

As threads de mensagens não são elegíveis para ZDR. Usar este recurso não afeta seu uso de outros recursos elegíveis para ZDR. A API mantém uma thread em memória, criptografada com uma chave gerenciada pelo servidor, nunca a grava em armazenamento durável e a exclui no máximo 1 hora após seu último uso.

Uma thread contém a conversa que a API envia ao modelo, o `system` e as `tools` da requisição de criação, e uma impressão digital dos campos fixos, que ela usa para verificar requisições posteriores. Ela mantém arquivos por referência, então mantenha disponível cada arquivo que a conversa usa enquanto você usar a thread.

Para a elegibilidade para ZDR em todos os recursos, consulte [API e retenção de dados](https://platform.claude.com/docs/pt-BR/manage-claude/api-and-data-retention).

## Veja também

* [Cache de prompt](https://platform.claude.com/docs/pt-BR/build-with-claude/prompt-caching)
* [Streaming](https://platform.claude.com/docs/pt-BR/build-with-claude/streaming)
* [Erros](https://platform.claude.com/docs/pt-BR/api/errors)

## Disponibilidade

Threads de mensagens estão em beta em todos os modelos.

### Suporte da API

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

* Disponibilidade: Disponível

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

### Headers beta obrigatórios

[Visão geral dos headers beta](https://platform.claude.com/docs/pt-BR/api/beta-headers)

Os headers beta permitem que você acesse recursos experimentais e novas capacidades de modelos antes que eles se tornem parte da API padrão.

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

### Tratamento de dados

[Visão geral do tratamento de dados](https://platform.claude.com/docs/pt-BR/manage-claude/api-and-data-retention#feature-eligibility)

| Item     | Retenção zero de dados                                                                                                                                                                                                                                                                                                                                                                                                                           | HIPAA        |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ |
| Status   | Não elegível                                                                                                                                                                                                                                                                                                                                                                                                                                     | Não elegível |
| Detalhes | O conteúdo de uma thread (a conversa, o prompt do sistema e as ferramentas) é mantido na memória, criptografado com uma chave gerenciada pelo servidor, nunca é gravado em armazenamento durável e é excluído no máximo 1 hora após o último uso da thread. O uso deste recurso não afeta o seu uso de outros recursos elegíveis para ZDR. [Saiba mais](https://platform.claude.com/docs/pt-BR/build-with-claude/message-threads#data-retention) | —            |

Endpoints aplicáveis:

* `/v1/messages` com `thread`
