Time travel using the server API

no

Original Documentation

Documentation Index#

Fetch the complete documentation index at: https://docs.langchain.com/llms.txt Use this file to discover all available pages before exploring further.

LangGraph provides the time travel functionality to resume execution from a prior checkpoint, either replaying the same state or modifying it to explore alternatives. In all cases, resuming past execution produces a new fork in the history.

To time travel using the LangSmith Deployment API (via the LangGraph SDK):

  1. Run the graph with initial inputs using LangGraph SDK’s client.runs.wait or client.runs.stream APIs.
  2. Identify a checkpoint in an existing thread: Use client.threads.get_history method to retrieve the execution history for a specific thread_id and locate the desired checkpoint_id. Alternatively, set a breakpoint before the node(s) where you want execution to pause. You can then find the most recent checkpoint recorded up to that breakpoint.
  3. (Optional) modify the graph state: Use the client.threads.update_state method to modify the graph’s state at the checkpoint and resume execution from alternative state.
  4. Resume execution from the checkpoint: Use the client.runs.wait or client.runs.stream APIs with an input of None and the appropriate thread_id and checkpoint_id.

Use time travel in a workflow#

```python from typing_extensions import TypedDict, NotRequired from langgraph.graph import StateGraph, START, END from langchain.chat_models import init_chat_model from langgraph.checkpoint.memory import InMemorySaver

class State(TypedDict): topic: NotRequired[str] joke: NotRequired[str]

model = init_chat_model( “claude-sonnet-4-6”, temperature=0, )

def generate_topic(state: State): “““LLM call to generate a topic for the joke””” msg = model.invoke(“Give me a funny topic for a joke”) return {“topic”: msg.content}

def write_joke(state: State): “““LLM call to write a joke based on the topic””” msg = model.invoke(f"Write a short joke about {state[’topic’]}") return {“joke”: msg.content}

Build workflow#

builder = StateGraph(State)

Add nodes#

builder.add_node(“generate_topic”, generate_topic) builder.add_node(“write_joke”, write_joke)

Add edges to connect nodes#

builder.add_edge(START, “generate_topic”) builder.add_edge(“generate_topic”, “write_joke”)

Compile#

graph = builder.compile()

</Accordion>

### 1. Run the graph

<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
  from langgraph_sdk import get_client
  client = get_client(url=<DEPLOYMENT_URL>)

  # Using the graph deployed with the name "agent"
  assistant_id = "agent"

  # create a thread
  thread = await client.threads.create()
  thread_id = thread["thread_id"]

  # Run the graph
  result = await client.runs.wait(
      thread_id,
      assistant_id,
      input={}
  )
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="JavaScript"></span>
```js
  import { Client } from "@langchain/langgraph-sdk";
  const client = new Client({ apiUrl: <DEPLOYMENT_URL> });

  // Using the graph deployed with the name "agent"
  const assistantID = "agent";

  // create a thread
  const thread = await client.threads.create();
  const threadID = thread["thread_id"];

  // Run the graph
  const result = await client.runs.wait(
    threadID,
    assistantID,
    { input: {}}
  );
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="cURL"></span>
Create a thread:

```bash
  curl --request POST \
  --url <DEPLOYMENT_URL>/threads \
  --header 'Content-Type: application/json' \
  --data '{}'
  ```

Run the graph:

```bash
  curl --request POST \
  --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/wait \
  --header 'Content-Type: application/json' \
  --data "{
    \"assistant_id\": \"agent\",
    \"input\": {}
  }"
  ```
<span class="tab-end"></span>
<span class="tab-group-end"></span>

### 2. Identify a checkpoint

<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
  # The states are returned in reverse chronological order.
  states = await client.threads.get_history(thread_id)
  selected_state = states[1]
  print(selected_state)
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="JavaScript"></span>
```js
  // The states are returned in reverse chronological order.
  const states = await client.threads.getHistory(threadID);
  const selectedState = states[1];
  console.log(selectedState);
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="cURL"></span>
```bash
  curl --request GET \
  --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/history \
  --header 'Content-Type: application/json'
  ```
<span class="tab-end"></span>
<span class="tab-group-end"></span>

<a id="optional" />

### 3. Update the state

[`update_state`](https://reference.langchain.com/python/langgraph/graphs/#langgraph.graph.state.CompiledStateGraph.update_state) will create a new checkpoint. The new checkpoint will be associated with the same thread, but a new checkpoint ID.

<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
  new_config = await client.threads.update_state(
      thread_id,
      {"topic": "chickens"},
      checkpoint_id=selected_state["checkpoint_id"]
  )
  print(new_config)
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="JavaScript"></span>
```js
  const newConfig = await client.threads.updateState(
    threadID,
    {
      values: { "topic": "chickens" },
      checkpointId: selectedState["checkpoint_id"]
    }
  );
  console.log(newConfig);
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="cURL"></span>
```bash
  curl --request POST \
  --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state \
  --header 'Content-Type: application/json' \
  --data "{
    \"assistant_id\": \"agent\",
    \"checkpoint_id\": <CHECKPOINT_ID>,
    \"values\": {\"topic\": \"chickens\"}
  }"
  ```
<span class="tab-end"></span>
<span class="tab-group-end"></span>

### 4. Resume execution from the checkpoint

<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
  await client.runs.wait(
      thread_id,
      assistant_id,
      input=None,
      checkpoint_id=new_config["checkpoint_id"]
  )
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="JavaScript"></span>
```javascript
  await client.runs.wait(
    threadID,
    assistantID,
    {
      input: null,
      checkpointId: newConfig["checkpoint_id"]
    }
  );
  ```
<span class="tab-end"></span>

<span class="tab-start" data-tab-title="cURL"></span>
```bash
  curl --request POST \
  --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/wait \
  --header 'Content-Type: application/json' \
  --data "{
    \"assistant_id\": \"agent\",
    \"checkpoint_id\": <CHECKPOINT_ID>
  }"
  ```
<span class="tab-end"></span>
<span class="tab-group-end"></span>

## Learn more

* [**LangGraph time travel guide**](/oss/python/langgraph/use-time-travel): learn more about using time travel in LangGraph.

***


<span class="callout-start" data-callout-type="note"></span>
[Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/langsmith/human-in-the-loop-time-travel.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
<span class="callout-end"></span>

<span class="callout-start" data-callout-type="note"></span>
[Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
<span class="callout-end"></span>
Link last verified June 7, 2026. View original ↗
Source: LangChain Docs
Link last verified: 2026-03-04