> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.twelvelabs.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.twelvelabs.io/_mcp/server.

# Multi-turn sessions

Maintain conversation context across multiple requests. Use multi-turn sessions when you want to ask follow-up questions, explore your videos and images iteratively, or build a chat interface that preserves context across turns. This guide shows you how to start a session, continue it with follow-up messages, and build a reusable chat pattern.

# Key concepts

* **Session**: A server-side conversation state that [Jockey](/v1.3/agents/concepts/jockey) maintains across requests. You do not need to resend previous messages. The session retains the full conversation history. Each response includes a session identifier that you pass on subsequent requests to continue the conversation.

# Prerequisites

* You've already uploaded your videos and images, and the assets have reached the `ready` status. See the [Upload content](/v1.3/agents/guides/upload-content) page for details.
* You've already created a knowledge store. See the [Create a knowledge store](/v1.3/agents/guides/create-a-knowledge-store) page for details.
* You've already added at least one asset to the knowledge store, and the item has reached the `ready` status. See the [Add assets to a knowledge store](/v1.3/agents/guides/add-assets) page for details.
* You've already read the [Create a response](/v1.3/agents/guides/create-a-response) page and understand the basic request and response format.

# Example

Copy and paste the code below, replacing the placeholders surrounded by `<>` with your values.

**`Python`**

```python Python maxlines=25
from twelvelabs import TwelveLabs

client = TwelveLabs(api_key="<YOUR_API_KEY>")

# Step 1: Start a session by omitting session_id
response = client.responses.create(
    knowledge_store_id="<YOUR_KNOWLEDGE_STORE_ID>",
    input=[{"type": "message", "role": "user", "content": "What are the main themes in these videos and images?"}],
)
session_id = response.session_id
print(f"Session started: {session_id}")

# Step 2: Continue the conversation with the session_id from the previous response
response = client.responses.create(
    knowledge_store_id="<YOUR_KNOWLEDGE_STORE_ID>",
    session_id=session_id,
    input=[{"type": "message", "role": "user", "content": "Which items best represent the first theme?"}],
)
```

**`Node.js`**

```javascript Node.js maxlines=25
import { TwelveLabs } from "twelvelabs-js";

const client = new TwelveLabs({ apiKey: "<YOUR_API_KEY>" });

// Step 1: Start a session by omitting sessionId
let response = await client.responses.create({
  knowledgeStoreId: "<YOUR_KNOWLEDGE_STORE_ID>",
  input: [{ type: "message", role: "user", content: "What are the main themes in these videos and images?" }],
});
const sessionId = response.sessionId;
console.log(`Session started: ${sessionId}`);

// Step 2: Continue the conversation with the sessionId from the previous response
response = await client.responses.create({
  knowledgeStoreId: "<YOUR_KNOWLEDGE_STORE_ID>",
  sessionId,
  input: [{ type: "message", role: "user", content: "Which items best represent the first theme?" }],
});
```

# Code explanation

#### Python

#### Start a session

Omit the `session_id` field on the first request. Jockey creates a new session and returns its identifier in the response.\

**Function call**: You call the [`responses.create`](/v1.3/sdk-reference/python/responses#create-a-response) method.\

**Parameters**:

* `knowledge_store_id`: The unique identifier of the knowledge store to reason over.
* `input`: An array of input items. Each item is a message you send to Jockey.\


**Return value**: An object of type `ResponseObject`. Read the `session_id` field and store it to continue the conversation.

#### Continue the conversation

Pass the `session_id` from the previous response to send a follow-up message. Jockey uses the full conversation history, so you do not resend earlier messages.\

**Function call**: You call the [`responses.create`](/v1.3/sdk-reference/python/responses#create-a-response) method.\

**Parameters**:

* `knowledge_store_id`: The unique identifier of the knowledge store. Keep it the same across turns.
* `session_id`: The session identifier from the previous response.
* `input`: An array of input items. Each item is a message you send to Jockey.\


**Return value**: An object of type `ResponseObject`. Reuse the same `session_id` for later turns.

#### Node.js

#### Start a session

Omit the `sessionId` field on the first request. Jockey creates a new session and returns its identifier in the response.\

**Function call**: You call the [`responses.create`](/v1.3/sdk-reference/node-js/responses#create-a-response) method.\

**Parameters**: You pass all parameters as properties of a single object.

* `knowledgeStoreId`: The unique identifier of the knowledge store to reason over.
* `input`: An array of input items. Each item is a message you send to Jockey.\


**Return value**: An `HttpResponsePromise` that resolves to an object of type `ResponseObject`. Read the `sessionId` field and store it to continue the conversation.

#### Continue the conversation

Pass the `sessionId` from the previous response to send a follow-up message. Jockey uses the full conversation history, so you do not resend earlier messages.\

**Function call**: You call the [`responses.create`](/v1.3/sdk-reference/node-js/responses#create-a-response) method.\

**Parameters**: You pass all parameters as properties of a single object.

* `knowledgeStoreId`: The unique identifier of the knowledge store. Keep it the same across turns.
* `sessionId`: The session identifier from the previous response.
* `input`: An array of input items. Each item is a message you send to Jockey.\


**Return value**: An `HttpResponsePromise` that resolves to an object of type `ResponseObject`. Reuse the same `sessionId` for later turns.

# Build a reusable chat function

For chat UIs or interactive applications, wrap the session logic in a function. The function creates a new session on the first call and reuses it for subsequent calls.

**`Python`**

```python Python maxlines=20
session_id = None

def chat(message, store_id):
    global session_id

    response = client.responses.create(
        knowledge_store_id=store_id,
        session_id=session_id,
        input=[{"type": "message", "role": "user", "content": message}],
    )
    session_id = response.session_id

    # Extract text from response
    for output in response.output:
        if output.type == "message":
            for content in output.content:
                return content.text
```

**`Node.js`**

```javascript Node.js maxlines=20
let sessionId: string | undefined;

async function chat(message: string, storeId: string) {
  const response = await client.responses.create({
    knowledgeStoreId: storeId,
    sessionId,
    input: [{ type: "message", role: "user", content: message }],
  });
  sessionId = response.sessionId;

  // Extract text from response
  for (const output of response.output ?? []) {
    if (output.type === "message") {
      for (const content of output.content ?? []) {
        return content.text;
      }
    }
  }
}
```

# Common pitfalls

* **Store the session identifier.** Without the `session_id` value you cannot continue a conversation, and must start a new one.
* **Query the same knowledge store across turns.** A session is tied to one store; pass the same `knowledge_store_id` on every turn.
* **Do not resend conversation history.** The session stores it server-side.

# Next steps

* [Streaming](/v1.3/agents/guides/create-a-response/streaming) - combine multi-turn sessions with real-time streaming
* [Structured output](/v1.3/agents/guides/create-a-response/structured-output) - receive typed JSON responses within a session
* [Create a response](/v1.3/agents/guides/create-a-response) - review the basic request and response format

# Jupyter notebook

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/twelvelabs-io/twelvelabs-developer-experience/blob/main/quickstarts/jockey/guides/multi_turn_sessions.ipynb)