---
title: Hilos de mensajes
url: https://platform.claude.com/docs/es/build-with-claude/message-threads
description: Ofrece a los agentes de larga duración un tiempo hasta el primer token más rápido, especialmente en conversaciones largas, enviando solo los mensajes nuevos en cada solicitud.
featureMetadata:
  status: beta
  betaHeader: message-threads-2026-08-12
  zdr:
    eligibility: not-eligible
    note: El contenido de un hilo (la conversación, la indicación del sistema y las herramientas) se mantiene en memoria, cifrado con una clave administrada por el servidor, nunca se escribe en almacenamiento duradero y se elimina como máximo 1 hora después del último uso del hilo. Usar esta función no afecta tu uso de otras funciones elegibles 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
---

Con un “message thread” (hilo de mensajes), las solicitudes son más pequeñas, y el “time to first token” (tiempo hasta el primer token) se mantiene más bajo y más estable a medida que crece la conversación. Los hilos son más útiles en bucles de agente largos. Sin un hilo, cada turno vuelve a subir toda la conversación, y la API vuelve a validarla y tokenizarla por completo. Con un hilo, la mayor parte de ese trabajo abarca solo el turno nuevo.

Un “message thread” (hilo de mensajes) mantiene una conversación en el servidor durante un tiempo breve. Envías la conversación completa una vez, con tu indicación del sistema y tus herramientas. En cada turno posterior, envías solo los mensajes nuevos y el `id` de la respuesta anterior. La API reconstruye la conversación antes de llamar al modelo. Agregas un parámetro, `thread`, a una solicitud de la [Messages API](https://platform.claude.com/docs/es/api/messages). La respuesta es el mensaje habitual.

<Note>
  Los hilos de mensajes son diferentes de los [hilos de sesión](https://platform.claude.com/docs/es/managed-agents/session-threads) en Claude Managed Agents.
</Note>

## Cómo funcionan los hilos de mensajes

* **Crear.** Envía tu primera solicitud como lo haces hoy, con la conversación completa, `system` y `tools`, y agrega `"thread": {"type": "create"}`. La API almacena la conversación, incluida la respuesta de Claude, bajo el `id` de la respuesta.
* **Continuar.** Envía solo los mensajes posteriores a la respuesta anterior y agrega `"thread": {"type": "continue", "previous_message_id": "<previous id>"}`. Deja `system` y `tools` fuera de la solicitud. El hilo conserva los valores de la solicitud de creación. Usa cada nuevo `id` de respuesta para el siguiente turno.
* **Reproducir.** Un hilo funciona según el mejor esfuerzo. Expira 5 minutos después de su última solicitud, y la API lo elimina como máximo 1 hora después de su último uso. Cada respuesta que la API almacena reinicia los 5 minutos. Si la API ya no puede continuar el hilo, una solicitud de continuación devuelve un error 404. Envía de nuevo la conversación completa en una nueva solicitud de creación y continúa desde el `id` de esa respuesta. El helper de hilos del SDK hace esta reproducción por ti (consulta [Cómo se comporta el helper del SDK](https://platform.claude.com/docs/es/build-with-claude/message-threads#sdk-helper-handles)). Después de una respuesta de un modelo de respaldo, consulta [Usar respaldos con un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#fallbacks).

Tu aplicación sigue siendo la fuente de verdad de la conversación. Conserva tu propia copia de cada mensaje y construye la [ruta de reproducción](https://platform.claude.com/docs/es/build-with-claude/message-threads#recover) desde el principio. Ninguna respuesta, ya sea a una solicitud de creación o de continuación, indica si la API almacenó ese turno. Lo descubres en la siguiente solicitud de continuación. El helper de hilos del SDK mantiene esta copia en memoria mientras existe el objeto helper, y no la guarda en ningún otro lugar. Si la conversación tiene que sobrevivir a tu proceso, conserva tu propia copia.

## Usar un hilo con un SDK

El SDK tiene un helper de hilos que construye las solicitudes del hilo por ti. Créalo con los mismos campos que una solicitud de Messages y luego envíale un turno a la vez. El helper mantiene la conversación completa en memoria.

Este ejemplo tiene dos turnos. El helper crea un hilo en el primer turno y lo continúa en el segundo, y agrega el encabezado beta por ti. El `cache_control` de nivel superior es opcional. Solicita el “prompt caching” (almacenamiento en caché de prompts) en cada turno (consulta [Almacenamiento en caché de prompts en un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#prompt-caching)). Sin él, cada turno posterior sigue enviando solo los mensajes nuevos, pero no se almacena nada en caché a menos que agregues puntos de interrupción de caché tú mismo.

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

  # Crea el helper. Esta llamada no envía ninguna solicitud.
  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: el helper crea un hilo y envía la conversación completa
  thread.send({"role": "user", "content": "Hi! I have a question about an order."})

  # Turno 2: el helper continúa el hilo y envía solo el mensaje nuevo
  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();

  // Crea el helper. Esta llamada no envía ninguna solicitud.
  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: el helper crea un hilo y envía la conversación completa
  await thread.send({ role: "user", content: "Hi! I have a question about an order." });

  // Turno 2: el helper continúa el hilo y envía solo el mensaje nuevo
  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();

  // Crea el helper. Esta llamada no envía ninguna solicitud.
  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: el helper crea un hilo y envía la conversación completa
  await thread.Send(
      new BetaUserMessageParam { Content = "Hi! I have a question about an order." }
  );

  // Turno 2: el helper continúa el hilo y envía solo el mensaje nuevo
  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()

  // Crea el helper. Esta llamada no envía ninguna solicitud.
  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: el helper crea un hilo y envía la conversación 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: el helper continúa el hilo y envía solo el mensaje nuevo
  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();

  // Crea el helper. Esta llamada no envía ninguna solicitud.
  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: el helper crea un hilo y envía la conversación completa
  thread.send("Hi! I have a question about an order.");

  // Turno 2: el helper continúa el hilo y envía solo el mensaje nuevo
  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();

  // Crea el helper. Esta llamada no envía ninguna solicitud.
  $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: el helper crea un hilo y envía la conversación completa
  $thread->send(['role' => 'user', 'content' => 'Hi! I have a question about an order.']);

  // Turno 2: el helper continúa el hilo y envía solo el mensaje nuevo
  $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

  # Crea el helper. Esta llamada no envía ninguna solicitud.
  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: el helper crea un hilo y envía la conversación completa
  thread.send_message({role: "user", content: "Hi! I have a question about an order."})

  # Turno 2: el helper continúa el hilo y envía solo el mensaje nuevo
  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 el campo `thread` tú mismo

Para construir las solicitudes del hilo tú mismo, por ejemplo con cURL, la CLI o el método `create` habitual de un SDK, agrega el campo `thread` a cada solicitud.

Envía el encabezado beta `message-threads-2026-08-12` en cada solicitud de un hilo.

Este ejemplo crea un hilo en el primer turno y lo continúa en el segundo. El `cache_control` de nivel superior solicita el almacenamiento en caché de prompts en cada turno. Surte efecto una vez que la conversación supera la [longitud mínima almacenable en caché](https://platform.claude.com/docs/es/build-with-claude/prompt-caching).

<CodeGroup>
  ```bash cURL
  # Turno 1: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo. Establece message_id con el id de la respuesta del turno 1.
  # Omite system y tools: el hilo los conserva.
  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: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo. Establece message_id en el id de la respuesta del turno 1.
  # Omite system y tools: el hilo los conserva.
  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: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo y el id de la respuesta del turno 1.
  # Omite system y tools: el hilo los conserva.
  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: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo y el id de la respuesta del turno 1.
  // Omite system y tools: el hilo los conserva.
  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: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo y el id de la respuesta del turno 1.
  // Omite System y Tools: el hilo los conserva.
  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: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo y el id de la respuesta del turno 1.
  // Omite System y Tools: el hilo los conserva.
  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: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo y el id de la respuesta del turno 1.
  // Omite system y tools: el hilo los conserva.
  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: envía la conversación completa y crea un hilo
  $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: envía solo el mensaje nuevo y el id de la respuesta del turno 1.
  // Omite system y tools: el hilo los conserva.
  $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: envía la conversación completa y crea un hilo
  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: envía solo el mensaje nuevo y el id de la respuesta del turno 1.
  # Omite system_ y tools: el hilo los conserva.
  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>

## Qué enviar en cada solicitud

| Grupo            | Campos                                                                                                                                                                                                                                                       | Regla                                                                                                                                                                                                                                    |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Solo de creación | `system`, `tools`                                                                                                                                                                                                                                            | Envíalos solo en la solicitud de creación, con cualquier punto de interrupción `cache_control` en ellos. Enviar cualquiera de los dos en una solicitud de continuación, incluso como `null`, devuelve un error 400.                      |
| Fijos            | `model`, `tool_choice`, `thinking`, `mcp_servers` (aparte del token de autorización de cada servidor), `context_management`, `output_config`, las `skills` en `container`, el `cache_control` de nivel superior y el conjunto de valores de `anthropic-beta` | Envíalos en cada solicitud del hilo, con los mismos valores que en la solicitud de creación. Un valor diferente devuelve un error 400 con el código `thread_fingerprint_mismatch`, y el mensaje de error nombra los campos que difieren. |
| Libres           | `max_tokens`, `stop_sequences`, `stream`, `metadata`, `service_tier` y otros campos no mencionados en esta página                                                                                                                                            | Pueden cambiar de un turno a otro.                                                                                                                                                                                                       |

La API no almacena las URL de los servidores MCP, los tokens de autorización de MCP ni el `id` del contenedor. Envía `mcp_servers` y `container` en cada solicitud que los use. Un token de autorización de MCP puede cambiar entre solicitudes.

El helper de hilos del SDK deja `system` y `tools` fuera de las solicitudes de continuación por ti y vuelve a enviar los campos fijos en cada turno.

Si usas el [respaldo del lado del servidor](https://platform.claude.com/docs/es/build-with-claude/refusals-and-fallback#server-side-fallback), envía el campo `fallbacks` en todas las solicitudes de un hilo o en ninguna. Consulta [Usar respaldos con un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#fallbacks).

Para cambiar un campo solo de creación o fijo, inicia un nuevo hilo: envía la conversación completa en una solicitud de creación con los nuevos valores.

En Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5, cambiar `system` o `tools` invalida los bloques `thinking` y `redacted_thinking` que ya están en la conversación, y la solicitud de creación puede devolver un error 400. Para evitarlo, deja fuera todos los bloques `thinking` y `redacted_thinking` de la conversación que envías. El modelo responde entonces sin ese razonamiento anterior. Consulta [Qué cuenta como una edición](https://platform.claude.com/docs/es/build-with-claude/preserved-thinking#what-counts-as-an-edit), [Cuando `prefix_mismatch_behavior` no está establecido](https://platform.claude.com/docs/es/build-with-claude/preserved-thinking#enforcement) y [Qué hace la API con un bloque no válido](https://platform.claude.com/docs/es/build-with-claude/preserved-thinking#mismatch-behavior).

Envía solo los mensajes nuevos en una solicitud de continuación. La API no los compara con los mensajes que ya tiene. Un mensaje que vuelvas a enviar puede aparecer dos veces en la conversación, o la solicitud puede devolver un error. Por ejemplo, una solicitud de continuación que empieza con la respuesta anterior devuelve un error.

Los mensajes nuevos suelen comenzar con un mensaje `user`: tu siguiente turno de usuario, o los bloques `tool_result` que responden a un `tool_use` en la respuesta anterior. Si una respuesta se detiene con [`stop_reason: "pause_turn"`](https://platform.claude.com/docs/es/build-with-claude/handling-stop-reasons#pause-turn), reanúdala con una solicitud de continuación desde el `id` de esa respuesta y una lista `messages` vacía (`"messages": []`). Si esa solicitud devuelve un error 404, reproduce la conversación completa, incluida la respuesta pausada, en una nueva solicitud de creación. No envíes un nuevo mensaje `user` mientras el turno está pausado: la API lo rechaza. Con el helper de hilos del SDK, llama a `send()` (go, csharp: `Send()`; ruby: `send_message()`) sin mensajes: el helper envía esta solicitud y reproduce la conversación ante un error 404.

Un hilo es de solo anexado, y cada `id` de respuesta se puede continuar una vez. Continúa siempre desde el `id` de respuesta más reciente del hilo. Para editar o ramificar un mensaje anterior, inicia un nuevo hilo con una solicitud de creación. Para reemplazar turnos anteriores con un resumen, consulta [Compactar una conversación](https://platform.claude.com/docs/es/build-with-claude/message-threads#compaction).

## Almacenamiento en caché de prompts en un hilo

Un hilo no almacena tu prompt en caché por ti. El [almacenamiento en caché de prompts](https://platform.claude.com/docs/es/build-with-claude/prompt-caching) funciona igual que sin un hilo: tú eliges dónde van los puntos de interrupción de caché.

Para almacenar en caché cada turno, envía un `cache_control` de nivel superior en cada solicitud del hilo, como en el ejemplo anterior. La API lo aplica al último bloque de los `messages` de cada solicitud que se pueda almacenar en caché. Así, cada turno lee la conversación anterior desde la caché y escribe el turno nuevo en ella. El `cache_control` de nivel superior es un campo fijo: envía el mismo valor en cada solicitud.

También puedes colocar puntos de interrupción `cache_control` en bloques tú mismo:

* Los puntos de interrupción que envías en la solicitud de creación siguen funcionando en cada turno posterior si están en `tools`, en `system` o en un bloque de mensaje anterior al último. Un punto de interrupción en el último bloque de los `messages` de una solicitud escribe la caché en esa solicitud. Para almacenar en caché cada turno nuevo, envía un punto de interrupción en cada solicitud. Una solicitud sin un punto de interrupción aún podría leer parte de la conversación desde la caché.
* No puedes mover ni eliminar un punto de interrupción después de enviarlo, porque una solicitud de continuación no puede volver a enviar un mensaje anterior.
* Una solicitud con `thread` puede llevar como máximo 4 puntos de interrupción `cache_control`. El `cache_control` de nivel superior cuenta como uno. Los puntos de interrupción en `system` y `tools` de la solicitud de creación vuelven a contar en cada solicitud de continuación. Los puntos de interrupción en mensajes anteriores almacenados no cuentan. Un punto de interrupción de más devuelve un error 400 con el código `thread_unsupported_request`.
* Si colocas tú mismo puntos de interrupción en bloques de mensajes, elimínalos de los mensajes anteriores cuando reproduzcas la conversación en una nueva solicitud de creación, y conserva uno en el último bloque, para que la solicitud se mantenga dentro del límite de 4.

## Streaming

Los hilos funcionan con [streaming](https://platform.claude.com/docs/es/build-with-claude/streaming). El `id` de la respuesta llega en el evento `message_start`, pero continúa desde él solo después de recibir el evento `message_stop`. Una solicitud de continuación enviada antes puede devolver un error 404.

Si el stream de una solicitud de continuación se interrumpe antes de `message_stop`, vuelve a enviar la misma solicitud de continuación. Si esa solicitud devuelve un error `thread_already_continued` o `thread_continue_in_flight`, reenvía la conversación completa en una nueva solicitud de creación.

Es posible que tu conexión se haya interrumpido mientras el servidor todavía generaba la respuesta, o después de que el servidor la guardara. Por eso la API puede rechazar el reintento. Reenviar siempre es seguro.

El helper de hilos del SDK no reintenta la solicitud de continuación después de un stream interrumpido. Consulta [Cómo se comporta el helper del SDK](https://platform.claude.com/docs/es/build-with-claude/message-threads#sdk-helper-handles).

## Recuperarse cuando un hilo no se puede continuar

Una solicitud de continuación devuelve un error 404 con `error.details.error_code` establecido en `thread_not_found` cuando la API no puede continuar el hilo. La respuesta no indica el motivo. Las causas incluyen las siguientes:

* El hilo expiró.
* La API sirvió el turno anterior pero no lo almacenó. Por ejemplo, la API no almacena una respuesta que termina en una llamada a herramienta cortada por `max_tokens`.
* Un modelo de respaldo escribió la respuesta anterior. Consulta [Usar respaldos con un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#fallbacks).
* La respuesta anterior todavía se está generando.
* La solicitud proviene de una organización o un espacio de trabajo diferente.
* La solicitud proviene de un usuario o una cuenta de servicio diferente de la que creó el hilo. Un hilo creado con una [clave de espacio de trabajo (heredada)](https://platform.claude.com/docs/es/manage-claude/authentication#key-types) permanece con esa clave, así que usa la misma clave para todo el hilo.
* Los mensajes nuevos agregan algo que la conversación almacenada no puede aceptar. Por ejemplo, la primera imagen en una conversación que no tenía ninguna puede devolver este error.

Para recuperarte, envía la conversación completa desde tu propia copia en una nueva solicitud de creación, con `system` y `tools`. El helper de hilos del SDK envía esta solicitud de creación una vez por sí mismo, y omite los puntos de interrupción `cache_control` de turnos anteriores al hacerlo. Si los mensajes anteriores de tu copia llevan puntos de interrupción `cache_control`, elimínalos primero (consulta [Almacenamiento en caché de prompts en un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#prompt-caching)). Luego continúa a partir del `id` de la nueva respuesta. Si un modelo de respaldo escribió la respuesta anterior, consulta [Usar respaldos con un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#fallbacks). Para descartar las causas relacionadas con la propiedad, usa la misma clave de API y el mismo espacio de trabajo para cada solicitud de un hilo. En Claude Platform on AWS, firma cada solicitud de un hilo con credenciales del rol de IAM o del usuario de IAM que lo creó.

Una solicitud para un modelo que no existe también devuelve un error 404, así que revisa `error.details.error_code` antes de reenviar.

Si una solicitud de continuación sigue devolviendo un error 404 justo después de reproducir la conversación, es posible que la API no pueda almacenar esa conversación, por ejemplo una muy grande. Envíala sin `thread`. El helper de hilos del SDK hace esto cuando lo creas con `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`) establecido en `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`). De lo contrario, reproduce la conversación en cada turno.

### Después de un rechazo

Cuando una respuesta tiene `stop_reason: "refusal"`, no continúes el hilo. Es posible que la API ya contenga el turno rechazado, y una solicitud de continuación no puede eliminarlo. Inicia un nuevo hilo con una solicitud de creación que omita o reformule el turno que provocó el rechazo. Consulta [Rechazos y respaldo](https://platform.claude.com/docs/es/build-with-claude/refusals-and-fallback). El helper de hilos del SDK hace esto por ti: no conserva el turno rechazado, y su siguiente turno inicia un nuevo hilo.

### Usar respaldos con un hilo

El [respaldo del lado del servidor](https://platform.claude.com/docs/es/build-with-claude/refusals-and-fallback#server-side-fallback) está disponible con hilos en la Claude API. Decide al crear el hilo: envía `fallbacks` en todas las solicitudes del hilo, o en ninguna. El valor de `fallbacks` puede cambiar entre solicitudes. Una solicitud de continuación que agrega o quita `fallbacks` devuelve un error 400 con el código `thread_fingerprint_mismatch`.

Un hilo conserva un solo modelo, por lo que la API no almacena un turno escrito por un modelo de respaldo. Recibes la respuesta como de costumbre, pero no puedes continuar desde su `id`. Después de cada respuesta, sigue estos pasos:

1. Si `stop_reason` es `"refusal"`, sigue [Después de un rechazo](https://platform.claude.com/docs/es/build-with-claude/message-threads#after-a-refusal).

2. De lo contrario, busca una entrada `fallback_message` en `usage.iterations`. En un stream, léela del evento `message_delta` final. Si no hay ninguna, continúa el hilo como de costumbre.

3. Si hay una, un modelo de respaldo escribió la respuesta. Envía la conversación completa, incluida esa respuesta y tu siguiente mensaje, en una nueva solicitud de creación. Mantén el encabezado beta `server-side-fallback-2026-07-01` en ella. Elige una de estas dos solicitudes:

   * **La misma solicitud de nuevo.** Mantén `model`, `fallbacks` y tus demás parámetros como estaban. Si responde el modelo que solicitaste, la API almacena el nuevo hilo. Si responde un modelo de respaldo, la respuesta vuelve a tener una entrada `fallback_message` y la API no la almacena, así que repite este paso en el siguiente turno. El [enrutamiento persistente](https://platform.claude.com/docs/es/build-with-claude/refusals-and-fallback#sticky-routing) podría enviar estas solicitudes directamente al modelo de respaldo, por lo que cada turno podría enviar la conversación completa. El helper de hilos del SDK funciona de esta manera.
   * **Un nuevo hilo en el modelo de respaldo.** Establece `model` en el `model` de esa entrada `fallback_message`, omite `fallbacks` y usa parámetros que este modelo acepte. La API almacena este hilo de inmediato, y permanece en el modelo de respaldo. Es posible que el intento de respaldo se haya ejecutado con una configuración diferente a la que enviaste, por lo que la API podría rechazar valores copiados de tu primera solicitud.

4. Vuelve al paso 1 con la respuesta a esa solicitud. Cuando no tenga ninguna entrada `fallback_message`, continúa el nuevo hilo a partir de su `id`.

El [enrutamiento persistente](https://platform.claude.com/docs/es/build-with-claude/refusals-and-fallback#sticky-routing) comienza después de que una solicitud recurre al respaldo (una solicitud de creación, o una solicitud sin `thread`). Durante aproximadamente una hora, podría enviar las solicitudes de creación posteriores de la misma conversación que incluyan `fallbacks` directamente al modelo de respaldo, sin intentar el modelo que solicitaste. La API no almacena ninguno de esos turnos, y cada uno que recibe respuesta reinicia ese plazo de una hora. Una solicitud de continuación nunca inicia este enrutamiento ni lo usa. El enrutamiento persistente no se aplica si tu organización o espacio de trabajo usa retención de datos cero o claves de cifrado administradas por el cliente.

## Compactar una conversación

Un hilo es de solo anexado, así que no puedes reemplazar sus turnos anteriores con un resumen. Para compactar una conversación, inicia un nuevo hilo a partir del resumen. Escribe el resumen en tu código y envíalo como un mensaje normal en una nueva solicitud de creación, con `system` y `tools`. La [compactación bajo demanda](https://platform.claude.com/docs/es/build-with-claude/compaction-on-demand) no está disponible con hilos (consulta [Funciones que los hilos no admiten](https://platform.claude.com/docs/es/build-with-claude/message-threads#unsupported)).

## Cómo se comporta el helper del SDK

Lo que el helper hace por ti:

* Agrega el encabezado beta `message-threads-2026-08-12` a cada solicitud que usa el hilo.
* Crea un hilo en el primer turno y lo continúa después de eso, enviando solo los mensajes nuevos y omitiendo `system` y `tools`.
* Reproduce la conversación completa una vez en una nueva solicitud de creación cuando una solicitud de continuación devuelve `thread_not_found`, `thread_already_continued` o `thread_continue_in_flight`.
* Reanuda una respuesta `pause_turn` cuando llamas a `send()` (go, csharp: `Send()`; ruby: `send_message()`) sin mensajes.
* Inicia un nuevo hilo después de un rechazo. Recibes la respuesta `stop_reason: "refusal"` como de costumbre, pero el helper no conserva ese turno: retira los mensajes que le diste a esa llamada. Los mensajes que agregaste con `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`), o que proporcionaste al crear el helper, permanecen preparados. Tu siguiente turno los envía junto con la conversación anterior al turno rechazado, en una nueva solicitud de creación. Envía un mensaje reformulado o, si un mensaje preparado provocó el rechazo, inicia un nuevo hilo a partir de los params sin él.
* Envía una nueva solicitud de creación después de una respuesta de un modelo de respaldo. Cuando una respuesta tiene una entrada `fallback_message` en `usage.iterations`, el helper conserva la respuesta y envía la conversación completa en una nueva solicitud de creación en el siguiente turno. No espera un error 404. Esa solicitud conserva el `model` y los `fallbacks` que configuraste.
* Omite los puntos de interrupción `cache_control` de turnos anteriores cada vez que los vuelve a enviar, por ejemplo en una reproducción o en el primer turno de una bifurcación. Tus mensajes más recientes, `system`, `tools` y el `cache_control` de nivel superior se envían tal como los proporcionaste.

Lo que manejas tú mismo:

* **Respaldos.** Mientras la API siga respondiendo desde un modelo de respaldo, el helper envía la conversación completa en una nueva solicitud de creación en cada turno, porque la API no almacena ninguno de esos turnos. Vuelve a las solicitudes de continuación después de una respuesta del modelo que solicitaste. Para mover la conversación al modelo de respaldo en su lugar, inicia un nuevo hilo a partir de los params con ese `model` y sin `fallbacks`, como en [Usar respaldos con un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#fallbacks).
* **Streams interrumpidos.** Si un stream termina a mitad de una respuesta, el helper conserva los bloques terminados y cualquier texto que haya llegado, y el siguiente turno envía la conversación completa en una nueva solicitud de creación. El helper no reintenta por sí mismo: para volver a enviar el turno interrumpido, llama a `send()` (go, csharp: `Send()`; ruby: `send_message()`) sin mensajes. Si la parte conservada termina en llamadas a herramientas, respóndelas en tu siguiente mensaje. Si dejas de leer un stream después de que muestra `stop_reason: "refusal"`, el helper trata ese turno como un rechazo.
* **Otros errores.** Los errores `thread_fingerprint_mismatch` y `thread_unsupported_request` llegan a tu código. Para continuar sin `thread` después de un error `thread_unsupported_request`, crea el helper con `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`) establecido en `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`). Con esa configuración, el helper también deja de usar `thread` cuando la primera solicitud de continuación después de una reproducción vuelve a devolver `thread_not_found`. Es posible que la API no pueda almacenar esa conversación. Sin esa configuración, el helper reproduce la conversación en cada turno. Un ejecutor de herramientas que crea su propio hilo usa esa configuración de forma predeterminada.

El ejecutor de herramientas beta del SDK también usa un hilo de forma predeterminada, lo cual puedes desactivar al crear el ejecutor.

### Otros métodos del helper

| Para hacer esto                                               | Usa                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Hacer streaming de un turno                                   | `thread.stream(...)` (csharp: `thread.SendStreaming(...)`; go: `thread.SendStreaming(ctx, params)`; java: `thread.sendStreaming(...)`; php: `$thread->sendStream(...)`)                                                                                                                                                              |
| Respuesta finalizada de un turno con streaming                | `stream.get_final_message()` (typescript: `stream.finalMessage()`; csharp: `thread.LastMessage`; go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`; ruby: `stream.accumulated_message`)                                                                                                        |
| Conversación completa                                         | `thread.messages` (csharp: `thread.Messages`; go: `thread.Messages()`; java: `thread.messages()`; php: `$thread->messages()`)                                                                                                                                                                                                        |
| `id` de la respuesta desde la que continúa el siguiente turno | `thread.previous_message_id` (typescript: `thread.previousMessageId`; csharp: `thread.PreviousMessageID`; go: `thread.PreviousMessageID()`; java: `thread.previousMessageId()`; php: `$thread->previousMessageId()`)                                                                                                                 |
| Agregar mensajes sin enviarlos                                | `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`)                                                                                                                                                                                                                                                 |
| Cambiar campos para turnos posteriores                        | `thread.update(...)` (csharp: `thread.Update(p => p with { ... })`; go: `thread.Params.MaxTokens = ...`; java: `thread.update(b -> ...)`; php: `$thread->update([...])`)                                                                                                                                                             |
| Copiar el hilo                                                | `thread.fork()` (csharp, go: `thread.Fork()`; php: `$thread->fork()`; ruby: `thread.fork`)                                                                                                                                                                                                                                           |
| Campos y conversación, para iniciar un nuevo hilo             | `thread.params` (csharp, go: `thread.Params`; java: `thread.params()`; php: `$thread->params()`)                                                                                                                                                                                                                                     |
| Ejecutor de herramientas en este hilo                         | `thread.tool_runner()` (typescript, java: `thread.toolRunner()`; csharp: `thread.ToolRunner(tools)`; go: `thread.NewToolRunner(tools)`; php: `$thread->toolRunner()`; ruby: `thread.tool_runner`)                                                                                                                                    |
| Ejecutor de herramientas sin un hilo                          | `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.** El helper registra la respuesta cuando el stream llega a `message_stop`, así que lee el stream hasta el final. Si dejas de leer antes, finaliza el stream para que el hilo quede libre para el siguiente turno:

* Python: sal del bloque `with`.
* TypeScript: sal del bucle o llama a `abort()`.
* Go: llama a `Close`.
* Java y Ruby: llama a `close()`.
* C#: libera el enumerador. Salir de `await foreach` hace esto.
* PHP: llama a `close()`.

En C#, la solicitud se envía cuando empiezas a leer el stream.

En C#, Go, Java y PHP, después de un rechazo `thread.LastMessage` (go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`) sigue devolviendo la respuesta del turno anterior, o nada en un primer turno. Lee el rechazo desde los eventos del stream.

**Cambiar campos.** Una actualización no envía nada y se aplica a cada turno posterior. Una vez que un hilo tiene una respuesta, el helper rechaza un turno que cambie `system` o `tools`, y la API rechaza un cambio en cualquier otro campo fijo (consulta [Qué enviar en cada solicitud](https://platform.claude.com/docs/es/build-with-claude/message-threads#what-to-send)). Para cambiar uno de estos campos, inicia un nuevo hilo a partir de los params, o bifurca el hilo y actualiza la bifurcación antes de su primer turno.

**Bifurcar.** Una bifurcación copia la conversación, los campos y las opciones de solicitud, y no envía nada. Su primer turno envía la conversación completa en una nueva solicitud de creación, y los dos hilos son independientes a partir de ahí. Una bifurcación siempre parte de toda la conversación, no de una respuesta anterior.

**Params.** Los params contienen los campos del helper y la conversación completa. Pásalos al método que crea un helper para iniciar un nuevo hilo, por ejemplo con un `system` diferente (consulta [Qué enviar en cada solicitud](https://platform.claude.com/docs/es/build-with-claude/message-threads#what-to-send)), o con `messages` recortado para descartar turnos posteriores. Un hilo que inicias a partir de los params envía cada mensaje tal como lo proporcionaste, incluidos los puntos de interrupción de `cache_control`, así que mantente dentro del límite de 4 (consulta [Almacenamiento en caché de prompts en un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#prompt-caching)). Excepto en Ruby, los params omiten las opciones de solicitud, así que pásalas de nuevo.

**Salida estructurada.** Indica el formato de salida al crear el helper. Un turno posterior no puede cambiarlo. La forma de obtener el resultado analizado depende del SDK:

* Python y TypeScript: llama a `thread.parse(...)`.
* C#: crea el helper con `client.Beta.Messages.Thread<T>(...)`.
* Go: `Send` deserializa en la estructura a la que apunta `Params.OutputConfig.Format.Schema`.
* Java: crea el helper con `thread(...)` y `outputConfig(MyClass.class)`.
* PHP: `send()` establece `parsed` en los bloques de texto cuando `outputConfig` nombra una clase de modelo.
* Ruby: pasa `output_config: {format: MyModel}` a `thread(...)` y luego lee `reply.parsed_output`.

## Errores

La API devuelve los errores de esta tabla antes de que se ejecute el modelo. La solicitud no usa tokens, y el hilo y su tiempo de expiración no cambian. `error.type` es `invalid_request_error` para los errores 400 y `not_found_error` para el error 404.

| Estado | `error_code`                  | Significado                                                                                                                                               | Qué hacer                                                                                                      |
| ------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| 404    | `thread_not_found`            | La API no puede continuar el hilo.                                                                                                                        | Envía la conversación completa en una nueva solicitud de creación.                                             |
| 400    | `thread_fingerprint_mismatch` | Un campo fijo difiere del valor almacenado con el hilo. El mensaje de error nombra los campos.                                                            | Mantén los campos fijos iguales, o inicia un nuevo hilo para cambiar uno.                                      |
| 400    | `thread_already_continued`    | Cada `id` de respuesta se puede continuar una vez.                                                                                                        | Continúa desde el `id` de respuesta más reciente del hilo. Si tu cliente nunca recibió esa respuesta, reenvía. |
| 400    | `thread_continue_in_flight`   | Otra solicitud de continuación desde este `id` de respuesta todavía se está ejecutando. Normalmente es tu propio intento anterior.                        | Deja que termine y continúa desde su `id` de respuesta, o reenvía.                                             |
| 400    | `thread_unsupported_request`  | La solicitud usa una función o una configuración de la organización que los hilos no admiten. `error.details.unsupported` la nombra cuando está presente. | Elimina esa función de la solicitud, o envía la conversación completa sin `thread`.                            |

Algunos errores 400 de solicitudes de hilo no llevan `error_code`, por ejemplo una solicitud de continuación sin `previous_message_id`, o una que incluye `system` o `tools`.

El siguiente ejemplo muestra el cuerpo de un error:

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

## Funciones que los hilos no admiten

Los hilos no admiten estas funciones:

* [Message Batches](https://platform.claude.com/docs/es/build-with-claude/batch-processing). Un elemento de solicitud que incluye `thread` termina con un `invalid_request_error` en los resultados del lote.
* [Conteo de tokens](https://platform.claude.com/docs/es/build-with-claude/token-counting). Una solicitud de conteo de tokens que incluye `thread` devuelve un error 400. En su lugar, cuenta la conversación completa, con `system` y `tools`.
* [Compactación](https://platform.claude.com/docs/es/build-with-claude/compaction). La [compactación bajo demanda](https://platform.claude.com/docs/es/build-with-claude/compaction-on-demand) no está disponible con hilos. Una solicitud que incluye `thread` devuelve un error 400 si establece el parámetro `compaction`, o si envía un bloque `compaction` con el encabezado beta `compact-2026-09-04`. Consulta [Compactar una conversación](https://platform.claude.com/docs/es/build-with-claude/message-threads#compaction).
* [Edición de contexto](https://platform.claude.com/docs/es/build-with-claude/context-editing), excepto `clear_thinking_20251015` con `keep: "all"`.
* Organizaciones que tienen habilitada la [preparación para HIPAA](https://platform.claude.com/docs/es/manage-claude/api-and-data-retention#hipaa-readiness).
* Organizaciones que tienen activados los [Inference hooks](https://platform.claude.com/docs/es/manage-claude/inference-hooks).

La API rechaza la mayoría de las solicitudes que los hilos no admiten con un error 400 y el código `thread_unsupported_request`. Cuando `error.details.unsupported` está presente, contiene uno de estos valores:

| Valor                | Significado                                                                                                                                                                                                         |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `context_management` | La solicitud usa gestión de contexto o compactación que los hilos no admiten.                                                                                                                                       |
| `cache_control`      | La solicitud tiene más de 4 puntos de interrupción `cache_control`. Consulta [Almacenamiento en caché de prompts en un hilo](https://platform.claude.com/docs/es/build-with-claude/message-threads#prompt-caching). |
| `fallbacks`          | La solicitud establece `fallbacks`, y tu organización no puede usar `fallbacks` con hilos.                                                                                                                          |
| `hipaa`              | Tu organización tiene habilitada la preparación para HIPAA.                                                                                                                                                         |
| `inference_hooks`    | Tu organización tiene activados los Inference hooks.                                                                                                                                                                |

La API puede agregar valores a esta lista. Si recibes un valor que no reconoces, envía la conversación completa sin `thread`. Una solicitud que cumple varias de estas condiciones recibe un error que nombra solo una.

## Limitaciones

* No hay ninguna API para listar, leer o eliminar un hilo.
* Los hilos están disponibles en la Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/es/build-with-claude/claude-platform-on-aws), Claude Models on Google Cloud (Anthropic managed), y [Claude in Microsoft Foundry](https://platform.claude.com/docs/es/build-with-claude/claude-in-microsoft-foundry).

## Precios y límites de velocidad

Los hilos no cambian los precios ni los [límites de velocidad](https://platform.claude.com/docs/es/api/rate-limits).

## Retención de datos

Los hilos de mensajes no son elegibles para ZDR. Usar esta función no afecta tu uso de otras funciones elegibles para ZDR. La API mantiene un hilo en memoria, cifrado con una clave administrada por el servidor, nunca lo escribe en almacenamiento duradero y lo elimina como máximo 1 hora después de su último uso.

Un hilo contiene la conversación que la API envía al modelo, el `system` y las `tools` de la solicitud de creación, y una huella de los campos fijos, que usa para verificar las solicitudes posteriores. Contiene los archivos por referencia, así que mantén disponibles todos los archivos que usa la conversación mientras uses el hilo.

Para conocer la elegibilidad para ZDR de todas las funciones, consulta [API y retención de datos](https://platform.claude.com/docs/es/manage-claude/api-and-data-retention).

## Consulta también

* [Almacenamiento en caché de prompts](https://platform.claude.com/docs/es/build-with-claude/prompt-caching)
* [Streaming](https://platform.claude.com/docs/es/build-with-claude/streaming)
* [Errores](https://platform.claude.com/docs/es/api/errors)

## Disponibilidad

Estado de Hilos de mensajes: en beta en todos los modelos.

### Compatibilidad con la API

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

* Disponibilidad: Disponible

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

### Encabezados beta requeridos

[Descripción general de los encabezados beta](https://platform.claude.com/docs/es/api/beta-headers)

Los encabezados beta te permiten acceder a funciones experimentales y nuevas capacidades de los modelos antes de que formen parte de la API estándar.

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

### Manejo de datos

[Descripción general del manejo de datos](https://platform.claude.com/docs/es/manage-claude/api-and-data-retention#feature-eligibility)

| Elemento | Retención de datos cero                                                                                                                                                                                                                                                                                                                                                                                                                                            | HIPAA       |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
| Estado   | No elegible                                                                                                                                                                                                                                                                                                                                                                                                                                                        | No elegible |
| Detalles | El contenido de un hilo (la conversación, la indicación del sistema y las herramientas) se mantiene en memoria, cifrado con una clave administrada por el servidor, nunca se escribe en almacenamiento duradero y se elimina como máximo 1 hora después del último uso del hilo. Usar esta función no afecta tu uso de otras funciones elegibles para ZDR. [Más información](https://platform.claude.com/docs/es/build-with-claude/message-threads#data-retention) | —           |

Endpoints aplicables:

* `/v1/messages` con `thread`
