
Anthropic SDKs add a message threads beta the API docs don't list yet
Python SDK 2.2.0 and TypeScript SDK 1.2.0 can keep a Claude conversation on the server, but Anthropic hasn't documented or announced the API side.
If you build on the Claude API in Python or TypeScript, Anthropic's SDKs now include client.beta.messages.thread(), a beta helper that sends only each new turn instead of the whole conversation. Anthropic shipped it on Oct 23 with no announcement, and the API docs still call the Messages API stateless. So treat it as an early beta you can read about and plan for, not a documented feature.
What changed#
The Python SDK v2.2.0 (9:10 AM ET Oct 23) and TypeScript SDK 1.2.0 (9:09 AM ET) both list "add support for message threads." The Python SDK guide says: "A message thread (beta) keeps the conversation on the server, so each request sends only the new messages instead of the whole history."
| Today's docs | With a thread (per the SDK) | |
|---|---|---|
| History | You resend all of it each request | The server holds it; you send new messages |
| Request field | None | thread: create, or continue with previous_message_id |
| Beta header | None | message-threads-2026-08-12 |
| Branching | Copy messages yourself | thread.fork() |
The docs still say: "The Messages API is stateless, which means that you always send the full conversational history to the API." At our 5:58 AM ET check, the release notes had no threads entry and the API reference's beta header list didn't include the threads header. The SDK's field description says: "The response shape is unchanged."
Why it matters#
Our read: long chats and agent loops resend a growing history on every call, and a server-held thread shrinks each request. Anthropic hasn't said whether threaded turns are billed or cached differently, so don't assume token savings.
Python users of the beta tool runner should also look. In the SDK source, a tool runner's thread "sends no thread field on a client without message threads or when params have thread as False, and it stops sending one when the server cannot thread a request." (_beta_threads.py) Our read: on the first-party client, the runner now tries threading by default.
How to use it#
- Upgrade:
pip install -U "anthropic>=2.2.0", or TypeScript SDK 1.2.0 or later. - Per the guide, "
client.beta.messages.thread(...)takes whatcreate()takes and sends nothing until the first turn." - Send turns. Anthropic's own example from that guide:
thread = client.beta.messages.thread(
model="claude-sonnet-5",
max_tokens=1024,
system="You are a support agent for Acme.",
)
first = thread.send({"role": "user", "content": "My order #4821 hasn't arrived."})
second = thread.send({"role": "user", "content": "It's been two weeks."})
- Use
thread.tool_runner()for tools andthread.fork()to branch. - Choose a fallback with
unsupported_request_behavior. Per _params.py: "What a thread does with a request the server cannot thread:"error", the default, raises the API's error, and"continue_unthreaded"sends that turn and every later one with the full history and nothread." - Audit existing code with Claude Code:
I upgraded the anthropic Python SDK to 2.2.0 or later. Search this repo for every call to client.beta.messages.tool_runner() and client.beta.messages.thread(). For each one, tell me whether it changes system or tools during a run, whether it runs on a Bedrock or Vertex client, and whether it should pass thread=False. Don't change any code yet. (ours, untested)
Good to know#
- Fixed settings. The example says: "
model,system,tools, ... are fixed for a thread's lifetime; start a new one from the history to change them." Theupdate()docstring in _beta_threads.py names onlysystemandtoolsas locked. - Tool runner rule. "
systemand thetoolssent cannot change during a run: useadd_tools()andremove_tools(), or create the runner withthread=False." (_beta_runner.py) - One turn at a time. "A thread runs one turn at a time." (_beta_threads.py)
- Bedrock and Vertex. In the Python SDK, the Bedrock and Vertex clients leave threads off. Per _base_client.py: "
beta.messages.thread()raises where it does not, andbeta.messages.tool_runner()sends the full history every turn." - Lost threads. The SDK keeps the history locally and replays it under a new thread on errors such as
thread_not_found(_thread_state.py). - We haven't run it, and Anthropic hasn't said which accounts or models the API accepts it for.
What to watch#
- A release notes entry, or the threads header in the API reference's beta list.
- Any word from Anthropic on billing, caching or retention for server-held threads.
Last checked: Oct 25, 2026, 5:50 to 6:05 AM ET (SDK releases and source at tag v2.3.0, Claude Platform docs and release notes). What changed: first published Oct 25; no updates since.
Sources#
- anthropic-sdk-python v2.2.0 release (GitHub, Oct 23, 2026)
- anthropic-sdk-typescript sdk-v1.2.0 release (GitHub, Oct 23, 2026)
- Python SDK helpers guide: Message Threads
- Python SDK example: message_threads.py
- Python SDK: message_create_params.py
- Python SDK: _beta_threads.py
- Python SDK: _params.py
- Python SDK: _thread_state.py
- Python SDK: _beta_runner.py
- Python SDK: _base_client.py
- Using the Messages API (Claude Platform docs)
- Claude Platform release notes
Steps
- Upgrade to the Python SDK 2.2.0 or later (pip install -U "anthropic>=2.2.0") or the TypeScript SDK 1.2.0 or later.
- Create a thread with client.beta.messages.thread(...), using the same arguments you pass to create(); per the SDK guide it sends nothing until the first turn.
- Send each turn with thread.send(...) (or thread.stream(...)); only the new messages go out.
- Use thread.tool_runner() for tool loops and thread.fork() to branch a conversation.
- Pick a fallback: the default unsupported_request_behavior="error" raises the API's error; "continue_unthreaded" resends full history from then on.
- If you already use the Python beta tool runner and change system or tools mid-run, review it, since the SDK says to pass thread=False for that.