> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tavus.io/llms.txt
> Use this file to discover all available pages before exploring further.

# PAL Strategies

> Two approaches to using PALs at scale: reuse with conversational context vs. create-per-session. Choose based on whether you need different data or different behavior per conversation.

This guide describes two common strategies for using [PALs](/api-reference/pals/create-pal) when you run many conversations. The right choice depends on a single question: **Does each conversation need different behavior, or only different data?**

* **Different data only** (e.g. user name, profile, session goal) → **Approach A: Reuse PALs** and pass per-conversation data via `conversational_context` and related options.
* **Different behavior** (e.g. different voice, objectives, guardrails, or tools per session) → **Approach B: Create a PAL per conversation** - define the PAL config in your code, create it via the API at session start, then delete it when the session ends.

Both patterns are valid and used in production. Below we lay out how each works, what you can and can’t customize, tradeoffs, and when to use which.

***

## Approach A: Reuse PALs + conversational\_context

### How it works

You keep **persistent** PALs in Tavus - whether one or many - and **reuse** them. For each new conversation you call [POST /v2/conversations](/api-reference/conversations/create-conversation) and pass **per-user or per-session data** via request body fields. The PAL itself is unchanged; only the conversation-level context changes.

### What you can customize per conversation

* **Any text/data in the LLM context** - e.g. user name, profile, history, prior session summary - via [`conversational_context`](/api-reference/conversations/create-conversation) when creating the conversation.
* **Custom greeting** - via [`custom_greeting`](/api-reference/conversations/create-conversation) so each participant gets a personalized opening.

<Note title="Bonus tip">
  **Mid-session context** - You can inject or replace context during a call via WebSocket events: [append\_llm\_context](/sections/event-schemas/conversation-append-context) to add context without replacing what’s there, or [overwrite\_llm\_context](/sections/event-schemas/conversation-overwrite-context) to replace the current `conversational_context`. Useful for injecting tool results or refreshed instructions without ending the call.
</Note>

### What you cannot customize per conversation

Everything that lives on the **PAL** is shared by all conversations using that PAL:

* **Objectives**, **guardrails**, **TTS voice**, **LLM model**, **tools** - all are PAL-level. A [PATCH](/api-reference/pals/patch-pal) to the PAL affects every current and future conversation that uses it.

### Advantages

* **Low API overhead** - one call to create a conversation (`POST /v2/conversations`) with `pal_id` and optional `conversational_context`, `custom_greeting`, etc.
* **Centralized updates** - change the PAL once (e.g. system prompt, guardrails, voice) and all new conversations immediately use the new config.
* **Simple at scale** - fewer PALs to manage; no create/delete lifecycle per session.

### Disadvantages

* **No per-session behavioral isolation** - a mistaken or premature PATCH to the PAL affects every conversation using it.
* **No per-session variation** of voice, objectives, guardrails, or tools - those stay fixed at the PAL level.

### Example use cases

* **Single shared PAL, rich context per call** - A team uses one PAL and builds a detailed `conversational_context` server-side before each call (e.g. user lifecycle stage, profile, engagement history, prior session summary). During the call they can use [append\_llm\_context](/sections/event-schemas/conversation-append-context) (and optionally [respond](/sections/event-schemas/conversation-respond) events) to inject tool outputs or updated guidance without interrupting the face.
* **Centralized prompt, per-user personalization** - One PAL holds the core system prompt and behavior. Each conversation gets a different `conversational_context` (e.g. participant name, background, preferences). A single update to the PAL rolls out to all users at once while still allowing personalized greetings and questions per session.
* **Static knowledge, dynamic audience** - A single PAL is configured with fixed reference content (e.g. product FAQs, academic programs). Institution or user context is passed in via `conversational_context` per conversation.
* **Storyteller** - A PAL has a static `system_prompt` and base context; each conversation passes in the participant’s name, age, and genre preferences via `conversational_context` and optionally a `custom_greeting`.

***

## Approach B: New PAL Per Conversation (Create & Delete)

### How it works

You **define the PAL config in your own code** (or in a config file, database, etc. - however you want to store it). That “template” is not stored in Tavus. At session start you:

1. [POST /v2/pals](/api-reference/pals/create-pal) - create a new PAL with the config from your code, including any session-specific overrides (e.g. voice, objectives, guardrails, system prompt).
2. [POST /v2/conversations](/api-reference/conversations/create-conversation) - create the conversation using the new PAL’s ID.
3. When the session ends - [DELETE /v2/pals/{pal_id}](/api-reference/pals/delete-pal) to remove the ephemeral PAL.

Any changes you make to the template are in your code; you deploy or update that code when you want new sessions to pick up new behavior. In-flight sessions keep the config they were created with until they end.

### What you can customize per conversation

**Everything** that lives on a PAL can differ per session:

* **Objectives**, **guardrails**, **TTS voice**, **LLM model**, **tools**, **system\_prompt**, and any other PAL-level fields.

You can still use `conversational_context` and `custom_greeting` on the conversation for additional per-session data.

### Advantages

* **Full isolation** - no cross-session contamination. A change or mistake in one session’s PAL does not affect others.
* **Maximum flexibility** - every PAL-level setting can vary per session (e.g. different voice per conversation, different objectives per role or demo).
* **Safe for multi-tenant or demo flows** - each tenant or demo can have its own PAL instance with custom guardrails, objectives, and context.
* **No risk of a PATCH affecting live sessions** - you only patch or delete the ephemeral PAL for that session.

### Disadvantages

* **Three API calls per session** - create PAL → create conversation → delete PAL (after session end). You need reliable cleanup logic (e.g. on session-end webhook or timeout) so ephemeral PALs don’t accumulate.
* **Template updates don’t affect in-flight sessions** - only new sessions pick up changes when you deploy updated code; existing conversations keep the config they were created with.

### Example use cases

* **Different TTS voice per conversation** - Because voice is configured at the PAL level and can’t be overridden at conversation creation, one practical approach is to create a new PAL per session (from your code template) with the desired voice. This pattern is often adopted as the standard production approach when voice-per-session is a requirement.
* **Demos with custom guardrails and objectives** - Demos need custom guardrails, objectives, and PAL context per demo - all PAL-level. Define your base config in code and create a new PAL per demo with demo-specific overrides. That way you avoid maintaining a large library of static PALs in Tavus or running batch update jobs when behavior changes; the template in your code is the single source of truth.
* **Structured flows where PAL-level changes broke global state** - Teams running structured conversations (e.g. role-specific recruiting or role-play) found that changing a shared PAL’s voice or objectives affected all active conversations. Creating a PAL per session from their code template gave per-conversation isolation and avoided those side effects.
* **Event- or deployment-specific config** - For kiosks or event-specific advisors, the PAL config can vary per event or deployment (system prompt, LLM backend, TTS provider). Store the config in your code or deployment pipeline and create a fresh PAL per context when the session starts.

***

## Choosing an approach

| If you need…                                                                                     | Prefer                                                                                                                                  |
| ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| **Different data per conversation** (user name, profile, history, session goal)                  | **Approach A** - reuse PALs and use `conversational_context`, `custom_greeting`, and (optionally) mid-session context events.           |
| **Different behavior per conversation** (voice, objectives, guardrails, tools, or system prompt) | **Approach B** - define the PAL config in your code and create a new PAL per session via the API, then delete it when the session ends. |

You can combine both: for example, create a PAL per session (Approach B) and still pass `conversational_context` and `custom_greeting` when [creating the conversation](/api-reference/conversations/create-conversation) for extra per-session data.
