---
title: Thread di messaggi
url: https://platform.claude.com/docs/it/build-with-claude/message-threads
description: Offri agli agenti a esecuzione prolungata un tempo al primo token più rapido, specialmente nelle conversazioni lunghe, inviando solo i nuovi messaggi a ogni richiesta.
featureMetadata:
  status: beta
  betaHeader: message-threads-2026-08-12
  zdr:
    eligibility: not-eligible
    note: Il contenuto di un thread (la conversazione, il prompt di sistema e gli strumenti) viene mantenuto in memoria, crittografato con una chiave gestita dal server, mai scritto in un archivio persistente ed eliminato non oltre 1 ora dopo l’ultimo utilizzo del thread. L’uso di questa funzionalità non influisce sul tuo uso di altre funzionalità idonee per 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” (thread di messaggi), le richieste sono più piccole e il “time to first token” (tempo al primo token) rimane più basso e più stabile man mano che la conversazione cresce. I thread sono più utili nei lunghi “agent loop” (cicli dell’agente). Senza un thread, ogni turno carica di nuovo l’intera conversazione, e l’API la convalida e la tokenizza di nuovo per intero. Con un thread, la maggior parte di questo lavoro riguarda solo il nuovo turno.

Un “message thread” (thread di messaggi) mantiene una conversazione sul server per un breve periodo. Invii l’intera conversazione una sola volta, con il tuo prompt di sistema e i tuoi strumenti. A ogni turno successivo, invii solo i nuovi messaggi e l’`id` della risposta precedente. L’API ricostruisce la conversazione prima di chiamare il modello. Aggiungi un solo parametro, `thread`, a una richiesta alla [Messages API](https://platform.claude.com/docs/it/api/messages). La risposta è il consueto messaggio.

<Note>
  I thread di messaggi sono diversi dai [thread di sessione](https://platform.claude.com/docs/it/managed-agents/session-threads) in Claude Managed Agents.
</Note>

## Come funzionano i thread di messaggi

* **Crea.** Invia la tua prima richiesta come fai oggi, con la conversazione completa, `system` e `tools`, e aggiungi `"thread": {"type": "create"}`. L’API memorizza la conversazione, inclusa la risposta di Claude, sotto l’`id` della risposta.
* **Continua.** Invia solo i messaggi successivi alla risposta precedente e aggiungi `"thread": {"type": "continue", "previous_message_id": "<previous id>"}`. Ometti `system` e `tools` dalla richiesta. Il thread mantiene i valori della richiesta di creazione. Usa ogni nuovo `id` di risposta per il turno successivo.
* **Riproduci.** Un thread è best-effort. Scade 5 minuti dopo la sua ultima richiesta, e l’API lo elimina non oltre 1 ora dopo il suo ultimo utilizzo. Ogni risposta che l’API memorizza fa ripartire i 5 minuti. Se l’API non può più continuare il thread, una richiesta di continuazione restituisce un errore 404. Invia di nuovo la conversazione completa in una nuova richiesta di creazione e continua dall’`id` di quella risposta. L’helper per i thread dell’SDK esegue questa riproduzione per te (vedi [Comportamento dell’helper dell’SDK](https://platform.claude.com/docs/it/build-with-claude/message-threads#sdk-helper-handles)). Dopo una risposta da un modello di fallback, vedi [Usare i fallback con un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#fallbacks).

La tua applicazione rimane la fonte di verità per la conversazione. Conserva una tua copia di ogni messaggio e costruisci il [percorso di replay](https://platform.claude.com/docs/it/build-with-claude/message-threads#recover) fin dall’inizio. Nessuna risposta, né a una richiesta di creazione né a una richiesta di continuazione, indica se l’API ha memorizzato quel turno. Lo scopri alla successiva richiesta di continuazione. L’helper thread dell’SDK conserva questa copia in memoria finché l’oggetto helper esiste, e non la salva da nessun’altra parte. Se la conversazione deve sopravvivere al tuo processo, conserva una tua copia.

## Usare un thread con un SDK

L’SDK dispone di un helper per i thread che costruisce le richieste del thread per te. Crealo con gli stessi campi di una richiesta Messages, poi inviagli un turno alla volta. L’helper mantiene in memoria la conversazione completa.

Questo esempio ha due turni. L’helper crea un thread al primo turno e lo continua al secondo, e aggiunge l’header beta per te. Il `cache_control` di primo livello è facoltativo. Richiede il “prompt caching” (cache dei prompt) a ogni turno (vedi [Cache dei prompt su un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#prompt-caching)). Senza di esso, ogni turno successivo invia comunque solo i nuovi messaggi, ma nulla viene memorizzato nella cache a meno che tu non aggiunga dei breakpoint di cache.

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

  # Crea l'helper. Questa chiamata non invia alcuna richiesta.
  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: l'helper crea un thread e invia l'intera conversazione
  thread.send({"role": "user", "content": "Hi! I have a question about an order."})

  # Turno 2: l'helper continua il thread e invia solo il nuovo messaggio
  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 l'helper. Questa chiamata non invia alcuna richiesta.
  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: l'helper crea un thread e invia l'intera conversazione
  await thread.send({ role: "user", content: "Hi! I have a question about an order." });

  // Turno 2: l'helper continua il thread e invia solo il nuovo messaggio
  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 l'helper. Questa chiamata non invia alcuna richiesta.
  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: l'helper crea un thread e invia l'intera conversazione
  await thread.Send(
      new BetaUserMessageParam { Content = "Hi! I have a question about an order." }
  );

  // Turno 2: l'helper prosegue il thread e invia solo il nuovo messaggio
  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 l'helper. Questa chiamata non invia alcuna richiesta.
  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: l'helper crea un thread e invia l'intera conversazione
  _, 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: l'helper prosegue il thread e invia solo il nuovo messaggio
  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 l'helper. Questa chiamata non invia alcuna richiesta.
  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: l'helper crea un thread e invia l'intera conversazione
  thread.send("Hi! I have a question about an order.");

  // Turno 2: l'helper prosegue il thread e invia solo il nuovo messaggio
  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 l'helper. Questa chiamata non invia alcuna richiesta.
  $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: l'helper crea un thread e invia l'intera conversazione
  $thread->send(['role' => 'user', 'content' => 'Hi! I have a question about an order.']);

  // Turno 2: l'helper continua il thread e invia solo il nuovo messaggio
  $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 l'helper. Questa chiamata non invia alcuna richiesta.
  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: l'helper crea un thread e invia l'intera conversazione
  thread.send_message({role: "user", content: "Hi! I have a question about an order."})

  # Turno 2: l'helper prosegue il thread e invia solo il nuovo messaggio
  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>

## Inviare tu stesso il campo `thread`

Per costruire tu stesso le richieste del thread, ad esempio con cURL, la CLI o il consueto metodo `create` di un SDK, aggiungi il campo `thread` a ogni richiesta.

Invia l’header beta `message-threads-2026-08-12` in ogni richiesta di un thread.

Questo esempio crea un thread al primo turno e lo continua al secondo. Il `cache_control` di primo livello richiede la cache dei prompt a ogni turno. Ha effetto una volta che la conversazione supera la [lunghezza minima memorizzabile nella cache](https://platform.claude.com/docs/it/build-with-claude/prompt-caching).

<CodeGroup>
  ```bash cURL
  # Turno 1: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio. Imposta message_id sull'id della risposta del turno 1.
  # Ometti system e tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio. Imposta message_id sull'id della risposta del turno 1.
  # Ometti system e tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio e l'id della risposta del turno 1.
  # Ometti system e tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio e l'id della risposta del turno 1.
  // Ometti system e tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio e l'id della risposta del turno 1.
  // Ometti System e Tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio e l'id della risposta del turno 1.
  // Ometti System e Tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio e l'id della risposta del turno 1.
  // Ometti system e tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio e l'id della risposta del turno 1.
  // Ometti system e tools: il thread li 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: invia l'intera conversazione e crea un 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: invia solo il nuovo messaggio e l'id della risposta del turno 1.
  # Ometti system_ e tools: il thread li 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>

## Cosa inviare in ogni richiesta

| Gruppo         | Campi                                                                                                                                                                                                                                                    | Regola                                                                                                                                                                                                                                       |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Solo creazione | `system`, `tools`                                                                                                                                                                                                                                        | Inviali solo nella richiesta di creazione, con eventuali breakpoint `cache_control` su di essi. Inviare uno dei due in una richiesta di continuazione, anche come `null`, restituisce un errore 400.                                         |
| Fissi          | `model`, `tool_choice`, `thinking`, `mcp_servers` (a parte il token di autorizzazione di ciascun server), `context_management`, `output_config`, le `skills` in `container`, il `cache_control` di primo livello e l’insieme dei valori `anthropic-beta` | Inviali in ogni richiesta del thread, con gli stessi valori della richiesta di creazione. Un valore diverso restituisce un errore 400 con il codice `thread_fingerprint_mismatch`, e il messaggio di errore indica i campi che differiscono. |
| Liberi         | `max_tokens`, `stop_sequences`, `stream`, `metadata`, `service_tier` e altri campi non menzionati in questa pagina                                                                                                                                       | Possono cambiare da un turno all’altro.                                                                                                                                                                                                      |

L’API non memorizza gli URL dei server MCP, i token di autorizzazione MCP né l’`id` del container. Invia `mcp_servers` e `container` in ogni richiesta che li usa. Un token di autorizzazione MCP può cambiare tra una richiesta e l’altra.

L’helper per i thread dell’SDK omette `system` e `tools` dalle richieste di continuazione per te e invia di nuovo i campi fissi a ogni turno.

Se usi il [fallback lato server](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback#server-side-fallback), invia il campo `fallbacks` in ogni richiesta di un thread oppure in nessuna. Vedi [Usare i fallback con un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#fallbacks).

Per modificare un campo di sola creazione o fisso, avvia un nuovo thread: invia l’intera conversazione in una richiesta di creazione con i nuovi valori.

Su Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5.5, Claude Sonnet 5.5 e Claude Haiku 5.5, la modifica di `system` o `tools` rende non validi i blocchi `thinking` e `redacted_thinking` già presenti nella conversazione, e la richiesta di creazione può restituire un errore 400. Per evitarlo, escludi ogni blocco `thinking` e `redacted_thinking` dalla conversazione che invii. Il modello risponde quindi senza quel ragionamento precedente. Consulta [Cosa conta come modifica](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#what-counts-as-an-edit), [Quando `prefix_mismatch_behavior` non è impostato](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#enforcement) e [Cosa fa l’API con un blocco non valido](https://platform.claude.com/docs/it/build-with-claude/preserved-thinking#mismatch-behavior).

Invia solo i nuovi messaggi in una richiesta di continuazione. L’API non li confronta con i messaggi che ha già. Un messaggio che invii di nuovo può comparire due volte nella conversazione, oppure la richiesta può restituire un errore. Ad esempio, una richiesta di continuazione che inizia con la risposta precedente restituisce un errore.

I nuovi messaggi di solito iniziano con un messaggio `user`: il tuo turno utente successivo, oppure i blocchi `tool_result` che rispondono a un `tool_use` nella risposta precedente. Se una risposta si interrompe con [`stop_reason: "pause_turn"`](https://platform.claude.com/docs/it/build-with-claude/handling-stop-reasons#pause-turn), riprendila con una richiesta di continuazione dall’`id` di quella risposta e un elenco `messages` vuoto (`"messages": []`). Se quella richiesta restituisce un errore 404, riproduci la conversazione completa, inclusa la risposta in pausa, in una nuova richiesta di creazione. Non inviare un nuovo messaggio `user` mentre il turno è in pausa: l’API lo rifiuta. Con l’helper per i thread dell’SDK, chiama `send()` (go, csharp: `Send()`; ruby: `send_message()`) senza messaggi: l’helper invia questa richiesta ed esegue la riproduzione in caso di errore 404.

Un thread è di sola aggiunta, e ogni `id` di risposta può essere continuato una sola volta. Continua sempre dall’ultimo `id` di risposta del thread. Per modificare o diramare un messaggio precedente, avvia un nuovo thread con una richiesta di creazione. Per sostituire i turni precedenti con un riepilogo, vedi [Compattare una conversazione](https://platform.claude.com/docs/it/build-with-claude/message-threads#compaction).

## Cache dei prompt su un thread

Un thread non memorizza il tuo prompt nella cache per te. La [cache dei prompt](https://platform.claude.com/docs/it/build-with-claude/prompt-caching) funziona come senza un thread: sei tu a scegliere dove posizionare i breakpoint di cache.

Per memorizzare nella cache ogni turno, invia un `cache_control` di primo livello in ogni richiesta del thread, come nell’esempio precedente. L’API lo applica all’ultimo blocco memorizzabile nella cache dei `messages` di ogni richiesta. Ogni turno legge quindi la conversazione precedente dalla cache e vi scrive il nuovo turno. Il `cache_control` di primo livello è un campo fisso: invia lo stesso valore in ogni richiesta.

Puoi anche posizionare tu stesso i breakpoint `cache_control` sui blocchi:

* I breakpoint che invii nella richiesta di creazione continuano a funzionare in ogni turno successivo se si trovano su `tools`, su `system` o su un blocco di messaggio precedente all’ultimo. Un breakpoint sull’ultimo blocco dei `messages` di una richiesta scrive la cache in quella richiesta. Per memorizzare nella cache ogni nuovo turno, invia un breakpoint in ogni richiesta. Una richiesta senza breakpoint potrebbe comunque leggere parte della conversazione dalla cache.
* Non puoi spostare o rimuovere un breakpoint dopo averlo inviato, perché una richiesta di continuazione non può inviare di nuovo un messaggio precedente.
* Una richiesta con `thread` può contenere al massimo 4 breakpoint `cache_control`. Il `cache_control` di primo livello conta come uno. I breakpoint su `system` e `tools` della richiesta di creazione vengono conteggiati di nuovo in ogni richiesta di continuazione. I breakpoint sui messaggi precedenti memorizzati non vengono conteggiati. Un breakpoint di troppo restituisce un errore 400 con il codice `thread_unsupported_request`.
* Se posizioni tu stesso i breakpoint sui blocchi di messaggio, rimuovili dai messaggi precedenti quando riproduci la conversazione in una nuova richiesta di creazione e mantienine uno sull’ultimo blocco, in modo che la richiesta rimanga entro il limite di 4.

## Streaming

I thread funzionano con lo [streaming](https://platform.claude.com/docs/it/build-with-claude/streaming). L’`id` della risposta arriva nell’evento `message_start`, ma continua da esso solo dopo aver ricevuto l’evento `message_stop`. Una richiesta di continuazione inviata prima può restituire un errore 404.

Se lo stream di una richiesta di continuazione si interrompe prima di `message_stop`, invia di nuovo la stessa richiesta di continuazione. Se quella richiesta restituisce un errore `thread_already_continued` o `thread_continue_in_flight`, riproduci l’intera conversazione in una nuova richiesta di creazione.

La tua connessione potrebbe essersi interrotta mentre il server stava ancora generando la risposta, oppure dopo che il server l’aveva salvata. Ecco perché l’API può rifiutare il nuovo tentativo. La riproduzione è sempre sicura.

L’helper per i thread dell’SDK non riprova la richiesta di continuazione dopo uno stream interrotto. Vedi [Comportamento dell’helper dell’SDK](https://platform.claude.com/docs/it/build-with-claude/message-threads#sdk-helper-handles).

## Ripristino quando un thread non può essere continuato

Una richiesta di continuazione restituisce un errore 404 con `error.details.error_code` impostato su `thread_not_found` quando l’API non può continuare il thread. La risposta non indica il motivo. Le cause includono le seguenti:

* Il thread è scaduto.
* L’API ha servito il turno precedente ma non lo ha memorizzato. Ad esempio, l’API non memorizza una risposta che termina con una chiamata a uno strumento interrotta da `max_tokens`.
* La risposta precedente è stata scritta da un modello di fallback. Vedi [Usare i fallback con un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#fallbacks).
* La risposta precedente è ancora in fase di generazione.
* La richiesta proviene da un’organizzazione o da un workspace diverso.
* La richiesta proviene da un utente o da un account di servizio diverso da quello che ha creato il thread. Un thread creato con una [chiave di workspace (legacy)](https://platform.claude.com/docs/it/manage-claude/authentication#key-types) resta legato a quella chiave, quindi usa la stessa chiave per l’intero thread.
* I nuovi messaggi aggiungono qualcosa che la conversazione memorizzata non può accogliere. Ad esempio, la prima immagine in una conversazione che non ne aveva può restituire questo errore.

Per ripristinare, invia l’intera conversazione dalla tua copia in una nuova richiesta di creazione, con `system` e `tools`. L’helper dei thread dell’SDK invia questa richiesta di creazione una volta da solo, omettendo in tal caso i breakpoint `cache_control` dei turni precedenti. Se i messaggi precedenti nella tua copia contengono breakpoint `cache_control`, rimuovili prima (vedi [Cache dei prompt su un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#prompt-caching)). Quindi continua dal nuovo `id` della risposta. Se la risposta precedente è stata scritta da un modello di fallback, vedi [Usare i fallback con un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#fallbacks). Per escludere le cause legate alla proprietà, usa la stessa chiave API e lo stesso workspace per ogni richiesta di un thread. Su Claude Platform on AWS, firma ogni richiesta di un thread con le credenziali del ruolo IAM o dell’utente IAM che lo ha creato.

Anche una richiesta per un modello che non esiste restituisce un errore 404, quindi controlla `error.details.error_code` prima di eseguire la riproduzione.

Se una richiesta di continuazione restituisce ancora un errore 404 subito dopo la riproduzione, l’API potrebbe non essere in grado di memorizzare quella conversazione, ad esempio se è molto grande. Inviala senza `thread`. L’helper thread dell’SDK lo fa quando lo crei con `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`) impostato su `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`). Altrimenti esegue la riproduzione a ogni turno.

### Dopo un rifiuto

Quando una risposta ha `stop_reason: "refusal"`, non continuare il thread. L’API potrebbe già contenere il turno rifiutato, e una richiesta di continuazione non può rimuoverlo. Avvia un nuovo thread con una richiesta di creazione che ometta o riformuli il turno che ha causato il rifiuto. Consulta [Rifiuti e fallback](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback). L’helper thread dell’SDK lo fa per te: non conserva il turno rifiutato, e il suo turno successivo avvia un nuovo thread.

### Usare i fallback con un thread

Il [fallback lato server](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback#server-side-fallback) è disponibile con i thread sulla Claude API. Decidi quando crei il thread: invia `fallbacks` in ogni richiesta del thread, oppure in nessuna. Il valore di `fallbacks` può cambiare tra una richiesta e l’altra. Una richiesta di continuazione che aggiunge o rimuove `fallbacks` restituisce un errore 400 con il codice `thread_fingerprint_mismatch`.

Un thread mantiene un solo modello, quindi l’API non memorizza un turno scritto da un modello di fallback. Ricevi la risposta come di consueto, ma non puoi continuare dal suo `id`. Dopo ogni risposta, segui questi passaggi:

1. Se `stop_reason` è `"refusal"`, segui [Dopo un rifiuto](https://platform.claude.com/docs/it/build-with-claude/message-threads#after-a-refusal).

2. Altrimenti, cerca una voce `fallback_message` in `usage.iterations`. In uno stream, leggila dall’evento `message_delta` finale. Se non ce n’è nessuna, continua il thread come di consueto.

3. Se ce n’è una, la risposta è stata scritta da un modello di fallback. Invia l’intera conversazione, inclusa quella risposta e il tuo messaggio successivo, in una nuova richiesta di creazione. Mantieni l’header beta `server-side-fallback-2026-07-01` su di essa. Scegli una di queste due richieste:

   * **La stessa richiesta di nuovo.** Mantieni `model`, `fallbacks` e gli altri parametri così come erano. Se risponde il modello che hai richiesto, l’API memorizza il nuovo thread. Se risponde un modello di fallback, la risposta contiene di nuovo una voce `fallback_message` e l’API non la memorizza, quindi ripeti questo passaggio al turno successivo. Il [routing persistente](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback#sticky-routing) potrebbe inviare queste richieste direttamente al modello di fallback, quindi ogni turno potrebbe inviare l’intera conversazione. L’helper per i thread dell’SDK funziona in questo modo.
   * **Un nuovo thread sul modello di fallback.** Imposta `model` sul `model` presente in quella voce `fallback_message`, ometti `fallbacks` e usa parametri accettati da questo modello. L’API memorizza subito questo thread, che rimane sul modello di fallback. Il tentativo di fallback potrebbe essere stato eseguito con impostazioni diverse da quelle che hai inviato, quindi l’API potrebbe rifiutare valori copiati dalla tua prima richiesta.

4. Torna al passaggio 1 con la risposta a quella richiesta. Quando non ha alcuna voce `fallback_message`, continua il nuovo thread dal suo `id`.

Il [routing persistente](https://platform.claude.com/docs/it/build-with-claude/refusals-and-fallback#sticky-routing) inizia dopo che una richiesta ricorre al fallback (una richiesta di creazione, o una richiesta senza `thread`). Per circa un’ora, potrebbe inviare le successive richieste di creazione per la stessa conversazione che includono `fallbacks` direttamente al modello di fallback, senza provare il modello che hai richiesto. L’API non memorizza nessuno di quei turni, e ciascuno a cui viene data risposta fa ripartire il conteggio di un’ora. Una richiesta di continuazione non avvia mai questo routing e non lo utilizza mai. Il routing persistente non si applica se la tua organizzazione o il tuo workspace utilizza la conservazione zero dei dati o chiavi di crittografia gestite dal cliente.

## Compattare una conversazione

Un thread è di sola aggiunta, quindi non puoi sostituire i suoi turni precedenti con un riepilogo. Per compattare una conversazione, avvia un nuovo thread dal riepilogo. Scrivi il riepilogo nel tuo codice e invialo come un normale messaggio in una nuova richiesta di creazione, con `system` e `tools`. La [compattazione su richiesta](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand) non è disponibile con i thread (vedi [Funzionalità che i thread non supportano](https://platform.claude.com/docs/it/build-with-claude/message-threads#unsupported)).

## Comportamento dell’helper dell’SDK

Cosa fa l’helper per te:

* Aggiunge l’header beta `message-threads-2026-08-12` a ogni richiesta che usa il thread.
* Crea un thread al primo turno e lo continua in seguito, inviando solo i nuovi messaggi e omettendo `system` e `tools`.
* Riproduce l’intera conversazione una volta in una nuova richiesta di creazione quando una richiesta di continuazione restituisce `thread_not_found`, `thread_already_continued` o `thread_continue_in_flight`.
* Riprende una risposta `pause_turn` quando chiami `send()` (go, csharp: `Send()`; ruby: `send_message()`) senza messaggi.
* Avvia un nuovo thread dopo un rifiuto. Ricevi la risposta `stop_reason: "refusal"` come di consueto, ma l’helper non conserva quel turno: ritira i messaggi che hai passato a quella chiamata. I messaggi che hai aggiunto con `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`), o che hai passato quando hai creato l’helper, restano in attesa. Il tuo turno successivo li invia insieme alla conversazione precedente al turno rifiutato, in una nuova richiesta di creazione. Invia un messaggio riformulato oppure, se è stato un messaggio in attesa a causare il rifiuto, avvia un nuovo thread dai params senza di esso.
* Invia una nuova richiesta di creazione dopo una risposta da un modello di fallback. Quando una risposta ha una voce `fallback_message` in `usage.iterations`, l’helper conserva la risposta e invia l’intera conversazione in una nuova richiesta di creazione al turno successivo. Non attende un errore 404. Quella richiesta mantiene il `model` e i `fallbacks` che hai impostato.
* Omette i breakpoint `cache_control` dei turni precedenti ogni volta che li invia di nuovo, ad esempio in una riproduzione o nel primo turno di un fork. I tuoi messaggi più recenti, `system`, `tools` e il `cache_control` di primo livello vengono inviati così come li hai forniti.

Cosa gestisci tu:

* **Fallback.** Finché l’API continua a rispondere da un modello di fallback, l’helper invia l’intera conversazione in una nuova richiesta di creazione a ogni turno, perché l’API non memorizza nessuno di quei turni. Torna alle richieste di continuazione dopo una risposta dal modello che hai richiesto. Per spostare invece la conversazione sul modello di fallback, avvia un nuovo thread dai params con quel `model` e senza `fallbacks`, come in [Usare i fallback con un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#fallbacks).
* **Stream interrotti.** Se uno stream termina a metà di una risposta, l’helper conserva i blocchi completati e l’eventuale testo arrivato, e il turno successivo invia l’intera conversazione in una nuova richiesta di creazione. L’helper non riprova da solo: per inviare di nuovo il turno interrotto, chiama invece `send()` (go, csharp: `Send()`; ruby: `send_message()`) senza messaggi. Se la parte conservata termina con chiamate a strumenti, rispondi a esse nel tuo messaggio successivo. Se smetti di leggere uno stream dopo che mostra `stop_reason: "refusal"`, l’helper tratta quel turno come un rifiuto.
* **Altri errori.** Gli errori `thread_fingerprint_mismatch` e `thread_unsupported_request` arrivano al tuo codice. Per proseguire senza `thread` dopo un errore `thread_unsupported_request`, crea l’helper con `unsupported_request_behavior` (typescript, java, php: `unsupportedRequestBehavior`; go, csharp: `UnsupportedRequestBehavior`) impostato su `continue_unthreaded` (ruby: `:continue_unthreaded`; java: `CONTINUE_UNTHREADED`; csharp: `ContinueUnthreaded`; go: `BetaMessageThreadUnsupportedRequestBehaviorContinueUnthreaded`). Con questa impostazione, l’helper smette di usare `thread` anche quando la prima richiesta di continuazione dopo una riproduzione restituisce di nuovo `thread_not_found`. L’API potrebbe non essere in grado di memorizzare quella conversazione. Senza questa impostazione, l’helper esegue la riproduzione a ogni turno. Un tool runner che crea il proprio thread usa questa impostazione per impostazione predefinita.

Anche il tool runner beta dell’SDK usa un thread per impostazione predefinita, che puoi disattivare quando crei il runner.

### Altri metodi dell’helper

| Per fare questo                                         | Usa                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Eseguire lo streaming di un turno                       | `thread.stream(...)` (csharp: `thread.SendStreaming(...)`; go: `thread.SendStreaming(ctx, params)`; java: `thread.sendStreaming(...)`; php: `$thread->sendStream(...)`)                                                                                                                                                              |
| Risposta completa di un turno in streaming              | `stream.get_final_message()` (typescript: `stream.finalMessage()`; csharp: `thread.LastMessage`; go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`; ruby: `stream.accumulated_message`)                                                                                                        |
| Conversazione completa                                  | `thread.messages` (csharp: `thread.Messages`; go: `thread.Messages()`; java: `thread.messages()`; php: `$thread->messages()`)                                                                                                                                                                                                        |
| `id` della risposta da cui continua il turno successivo | `thread.previous_message_id` (typescript: `thread.previousMessageId`; csharp: `thread.PreviousMessageID`; go: `thread.PreviousMessageID()`; java: `thread.previousMessageId()`; php: `$thread->previousMessageId()`)                                                                                                                 |
| Aggiungere messaggi senza inviarli                      | `thread.append(...)` (csharp, go: `thread.Append(...)`; php: `$thread->append(...)`)                                                                                                                                                                                                                                                 |
| Modificare i campi per i turni successivi               | `thread.update(...)` (csharp: `thread.Update(p => p with { ... })`; go: `thread.Params.MaxTokens = ...`; java: `thread.update(b -> ...)`; php: `$thread->update([...])`)                                                                                                                                                             |
| Copiare il thread                                       | `thread.fork()` (csharp, go: `thread.Fork()`; php: `$thread->fork()`; ruby: `thread.fork`)                                                                                                                                                                                                                                           |
| Campi e conversazione, per avviare un nuovo thread      | `thread.params` (csharp, go: `thread.Params`; java: `thread.params()`; php: `$thread->params()`)                                                                                                                                                                                                                                     |
| Tool runner su questo 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 senza un 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.** L’helper registra la risposta quando lo stream raggiunge `message_stop`, quindi leggi lo stream fino alla fine. Se smetti di leggere prima, chiudi lo stream in modo che il thread sia libero per il turno successivo:

* Python: esci dal blocco `with`.
* TypeScript: esci dal ciclo o chiama `abort()`.
* Go: chiama `Close`.
* Java e Ruby: chiama `close()`.
* C#: esegui il dispose dell’enumeratore. Uscire da `await foreach` lo fa.
* PHP: chiama `close()`.

In C#, la richiesta parte quando inizi a leggere lo stream.

In C#, Go, Java e PHP, dopo un rifiuto `thread.LastMessage` (go: `thread.LastMessage()`; java: `thread.lastMessage()`; php: `$thread->lastMessage()`) restituisce ancora la risposta del turno precedente, o nulla al primo turno. Leggi il rifiuto dagli eventi dello stream.

**Modificare i campi.** Un aggiornamento non invia nulla e si applica a ogni turno successivo. Una volta che un thread ha una risposta, l’helper rifiuta un turno che modifica `system` o `tools`, e l’API rifiuta una modifica a qualsiasi altro campo fisso (vedi [Cosa inviare in ogni richiesta](https://platform.claude.com/docs/it/build-with-claude/message-threads#what-to-send)). Per modificare uno di questi campi, avvia un nuovo thread dai params, oppure esegui il fork del thread e aggiorna il fork prima del suo primo turno.

**Fork.** Un fork copia la conversazione, i campi e le opzioni della richiesta, e non invia nulla. Il suo primo turno invia l’intera conversazione in una nuova richiesta di creazione, e da quel momento i due thread sono indipendenti. Un fork parte sempre dall’intera conversazione, non da una risposta precedente.

**Params.** I params contengono i campi dell’helper e l’intera conversazione. Passali al metodo che crea un helper per avviare un nuovo thread, ad esempio con un `system` diverso (vedi [Cosa inviare in ogni richiesta](https://platform.claude.com/docs/it/build-with-claude/message-threads#what-to-send)), o con `messages` ridotti per eliminare i turni successivi. Un thread che avvii dai params invia ogni messaggio così come lo hai fornito, breakpoint `cache_control` inclusi, quindi rimani entro il limite di 4 (vedi [Cache dei prompt su un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#prompt-caching)). Tranne che in Ruby, i params omettono le opzioni della richiesta, quindi passale di nuovo.

**Output strutturato.** Specifica il formato di output quando crei l’helper. Un turno successivo non può modificarlo. Il modo in cui ottieni il risultato analizzato dipende dall’SDK:

* Python e TypeScript: chiama `thread.parse(...)`.
* C#: crea l’helper con `client.Beta.Messages.Thread<T>(...)`.
* Go: `Send` esegue l’unmarshal nella struct a cui punta `Params.OutputConfig.Format.Schema`.
* Java: crea l’helper con `thread(...)` e `outputConfig(MyClass.class)`.
* PHP: `send()` imposta `parsed` sui blocchi di testo quando `outputConfig` indica una classe modello.
* Ruby: passa `output_config: {format: MyModel}` a `thread(...)`, poi leggi `reply.parsed_output`.

## Errori

L’API restituisce gli errori di questa tabella prima che il modello venga eseguito. La richiesta non consuma token, e il thread e il suo tempo di scadenza non cambiano. `error.type` è `invalid_request_error` per gli errori 400 e `not_found_error` per l’errore 404.

| Stato | `error_code`                  | Significato                                                                                                                                                 | Cosa fare                                                                                                                       |
| ----- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| 404   | `thread_not_found`            | L’API non può continuare il thread.                                                                                                                         | Invia l’intera conversazione in una nuova richiesta di creazione.                                                               |
| 400   | `thread_fingerprint_mismatch` | Un campo fisso differisce dal valore memorizzato con il thread. Il messaggio di errore indica i campi.                                                      | Mantieni invariati i campi fissi, oppure avvia un nuovo thread per modificarne uno.                                             |
| 400   | `thread_already_continued`    | Ogni `id` di risposta può essere continuato una sola volta.                                                                                                 | Continua dall’ultimo `id` di risposta del thread. Se il tuo client non ha mai ricevuto quella risposta, esegui la riproduzione. |
| 400   | `thread_continue_in_flight`   | Un’altra richiesta di continuazione da questo `id` di risposta è ancora in esecuzione. Di solito si tratta di un tuo tentativo precedente.                  | Lascia che termini e continua dal suo `id` di risposta, oppure esegui la riproduzione.                                          |
| 400   | `thread_unsupported_request`  | La richiesta usa una funzionalità o un’impostazione dell’organizzazione che i thread non supportano. `error.details.unsupported` la indica quando presente. | Rimuovi quella funzionalità dalla richiesta, oppure invia l’intera conversazione senza `thread`.                                |

Alcuni errori 400 per le richieste di thread non contengono alcun `error_code`, ad esempio una richiesta di continuazione senza `previous_message_id`, o una che include `system` o `tools`.

L’esempio seguente mostra il corpo di un errore:

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

## Funzionalità che i thread non supportano

I thread non supportano queste funzionalità:

* [Message Batches](https://platform.claude.com/docs/it/build-with-claude/batch-processing). Un elemento di richiesta che include `thread` termina con un `invalid_request_error` nei risultati del batch.
* [Conteggio dei token](https://platform.claude.com/docs/it/build-with-claude/token-counting). Una richiesta di conteggio dei token che include `thread` restituisce un errore 400. Conta invece l’intera conversazione, con `system` e `tools`.
* [Compattazione](https://platform.claude.com/docs/it/build-with-claude/compaction). La [compattazione su richiesta](https://platform.claude.com/docs/it/build-with-claude/compaction-on-demand) non è disponibile con i thread. Una richiesta che include `thread` restituisce un errore 400 se imposta il parametro `compaction`, oppure se invia un blocco `compaction` con l’header beta `compact-2026-09-04`. Vedi [Compattare una conversazione](https://platform.claude.com/docs/it/build-with-claude/message-threads#compaction).
* [Modifica del contesto](https://platform.claude.com/docs/it/build-with-claude/context-editing), tranne `clear_thinking_20251015` con `keep: "all"`.
* Organizzazioni che hanno abilitato la [predisposizione HIPAA](https://platform.claude.com/docs/it/manage-claude/api-and-data-retention#hipaa-readiness).
* Organizzazioni che hanno attivato gli [Inference hooks](https://platform.claude.com/docs/it/manage-claude/inference-hooks).

L’API rifiuta la maggior parte delle richieste che i thread non supportano con un errore 400 e il codice `thread_unsupported_request`. Quando `error.details.unsupported` è presente, contiene uno di questi valori:

| Valore               | Significato                                                                                                                                                                      |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `context_management` | La richiesta usa una gestione del contesto o una compattazione che i thread non supportano.                                                                                      |
| `cache_control`      | La richiesta ha più di 4 breakpoint `cache_control`. Vedi [Cache dei prompt su un thread](https://platform.claude.com/docs/it/build-with-claude/message-threads#prompt-caching). |
| `fallbacks`          | La richiesta imposta `fallbacks`, e la tua organizzazione non può usare `fallbacks` con i thread.                                                                                |
| `hipaa`              | La tua organizzazione ha abilitato la predisposizione HIPAA.                                                                                                                     |
| `inference_hooks`    | La tua organizzazione ha attivato gli Inference hooks.                                                                                                                           |

L’API può aggiungere valori a questo elenco. Se ricevi un valore che non riconosci, invia l’intera conversazione senza `thread`. Una richiesta che soddisfa più di queste condizioni riceve un errore che ne indica solo una.

## Limitazioni

* Non esiste un’API per elencare, leggere o eliminare un thread.
* I thread sono disponibili sulla Claude API, su [Claude Platform on AWS](https://platform.claude.com/docs/it/build-with-claude/claude-platform-on-aws), Claude Models on Google Cloud (Anthropic managed), e su [Claude in Microsoft Foundry](https://platform.claude.com/docs/it/build-with-claude/claude-in-microsoft-foundry).

## Prezzi e limiti di velocità

I thread non modificano i prezzi né i [limiti di velocità](https://platform.claude.com/docs/it/api/rate-limits).

## Conservazione dei dati

I thread di messaggi non sono idonei alla ZDR. L’utilizzo di questa funzionalità non influisce sul tuo utilizzo di altre funzionalità idonee alla ZDR. L’API conserva un thread in memoria, crittografato con una chiave gestita dal server, non lo scrive mai su un archivio persistente e lo elimina non oltre 1 ora dopo il suo ultimo utilizzo.

Un thread contiene la conversazione che l’API invia al modello, `system` e `tools` della richiesta di creazione e un’impronta dei campi fissi, che usa per verificare le richieste successive. Contiene i file per riferimento, quindi mantieni disponibile ogni file usato dalla conversazione mentre usi il thread.

Per l’idoneità alla ZDR di tutte le funzionalità, vedi [API e conservazione dei dati](https://platform.claude.com/docs/it/manage-claude/api-and-data-retention).

## Vedi anche

* [Cache dei prompt](https://platform.claude.com/docs/it/build-with-claude/prompt-caching)
* [Streaming](https://platform.claude.com/docs/it/build-with-claude/streaming)
* [Errori](https://platform.claude.com/docs/it/api/errors)

## Disponibilità

La funzionalità Thread di messaggi è in beta su tutti i modelli.

### Supporto API

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

* Disponibilità: Disponibile

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

### Header beta richiesti

[Panoramica degli header beta](https://platform.claude.com/docs/it/api/beta-headers)

Gli header beta consentono di accedere a funzionalità sperimentali e a nuove capacità dei modelli prima che entrino a far parte dell’API standard.

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

### Gestione dei dati

[Panoramica sulla gestione dei dati](https://platform.claude.com/docs/it/manage-claude/api-and-data-retention#feature-eligibility)

| Elemento | Conservazione zero dei dati                                                                                                                                                                                                                                                                                                                                                                                                                                               | HIPAA      |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| Stato    | Non idoneo                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Non idoneo |
| Dettagli | Il contenuto di un thread (la conversazione, il prompt di sistema e gli strumenti) viene mantenuto in memoria, crittografato con una chiave gestita dal server, mai scritto in un archivio persistente ed eliminato non oltre 1 ora dopo l’ultimo utilizzo del thread. L’uso di questa funzionalità non influisce sul tuo uso di altre funzionalità idonee per ZDR. [Scopri di più](https://platform.claude.com/docs/it/build-with-claude/message-threads#data-retention) | —          |

Endpoint applicabili:

* `/v1/messages` con `thread`
