Skip to main content
This guide shows you how to create, view, and inspect threads. Threads work with assistants to enable stateful execution of your deployed graphs.

Understand threads

A thread is a persistent conversation container that maintains state across multiple runs. Each time you execute a run on a thread, the graph processes the input with the thread’s current state and updates that state with new information. Threads enable stateful interactions by preserving conversation history and context between runs. Without threads, each run would be stateless, with no memory of previous interactions. Threads are particularly useful for:
  • Multi-turn conversations where the assistant needs to remember what was discussed.
  • Long-running tasks that require maintaining context across multiple steps.
  • User-specific state management where each user has their own conversation history.
The diagram illustrates how a thread maintains state across two runs. The second run has access to the messages from the first run, allowing the assistant to understand that the context of “What about tomorrow?” refers to the weather query from the first run:
  • A thread maintains a persistent conversation with a unique thread ID.
  • Each run applies the assistant’s configuration to the graph execution.
  • State is updated after each run and persists for subsequent runs.
  • Later runs have access to the full conversation history.
  • Assistants define the configuration (model, prompts, tools) for how your graph executes. When creating a run, you can specify either a graph name (e.g., "agent") to use the default assistant, or an assistant ID (UUID) to use a specific configuration.
  • Threads maintain the state and conversation history.
  • Runs combine an assistant and thread to execute your graph with a specific configuration and state.

Create a thread

To run your graph with state persistence, you must first create a thread:
  • SDK
  • UI

Empty thread

To create a new thread, use one of:
from langgraph_sdk import get_client

# Initialize the client with your deployment URL
client = get_client(url=<DEPLOYMENT_URL>)

# Create an empty thread
# This creates a new thread with no initial state
thread = await client.threads.create()

print(thread)
For more information, refer to the Python and JS SDK docs, or the REST API reference.Output:
{
"thread_id": "123e4567-e89b-12d3-a456-426614174000",
"created_at": "2025-05-12T14:04:08.268Z",
"updated_at": "2025-05-12T14:04:08.268Z",
"metadata": {},
"status": "idle",
"values": {}
}

Copy thread

Alternatively, if you already have a thread in your application whose state you wish to copy, you can use the copy method. This will create an independent thread whose history is identical to the original thread at the time of the operation:
# Copy an existing thread
# The new thread will have the same state as the original at the time of copying
copied_thread = await client.threads.copy(<THREAD_ID>)
For more information, refer to the Python and JS SDK docs, or the REST API reference.

Prepopulated State

You can create a thread with an arbitrary pre-defined state by providing a list of supersteps into the create method. The supersteps describe a sequence of state updates that establish the initial state of the thread. This is useful when you want to:
  • Create a thread with existing conversation history.
  • Migrate conversations from another system.
  • Set up test scenarios with specific initial states.
  • Resume conversations from a previous session.
For more information on checkpoints and state management, refer to the LangGraph persistence documentation.
from langgraph_sdk import get_client

# Initialize the client
client = get_client(url=<DEPLOYMENT_URL>)

# Create a thread with pre-populated conversation history
# The supersteps define a sequence of state updates that build up the initial state
thread = await client.threads.create(
  graph_id="agent",  # Specify which graph this thread is for
  supersteps=[
    {
      updates: [
        {
          values: {},
          as_node: '__input__',  # Initial input node
        },
      ],
    },
    {
      updates: [
        {
          values: {
            messages: [
              {
                type: 'human',
                content: 'hello',
              },
            ],
          },
          as_node: '__start__',  # User's first message
        },
      ],
    },
    {
      updates: [
        {
          values: {
            messages: [
              {
                content: 'Hello! How can I assist you today?',
                type: 'ai',
              },
            ],
          },
          as_node: 'call_model',  # Assistant's response
        },
      ],
    },
  ])

print(thread)
Output:
{
"thread_id": "f15d70a1-27d4-4793-a897-de5609920b7d",
"created_at": "2025-05-12T15:37:08.935038+00:00",
"updated_at": "2025-05-12T15:37:08.935046+00:00",
"metadata": {"graph_id": "agent"},
"status": "idle",
"config": {},
"values": {
"messages": [
{
"content": "hello",
"additional_kwargs": {},
"response_metadata": {},
"type": "human",
"name": null,
"id": "8701f3be-959c-4b7c-852f-c2160699b4ab",
"example": false
},
{
"content": "Hello! How can I assist you today?",
"additional_kwargs": {},
"response_metadata": {},
"type": "ai",
"name": null,
"id": "4d8ea561-7ca1-409a-99f7-6b67af3e1aa3",
"example": false,
"tool_calls": [],
"invalid_tool_calls": [],
"usage_metadata": null
}
]
}
}

List threads

  • SDK
  • UI
To list threads, use the search method. This will list the threads in the application that match the provided filters:

Filter by thread status

Use the status field to filter threads based on their status. Supported values are idle, busy, interrupted, and error. For example, to view idle threads:
# Search for idle threads
# The status filter accepts: idle, busy, interrupted, error
print(await client.threads.search(status="idle", limit=1))
For more information, refer to the Python and JS SDK docs, or the REST API reference.Output:
[
{
'thread_id': 'cacf79bb-4248-4d01-aabc-938dbd60ed2c',
'created_at': '2024-08-14T17:36:38.921660+00:00',
'updated_at': '2024-08-14T17:36:38.921660+00:00',
'metadata': {'graph_id': 'agent'},
'status': 'idle',
'config': {'configurable': {}}
}
]

