Session management

Maintain conversation context using previousChatId vs sessionId

Overview

Vapi provides two approaches for maintaining conversation context across multiple chat interactions.

Two Context Management Methods:

  • previousChatId - Links individual chats in sequence
  • sessionId - Groups multiple chats under a persistent session

previousChatId and sessionId are mutually exclusive. You cannot use both in the same request.

Prerequisites

  • Completed Chat quickstart tutorial
  • Basic understanding of chat requests and responses

Method 1: Using previousChatId

Link chats together by referencing the ID of the previous chat.

1

Send first message

Initial Chat
$curl -X POST https://api.vapi.ai/chat \
> -H "Authorization: Bearer YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "assistantId": "your-assistant-id",
> "input": "Hello, my name is Sarah"
> }'
2

Get the chat ID from response

Response
1{
2 "id": "chat_abc123",
3 "output": [{"role": "assistant", "content": "Hello Sarah!"}]
4}
3

Reference previous chat in next request

Follow-up Chat
$curl -X POST https://api.vapi.ai/chat \
> -H "Authorization: Bearer YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "assistantId": "your-assistant-id",
> "previousChatId": "chat_abc123",
> "input": "What was my name again?"
> }'

Here’s a TypeScript implementation of the conversation chain:

conversation-chain.ts
1function createConversationChain() {
2 let lastChatId: string | null = null;
3
4 return async function sendMessage(assistantId: string, input: string) {
5 const requestBody = {
6 assistantId,
7 input,
8 ...(lastChatId && { previousChatId: lastChatId })
9 };
10
11 const response = await fetch('https://api.vapi.ai/chat', {
12 method: 'POST',
13 headers: {
14 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`,
15 'Content-Type': 'application/json'
16 },
17 body: JSON.stringify(requestBody)
18 });
19
20 const chat = await response.json();
21 lastChatId = chat.id;
22
23 return chat.output[0].content;
24 };
25}
26
27// Usage
28const sendMessage = createConversationChain();
29await sendMessage("asst_123", "Hi, I'm Alice");
30await sendMessage("asst_123", "What's my name?"); // Remembers Alice

Method 2: Using sessionId

Create a persistent session that groups multiple chats.

1

Create a session

Create Session
$curl -X POST https://api.vapi.ai/session \
> -H "Authorization: Bearer YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"assistantId": "your-assistant-id"}'
2

Get session ID from response

Session Response
1{
2 "id": "session_xyz789",
3 "assistantId": "your-assistant-id"
4}
  • Sessions expire automatically after 24 hours by default. After expiration, you’ll need to create a new session to continue conversations.
  • Web chat widget and SMS conversations automatically manage session creation and expiration. You don’t need to manually create or manage sessions when using these channels.

Here’s a TypeScript implementation of the session manager:

session-manager.ts
1async function createSession(assistantId: string) {
2 const response = await fetch('https://api.vapi.ai/session', {
3 method: 'POST',
4 headers: {
5 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`,
6 'Content-Type': 'application/json'
7 },
8 body: JSON.stringify({ assistantId })
9 });
10
11 const session = await response.json();
12
13 return function sendMessage(input: string) {
14 return fetch('https://api.vapi.ai/chat', {
15 method: 'POST',
16 headers: {
17 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`,
18 'Content-Type': 'application/json'
19 },
20 body: JSON.stringify({ sessionId: session.id, input })
21 })
22 .then(response => response.json())
23 .then(chat => chat.output[0].content);
24 };
25}
26
27// Usage
28const sendMessage = await createSession("asst_123");
29await sendMessage("I need help with my account");
30await sendMessage("What was my first question?"); // Remembers context

When to use each approach

Use previousChatId when:

  • Dealing with simple back-and-forth conversations
  • Looking for a minimal setup

Use sessionId when:

  • Building complex multi-step workflows
  • Long-running conversations
  • Error resilience needed

Sessions are tied to one assistant. You cannot specify assistantId when using sessionId.


Multi-Assistant Workflows

For workflows with multiple assistants, create separate sessions for each assistant.

multi-assistant-workflow.ts
1function createMultiAssistantWorkflow() {
2 const sessions = new Map<string, string>();
3
4 return async function sendToAssistant(assistantId: string, input: string) {
5 let sessionId = sessions.get(assistantId);
6
7 if (!sessionId) {
8 const response = await fetch('https://api.vapi.ai/session', {
9 method: 'POST',
10 headers: {
11 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`,
12 'Content-Type': 'application/json'
13 },
14 body: JSON.stringify({ assistantId })
15 });
16
17 const session = await response.json();
18 sessionId = session.id;
19 sessions.set(assistantId, sessionId);
20 }
21
22 const response = await fetch('https://api.vapi.ai/chat', {
23 method: 'POST',
24 headers: {
25 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`,
26 'Content-Type': 'application/json'
27 },
28 body: JSON.stringify({ sessionId, input })
29 });
30
31 const chat = await response.json();
32 return chat.output[0].content;
33 };
34}
35
36// Usage
37const sendToAssistant = createMultiAssistantWorkflow();
38await sendToAssistant("support_agent", "I have a billing issue");
39await sendToAssistant("billing_agent", "Can you help with this?");

Webhook Support

Sessions support the following webhook events through server messaging:

  • session.created - Triggered when a new session is created
  • session.updated - Triggered when a session is updated
  • session.deleted - Triggered when a session is deleted

To receive these webhooks, go to your Assistant page in the Dashboard and navigate to “Server Messaging” and select the events you want to receive.

These webhooks are useful for tracking session lifecycle, managing session state in your own database, and triggering workflows based on session changes.


Next Steps

Need help? Chat with the team on our Discord or mention us on X/Twitter.