Non-streaming chat

Build reliable chat integrations with complete response patterns for batch processing and simple UIs

Overview

Build a chat integration that receives complete responses after processing, perfect for batch processing, simple UIs, or when you need the full response before proceeding. Ideal for integrations where real-time display isn’t essential.

What You’ll Build:

  • Simple request-response chat patterns with immediate complete responses
  • Context management using previousChatId for linked conversations
  • Basic integration with predictable response timing

For comprehensive context management options including sessions, see Session management.

Prerequisites

  • Completed Chat quickstart tutorial
  • Understanding of basic HTTP requests and JSON handling
  • Familiarity with JavaScript/TypeScript promises or async/await

Scenario

We’ll build a help desk system for “TechFlow” that processes support messages through text chat and maintains conversation history using previousChatId.


1. Basic Non-Streaming Implementation

1

Create a simple chat function

Start with a basic non-streaming chat implementation:

Basic Non-Streaming Request
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": "I need help resetting my password"
}'
2

Understand the response structure

Non-streaming responses come back as complete JSON objects:

Complete Chat Response
{
"id": "chat_123456",
"orgId": "org_789012",
"assistantId": "assistant_345678",
"name": "Password Reset Help",
"sessionId": "session_901234",
"messages": [
{
"role": "user",
"content": "I need help resetting my password"
}
],
"output": [
{
"role": "assistant",
"content": "I can help you reset your password. First, let me verify your account information..."
}
],
"createdAt": "2024-01-15T09:30:00Z",
"updatedAt": "2024-01-15T09:30:01Z"
}
3

Implement in TypeScript

Create a reusable function for non-streaming chat:

non-streaming-chat.ts
async function sendChatMessage(
message: string,
previousChatId?: string
): Promise<{ chatId: string; response: string }> {
const response = await fetch('https://api.vapi.ai/chat', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
assistantId: 'your-assistant-id',
input: message,
...(previousChatId && { previousChatId })
})
});
const chat = await response.json();
return {
chatId: chat.id,
response: chat.output[0].content
};
}

2. Context Management with previousChatId


3. Custom Assistant Configuration

1

Use inline assistant configuration

Instead of pre-created assistants, define configuration per request:

Custom Assistant Request
curl -X POST https://api.vapi.ai/chat \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": "I need help with enterprise features",
"assistant": {
"model": {
"provider": "openai",
"model": "gpt-4o",
"temperature": 0.7,
"messages": [
{
"role": "system",
"content": "You are a helpful technical support agent specializing in enterprise features."
}
]
}
}
}'
2

Create specialized chat handlers

Build different chat handlers for different types of requests:

specialized-handlers.ts
async function createSpecializedChat(systemPrompt: string) {
return async function(userInput: string): Promise<string> {
const response = await fetch('https://api.vapi.ai/chat', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
input: userInput,
assistant: {
model: {
provider: 'openai',
model: 'gpt-4o',
temperature: 0.3,
messages: [{ role: 'system', content: systemPrompt }]
}
}
})
});
const chat = await response.json();
return chat.output[0].content;
};
}
const technicalSupport = await createSpecializedChat(
"You are a technical support specialist. Ask clarifying questions and provide step-by-step troubleshooting."
);
const billingSupport = await createSpecializedChat(
"You are a billing support specialist. Be precise about billing terms and always verify account information."
);
// Usage
const techResponse = await technicalSupport("My API requests are returning 500 errors");
const billingResponse = await billingSupport("I was charged twice this month");

Next Steps

Enhance your non-streaming chat system further:

Need help? Ask other developers in the Vapi Discord community or mention us on X/Twitter.