Filter by metadata

The search method allows you to filter on metadata. This is useful for finding threads associated with specific graphs, users, or custom metadata you’ve added to threads:
# Search for threads with specific metadata
# Metadata filtering is useful for organizing threads by graph, user, or custom tags
print((await client.threads.search(metadata={"graph_id":"agent"}, limit=1)))
Output:
[
{
'thread_id': 'cacf79bb-4248-4d01-aabc-938dbd60ed2c',
'created_at': '2024-08-14T17:36:38.921660+00:00',
'updated_at': '2024-08-14T17:36:38.921660+00:00',
'metadata': {'graph_id': 'agent'},
'status': 'idle',
'config': {'configurable': {}}
}
]

Sorting

The SDK also supports sorting threads by thread_id, status, created_at, and updated_at using the sort_by and sort_order parameters.

Inspect threads

  • SDK
  • UI

Get Thread

To view a specific thread given its thread_id, use the get method:
# Retrieve a specific thread by its ID
# Returns the thread metadata including status, creation time, and metadata
print((await client.threads.get(<THREAD_ID>)))
Output:
{
'thread_id': 'cacf79bb-4248-4d01-aabc-938dbd60ed2c',
'created_at': '2024-08-14T17:36:38.921660+00:00',
'updated_at': '2024-08-14T17:36:38.921660+00:00',
'metadata': {'graph_id': 'agent'},
'status': 'idle',
'config': {'configurable': {}}
}
For more information, refer to the Python and JS SDK docs, or the REST API reference.

Inspect thread state

To view the current state of a given thread, use the get_state method. This returns the current values, next nodes to execute, and checkpoint information:
# Get the current state of a thread
# Returns values, next nodes, tasks, checkpoint info, and metadata
print((await client.threads.get_state(<THREAD_ID>)))
Output:
{
"values": {
"messages": [
{
"content": "hello",
"additional_kwargs": {},
"response_metadata": {},
"type": "human",
"name": null,
"id": "8701f3be-959c-4b7c-852f-c2160699b4ab",
"example": false
},
{
"content": "Hello! How can I assist you today?",
"additional_kwargs": {},
"response_metadata": {},
"type": "ai",
"name": null,
"id": "4d8ea561-7ca1-409a-99f7-6b67af3e1aa3",
"example": false,
"tool_calls": [],
"invalid_tool_calls": [],
"usage_metadata": null
}
]
},
"next": [],
"tasks": [],
"metadata": {
"thread_id": "f15d70a1-27d4-4793-a897-de5609920b7d",
"checkpoint_id": "1f02f46f-7308-616c-8000-1b158a9a6955",
"graph_id": "agent_with_quite_a_long_name",
"source": "update",
"step": 1,
"writes": {
"call_model": {
"messages": [
{
"content": "Hello! How can I assist you today?",
"type": "ai"
}
]
}
},
"parents": {}
},
"created_at": "2025-05-12T15:37:09.008055+00:00",
"checkpoint": {
"checkpoint_id": "1f02f46f-733f-6b58-8001-ea90dcabb1bd",
"thread_id": "f15d70a1-27d4-4793-a897-de5609920b7d",
"checkpoint_ns": ""
},
"parent_checkpoint": {
"checkpoint_id": "1f02f46f-7308-616c-8000-1b158a9a6955",
"thread_id": "f15d70a1-27d4-4793-a897-de5609920b7d",
"checkpoint_ns": ""
},
"checkpoint_id": "1f02f46f-733f-6b58-8001-ea90dcabb1bd",
"parent_checkpoint_id": "1f02f46f-7308-616c-8000-1b158a9a6955"
}
For more information, refer to the Python and JS SDK docs, or the REST API reference.Optionally, to view the state of a thread at a given checkpoint, pass in the checkpoint ID. This is useful for inspecting the thread state at a specific point in its execution history:
# Get thread state at a specific checkpoint
# Useful for inspecting historical state or debugging
thread_state = await client.threads.get_state(
  thread_id=<THREAD_ID>,
  checkpoint_id=<CHECKPOINT_ID>
)

Inspect full thread history

To view a thread’s history, use the get_history method. This returns a list of every state the thread experienced, allowing you to trace the full execution path:
# Get the full history of a thread
# Returns a list of all state snapshots from the thread's execution
history = await client.threads.get_history(
  thread_id=<THREAD_ID>,
  limit=10  # Optional: limit the number of states returned
)

for state in history:
    print(f"Checkpoint: {state['checkpoint_id']}")
    print(f"Step: {state['metadata']['step']}")
This method is particularly useful for:
  • Debugging execution flow by seeing how state evolved.
  • Understanding decision points in your graph’s execution.
  • Auditing conversation history and state changes.
  • Replaying or analyzing past interactions.
For more information, refer to the Python and JS SDK docs, or the REST API reference.

Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.