Claude Message Threads API: guida ai thread
Invia la conversazione una volta, poi manda solo i messaggi nuovi.
In questa pagina
- Cosa risparmia un thread
- Crea il primo turno, poi continua
- Cosa reinviare e cosa mai
- Scadenza, reinvio e il 404
- Errori
- Domande frequenti
- Che cos'è l'API Claude Message Threads?
- I thread funzionano con la cache dei prompt?
- Posso cambiare modello a metà thread?
- Perché una continue dà 400 senza error_code?
- Quanto dura un thread e cosa succede alla scadenza?
- Fonti verificate
L'API Claude Message Threads ti permette di inviare una conversazione lunga una volta sola e, a ogni turno successivo, mandare solo i messaggi nuovi. Aggiungi "thread": {"type": "create"} alla prima richiesta Messages e l'header beta message-threads-2026-08-12: l'API tiene la conversazione in memoria e la richiesta successiva invia meno contenuto (pagina Message threads di Anthropic, 4 novembre 2026).
È beta su tutti i modelli. 17 ID di modello possono usarla, incluso Claude Opus 5.5, che il codice qui sotto chiama. L'header beta accompagna ogni richiesta di un thread.
Cosa risparmia un thread
Senza thread, ogni turno porta l'intera trascrizione: il system prompt, le definizioni degli strumenti, tutti i messaggi precedenti e tutti i risultati degli strumenti. Un thread archivia quella conversazione, risposta di Claude compresa, sotto l'id della risposta, e una richiesta continue invia solo ciò che è successo dopo (pagina Message threads, 4 novembre 2026). Meno contenuto a ogni turno.
La cache dei prompt aiuta la stessa conversazione da un altro lato. Un cache hit rende più economico l'input ripetuto: su Opus 5.5, 0,20 USD per milione di token contro 4 USD per un input nuovo (pagina dei prezzi di Anthropic, 4 novembre 2026). La richiesta porta comunque quell'input. Il thread riduce quello che invii; la cache abbassa il prezzo di ciò che si ripete. Le sessioni lunghe vogliono entrambi, e ridurre il consumo di token di Claude Code copre il lato contesto.
I thread non cambiano né i prezzi né i limiti di frequenza (pagina Message threads, 4 novembre 2026). Le tariffe attuali sono nella pagina prezzi.
La cache la gestisci tu. Invia un cache_control di primo livello in ogni richiesta e l'API lo applica all'ultimo blocco messages memorizzabile di quella richiesta. Il limite di quattro breakpoint è una regola della cache dei prompt valida per tutta la piattaforma, e la cache automatica ne occupa uno (pagina della cache dei prompt di Anthropic, 4 novembre 2026). Distribuiscili così:
- il
cache_controldi primo livello, un punto in ogni richiesta del thread; - uno su
system, inviato con la richiesta create; - uno su
tools, anche alla create; - uno sul messaggio più recente.
I breakpoint sui messaggi già archiviati restano fuori da questo budget, perché una richiesta continue invia solo i messaggi nuovi. Un breakpoint inviato resta dov'è. Quando reinvii una conversazione, togli i punti dai messaggi precedenti e lascia un punto sull'ultimo blocco (pagina Message threads, 4 novembre 2026).
Crea il primo turno, poi continua
Tre passaggi:
- Metti la tua chiave Anthropic in
ANTHROPIC_API_KEY. - Invia la conversazione completa, con
systemetoolsse li usi, più"thread": {"type": "create"}. - Invia solo i messaggi dall'ultima risposta, più
"thread": {"type": "continue", "previous_message_id": "<previous id>"}, e lascia fuorisystemetools.
Ogni richiesta porta l'header beta e anthropic-version: 2026-10-21, la versione attuale (pagina delle versioni di Anthropic, 4 novembre 2026).
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2026-10-21" \
-H "anthropic-beta: message-threads-2026-08-12" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"system": "You are a careful backend reviewer.",
"messages": [
{"role": "user", "content": "Read this design and list the risks."}
],
"thread": {"type": "create"}
}'
Conserva l'id di quella risposta. La richiesta successiva invia solo il messaggio nuovo:
PREVIOUS_ID="<id from the previous response>"
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2026-10-21" \
-H "anthropic-beta: message-threads-2026-08-12" \
-H "content-type: application/json" \
-d @- <<JSON
{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Turn those risks into a checklist."}
],
"thread": {"type": "continue", "previous_message_id": "$PREVIOUS_ID"}
}
JSON
Tieni l'id più recente di ogni risposta: un thread accetta solo aggiunte, ogni id di risposta si continua una volta sola, e la richiesta successiva deve usare l'ultimo (pagina Message threads, 4 novembre 2026).
Se ti serve un'altra strada per una chiave API, OmniaKey vende accesso all'API Claude con gli stessi ID di modello, quindi il corpo della richiesta non cambia. I thread sono beta dalla parte di Anthropic, quindi prima di dipenderne in produzione controlla che l'intermediario che usi lasci passare il campo thread così com'è.
L'SDK Python segue gli id per te. Prepara un helper con client.beta.messages.thread(...), che si limita a preparare la chiamata, e invia ogni turno con thread.send(). L'helper aggiunge l'header beta, crea al primo turno, continua con i soli messaggi nuovi e una volta reinvia tutta la conversazione in una nuova richiesta create quando una continue dà thread_not_found, thread_already_continued o thread_continue_in_flight (pagina Message threads, 4 novembre 2026).
import anthropic
client = anthropic.Anthropic() # legge ANTHROPIC_API_KEY
# L'helper non invia ancora nulla; conserva i campi che ogni turno riusa.
thread = client.beta.messages.thread(
model="claude-opus-5-5",
max_tokens=1024,
system="You are a careful backend reviewer.",
)
first = thread.send({"role": "user", "content": "Read this design and list the risks."})
print(first.id, first.stop_reason)
second = thread.send({"role": "user", "content": "Turn those risks into a checklist."})
print(second.id) # la prossima volta continua da questo id
Non abbiamo eseguito queste richieste contro l'API di Anthropic; la forma viene dalla pagina Message threads di Anthropic. Per lo streaming, thread.stream(...) e stream.get_final_message() danno lo stesso flusso, e thread.previous_message_id restituisce l'id se preferisci seguirlo da solo.
Cosa reinviare e cosa mai
Invia i campi fissi con gli stessi valori in ogni richiesta, system e tools solo nella richiesta create, e lascia che i campi liberi cambino da un turno all'altro.
| Gruppo | Campi | Regola |
|---|---|---|
| Solo create | system, tools | Solo nella richiesta create; inviare uno dei due in una richiesta continue, anche come null, dà 400. |
| Fissi | model, tool_choice, thinking, mcp_servers tranne il token di autorizzazione di ogni server, context_management, output_config, gli skills di container, il cache_control di primo livello e l'insieme dei valori di anthropic-beta | Sempre lo stesso valore. Un valore diverso dà 400 e nomina il campo che differisce. |
| Liberi | max_tokens, stop_sequences, stream, metadata, service_tier e i campi senza nome | Cambiali quando vuoi. |
Il 400 di un campo fisso modificato porta thread_fingerprint_mismatch, e il messaggio elenca i campi che differiscono. Per cambiare uno di questi valori, apri un nuovo thread con la conversazione completa e il nuovo valore.
Se manca previous_message_id, la richiesta continue dà 400 con un message nel corpo ma nessun error_code; aggiungere system o tools fa lo stesso. Una richiesta continue deve portare esattamente i messaggi dall'ultima risposta.
mcp_servers è fisso, ma gli URL dei server e i token di autorizzazione vivono solo nella tua richiesta, quindi invia la lista in ogni richiesta che usa MCP; un token può cambiare tra due richieste. Anche l'id del container vive solo nella tua richiesta, quindi invia container ogni volta (pagina Message threads, 4 novembre 2026).
Il fallback lato server si decide alla create: invia fallbacks in ogni richiesta del thread o in nessuna. Il valore può cambiare tra i turni, ma aggiungere o togliere il campo dà thread_fingerprint_mismatch.
Scadenza, reinvio e il 404
Un thread scade 5 minuti dopo l'ultima richiesta, e l'API lo elimina al più tardi 1 ora dopo l'ultimo uso. Ogni risposta archiviata riavvia i 5 minuti. I thread non rientrano nella conservazione zero dei dati: la conversazione, il system prompt e gli strumenti restano in memoria, cifrati, e non vengono mai scritti su uno storage durevole (pagina Message threads, 4 novembre 2026).
Nessun campo della risposta dice se l'API ha archiviato un turno, né alla create né alla continue. Lo scopri alla richiesta continue successiva, quindi la tua applicazione resta la fonte di verità e tiene una propria copia di ogni messaggio (pagina Message threads, 4 novembre 2026).
Quando una richiesta continue dà 404 thread_not_found, invia la conversazione completa in una nuova richiesta create e riparti dall'id di quella risposta. L'API dà lo stesso 404 in tutti questi casi:
- il thread è scaduto;
- il turno precedente è stato servito e poi scartato, per esempio una chiamata a uno strumento tagliata da
max_tokens; - la risposta precedente l'ha scritta un modello di fallback;
- la risposta precedente è ancora in generazione;
- la richiesta arriva da un'altra organizzazione, workspace, utente o chiave di workspace;
- i messaggi nuovi portano contenuto che la conversazione archiviata non ha, come la prima immagine di una conversazione che non ne aveva.
Reinviare la conversazione completa è sempre sicuro e sistema ognuno di questi casi.
Lo streaming aggiunge una regola: riparti dall'id della risposta solo dopo message_stop, perché una continue inviata prima può dare 404. Se lo stream di una richiesta continue si interrompe prima di message_stop, invia di nuovo la stessa richiesta continue, e reinvia tutto se questo dà thread_already_continued o thread_continue_in_flight. Lo stream interrotto l'helper dell'SDK lo lascia al tuo retry.
Altri tre casi hanno una strada propria:
pause_turn: riparti dall'iddi quella risposta con"messages": []. Se dà 404, reinvia tutto includendo la risposta in pausa.stop_reason: "refusal": apri un nuovo thread senza il turno che l'ha provocato; l'API potrebbe già avere il turno rifiutato.- una voce
fallback_messageinusage.iterations, o nell'ultimomessage_deltadi uno stream, segnala una risposta di fallback: reinvia tutto.
Errori
I cinque errori di thread tornano prima che il modello giri: la richiesta non consuma token e il thread tiene la sua scadenza. error.type vale invalid_request_error per i 400 e not_found_error per il 404 (pagina Message threads, 4 novembre 2026).
- 404,
thread_not_found: l'API non può continuare questo thread. Invia la conversazione completa in una nuova richiesta create. - 400,
thread_fingerprint_mismatch: un campo fisso è cambiato rispetto al valore salvato con il thread. Tienilo identico o apri un nuovo thread. - 400,
thread_already_continued: quell'iddi risposta è già stato usato una volta. Riparti dall'idpiù recente e reinvia tutto se non l'hai mai ricevuto. - 400,
thread_continue_in_flight: un'altra continue sullo stessoidè ancora in corso, di solito il tuo tentativo precedente. Lasciala finire o reinvia tutto. - 400,
thread_unsupported_request: la richiesta usa una funzione o un'impostazione dell'organizzazione che i thread non supportano.error.details.unsupportednomina uno tracontext_management,cache_control,fallbacks,hipaaeinference_hooks; l'elenco può allungarsi, quindi se un valore ti è sconosciuto invia la conversazione completa senzathread.
Message Batches rifiuta il campo thread (un elemento di batch che lo porta fallisce con invalid_request_error), e il conteggio dei token e la compattazione danno 400; lo stesso vale per la modifica del contesto diversa da clear_thinking_20251015 con keep: "all". Le organizzazioni pronte per HIPAA e quelle con Inference hooks attivi sono escluse. Elencare, leggere ed eliminare un thread non esistono nell'API.
Domande frequenti
Che cos'è l'API Claude Message Threads?
È una funzione beta dell'API Messages che archivia una conversazione dalla parte di Anthropic, così i turni successivi inviano solo i messaggi nuovi. L'header beta è message-threads-2026-08-12, e ogni richiesta aggiunge un oggetto thread con type uguale a create o continue.
I thread funzionano con la cache dei prompt?
Sì. Il thread non mette in cache il tuo prompt al posto tuo: invia un cache_control di primo livello in ogni richiesta e resta entro quattro breakpoint. I punti sui messaggi archiviati non contano; quello di primo livello e quelli su system o tools contano.
Posso cambiare modello a metà thread?
Cambiare modello richiede un nuovo thread. model è un campo fisso, quindi un valore diverso dà 400 thread_fingerprint_mismatch; apri un nuovo thread con la conversazione completa e il nuovo modello.
Perché una continue dà 400 senza error_code?
Manca previous_message_id, oppure la richiesta contiene system o tools, anche come null. Quei 400 portano un message e omettono error_code, quindi leggi il testo.
Quanto dura un thread e cosa succede alla scadenza?
Un thread scade 5 minuti dopo l'ultima richiesta e viene eliminato al più tardi 1 ora dopo l'ultimo uso. Dopo, una continue dà 404 thread_not_found; invia la conversazione completa in una nuova richiesta create e riparti dal suo id.
Fonti verificate
Modelli citati in questo articolo
Articoli correlati
Ridurre l’uso di token in Claude Code
Il risparmio maggiore di solito deriva dalla riduzione del contesto ripetuto e dalla prevenzione di rielaborazioni, non dalla richiesta di una risposta finale più breve.
Opus 5.5 o Sonnet 5.5
Scegli in base al risultato verificato e al costo totale.
Prezzi di Claude 2026: piani, limiti d’uso e modelli inclusi
Ogni piano di Claude con prezzo e limite d’uso, più le tariffe dell’API e il piano che include davvero Fable.
Articoli recenti
- Gemini 2.5 Pro deprecato: cosa cambia il 1° dicembre 2026
- Gemini 4 Argon: test di programmazione su 8 attività e test nascosti
- Nano Banana Pro API: tutorial Python, modifica delle immagini e prezzo
- Qwen Image 3 Pro vs GPT Image 2: cinque prompt, due modelli
- Seedance 2.0: lip sync, dialoghi e 4 clip reali