Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions fern/chat/variable-substitution.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
title: Variable substitution in sessions
subtitle: Learn how template variables behave with sessions and chats
slug: chat/variable-substitution
---

## 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.

<Note>
Vapi uses [LiquidJS](https://liquidjs.com/) for variable substitution. The `{{ }}` syntax follows Liquid template language conventions, giving you access to filters, conditionals, and other Liquid features beyond simple variable replacement.
</Note>

---

## 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

```bash title="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:

```bash title="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

<Warning>
Passing new `variableValues` in a chat request **will not** change the session's pre-substituted assistant. The template placeholders no longer exist.
</Warning>

```bash title="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:

```bash title="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

| Scenario | Variables applied? | Why |
|----------|-------------------|-----|
| Session creation with `variableValues` | ✅ Yes | Templates exist, substitution happens |
| Chat with just `sessionId` | ✅ Session values persist | Pre-substituted assistant is used |
| Chat with `sessionId` + new `variableValues` | ❌ No effect | No `{{ }}` placeholders left to substitute |
| Chat with `sessionId` + new template with `{{ }}` + new `variableValues` | ✅ New values applied | Fresh 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:

<AccordionGroup>
<Accordion title="Option A: Don't use sessions">
Pass the full assistant configuration in each chat request. This gives you complete control over variables per request.
</Accordion>
<Accordion title="Option B: Override with fresh templates">
Include a new system prompt (or other text field) with `{{ }}` placeholders plus new `variableValues` in your chat request.
</Accordion>
<Accordion title="Option C: Create separate sessions">
Create a new session for each unique variable context. This keeps conversations cleanly separated.
</Accordion>
</AccordionGroup>

---

## Next steps

- **[Session management](/chat/session-management)** - Learn about `previousChatId` vs `sessionId` approaches
- **[Variables](/assistants/dynamic-variables)** - Configure dynamic variables in your assistant
- **[Streaming responses](/chat/streaming)** - Add real-time responses to your chats

<Callout>
Need help? Chat with the team on our [Discord](https://discord.com/invite/pUFNcf2WmH) or mention us on [X/Twitter](https://x.com/Vapi_AI).
</Callout>
3 changes: 3 additions & 0 deletions fern/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,9 @@ navigation:
- page: Session management
path: chat/session-management.mdx
icon: fa-light fa-layer-group
- page: Variable substitution
path: chat/variable-substitution.mdx
icon: fa-light fa-brackets-curly
- page: SMS chat
path: chat/sms-chat.mdx
icon: fa-light fa-comment-sms
Expand Down
Loading