Variable substitution in sessions

Learn how template variables behave with sessions and chats

Overview

When using sessions with the Chat API, understanding how variable substitution works is essential for building dynamic, personalized conversations.

Key concept: Variables are substituted at session creation time and “baked into” the stored assistant configuration. Template placeholders like {{name}} are replaced with actual values and no longer exist in the session.

Vapi uses LiquidJS for variable substitution. The {{ }} syntax follows Liquid template language conventions, giving you access to filters, conditionals, and other Liquid features beyond simple variable replacement.


How variable substitution works

At session creation

When you create a session with assistantOverrides.variableValues, the system:

  1. Takes your assistant’s template variables (e.g., "Hello {{name}} from {{company}}")
  2. Substitutes all {{ }} placeholders using LiquidJS
  3. Stores the pre-substituted assistant in the session
  4. Saves the original variable values in session.metadata.variableValues for reference
Create session with variables
$curl -X POST https://api.vapi.ai/session \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "assistantId": "79f3cae3-5e47-4d8c-a1b2-9f8e7d6c5b4a",
> "assistantOverrides": {
> "variableValues": {
> "name": "John",
> "company": "Acme Corp"
> }
> }
> }'

If your assistant’s system prompt was "You are a helpful assistant for {{name}} at {{company}}", the session stores: "You are a helpful assistant for John at Acme Corp".

At chat creation

When you send a chat request with a sessionId:

  1. The system loads the session’s pre-substituted assistant
  2. Any variableValues in the chat request are processed, but there are no {{ }} placeholders left to substitute
  3. New variable values have no effect on already-substituted text

Behavior examples

Variables persist across chats

Once you set variables at session creation, they persist for all chats in that session:

Chat using the session
$curl -X POST https://api.vapi.ai/chat \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "sessionId": "6b4c494f-c22c-4bce-84fa-a7a86942c7d3",
> "input": "What is my name and company?"
> }'

The assistant will respond with the values set at session creation (John, Acme Corp).

New variableValues don’t override session values

Passing new variableValues in a chat request will not change the session’s pre-substituted assistant. The template placeholders no longer exist.

This will NOT change the assistant's context
$curl -X POST https://api.vapi.ai/chat \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "sessionId": "6b4c494f-c22c-4bce-84fa-a7a86942c7d3",
> "input": "What is my name and company?",
> "assistantOverrides": {
> "variableValues": {
> "name": "Jane",
> "company": "Wayne Enterprises"
> }
> }
> }'

The assistant still responds with “John” and “Acme Corp” because the original templates were already replaced.

Provide fresh templates to use new values

To use different variable values mid-session, provide a new template with {{ }} placeholders along with the new values:

Override with fresh template
$curl -X POST https://api.vapi.ai/chat \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "sessionId": "6b4c494f-c22c-4bce-84fa-a7a86942c7d3",
> "input": "What is my name and company?",
> "assistantOverrides": {
> "model": {
> "provider": "openai",
> "model": "gpt-4.1",
> "systemPrompt": "You are a helpful assistant for {{name}} at {{company}}. Be very formal."
> },
> "variableValues": {
> "name": "Jane",
> "company": "Wayne Enterprises"
> }
> }
> }'

Now the assistant responds with “Jane” and “Wayne Enterprises” because fresh template placeholders were provided.


Quick reference

ScenarioVariables applied?Why
Session creation with variableValues✅ YesTemplates exist, substitution happens
Chat with just sessionId✅ Session values persistPre-substituted assistant is used
Chat with sessionId + new variableValues❌ No effectNo {{ }} placeholders left to substitute
Chat with sessionId + new template with {{ }} + new variableValues✅ New values appliedFresh templates provided

Best practices

For consistent variables across a session

Pass assistantOverrides.variableValues once when creating the session. Subsequent chat requests only need the sessionId and input.

For different variables per conversation

Choose one of these approaches:

Pass the full assistant configuration in each chat request. This gives you complete control over variables per request.

Include a new system prompt (or other text field) with {{ }} placeholders plus new variableValues in your chat request.

Create a new session for each unique variable context. This keeps conversations cleanly separated.


Next steps

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