Skip to navigation

Pass context and variables

Control the history and values available after a handoff

A handoff carries conversation messages and variable values separately. Set contextEngineeringPlan on the destination to choose which earlier messages its model sees. The destination gets its own system prompt in every mode.

Values already collected in the call remain available to later assistants even if the destination receives no earlier messages.

The destination’s system prompt is the first system message in its model.messages. On a handoff, any additional system messages in that array are dropped, so combine all destination instructions into a single system message.

Context engineering

Set contextEngineeringPlan on an assistant or squad destination. It filters the messages sent to that destination; it does not clear saved variables.

TypeEarlier messages the destination receives
all (default)All earlier conversation messages, including tool calls and results. The previous system prompt is replaced by the destination’s system prompt.
lastNMessagesThe most recent maxMessages messages. Use a positive value: 0 currently selects all messages.
userAndAssistantMessagesUser and assistant messages; tool calls and tool results are excluded.
previousAssistantMessagesMessages from before the current assistant received its incoming handoff. On the first handoff, there is no earlier assistant context to carry.
noneNo earlier conversation messages.

For example, this destination receives the ten most recent messages:

{
"type": "assistant",
"assistantName": "Specialist",
"contextEngineeringPlan": {
"type": "lastNMessages",
"maxMessages": 10
}
}

previousAssistantMessages and none filter the destination model’s message history. They do not erase values already in the variable bag or remove messages from a full-history call artifact. If you handle sensitive information, control what is collected, stored, extracted, and passed in variables as well as message history.

Variable extraction

Choose how a value reaches the destination based on its source:

Value sourceWhen it runsWhat reaches the destination
Standard call and time valuesVapi makes supported values available for the call or channel. See Dynamic variables.Available values such as customer.number, call.id, and now can render in the prompt.
Initial custom valuesSupply assistantOverrides.variableValues when starting the call.Those named values can render in the destination prompt.
Earlier tool responseConfigure variableExtractionPlan.aliases on the result-producing tool; it selects fields when the tool returns.Only selected alias values are saved. A JSON response alone is not copied into the variable bag.
Handoff argumentsDefine custom function.parameters on the handoff tool; the model fills them in the outgoing handoff tool call.Every argument except destination is added to the bag.
Conversation contentDefine variableExtractionPlan.schema on the destination; a separate model request runs at handoff.Top-level properties in the extracted object are added to the bag if extraction succeeds.
Existing bag valueLiquid runs when the destination prompt is rendered.A reference such as {{customerName}} reads the current value; it does not extract one.

At handoff, Vapi adds tool arguments, then any schema-extracted values, then the chosen destination’s assistantOverrides.variableValues or squadOverrides.variableValues. If the same key is set more than once, the later value wins.

Handoff arguments

Use function.parameters when the outgoing assistant can provide a value as it decides to hand off. This tool passes customerIntent to Specialist:

{
"type": "handoff",
"destinations": [
{
"type": "assistant",
"assistantName": "Specialist",
"description": "Handle billing questions"
}
],
"function": {
"name": "handoff_to_specialist",
"parameters": {
"type": "object",
"properties": {
"destination": {
"type": "string",
"enum": ["Specialist"]
},
"customerIntent": {
"type": "string",
"description": "The caller's reason for contacting billing"
}
},
"required": ["destination", "customerIntent"]
}
}
}

The destination can use {{customerIntent}} in its prompt. destination selects the target and is not saved as a variable. For fixed destinations, Vapi derives the allowed destination values from the configured destinations. Dynamic routing can leave destination optional so the webhook can resolve it. Since the model supplies custom arguments, verify critical IDs against a trusted source.

Destination schema extraction

Use variableExtractionPlan.schema on the destination when you need a separate request to extract information from the outgoing assistant’s currently available conversation:

{
"type": "assistant",
"assistantName": "Specialist",
"variableExtractionPlan": {
"schema": {
"type": "object",
"properties": {
"customerName": {
"type": "string",
"description": "Name the caller gave during the conversation"
}
},
"required": ["customerName"]
}
}
}

The destination can read the top-level property as {{customerName}}. A nested object can be read with a path such as {{shippingAddress.city}}. An earlier history filter can limit what the extraction request sees; it does not recover messages removed from the outgoing assistant’s context.

Extraction is best effort. Without a schema, the plan adds nothing. If the request fails or returns a non-object, the handoff continues without new extracted values. A required schema property is not guaranteed to be available in the destination prompt.

Use tool-result aliases on the tool that produces a response when you need exact fields from that response. A handoff destination’s variableExtractionPlan uses its schema for conversation extraction; aliases there are not applied by the current handoff path.

Reuse values after another handoff

Suppose assistant A passes customerIntent as a handoff argument to B. B extracts customerName, then hands off to C with contextEngineeringPlan.type set to none. C receives no earlier conversation messages, but can still use {{customerIntent}} and {{customerName}} from the shared variable bag. If B sets customerIntent again, its later value replaces A’s value.

Configuration paths and verification

The history and variable rules above apply to a completed assistant or squad handoff. Check how the handoff is configured:

PathWhat to check
Saved squad, API or DashboardUse a handoff tool on the outgoing assistant, or configure a squad member’s Handoff Tools. For custom function.parameters, configure the tool itself; the squad member Handoff Tools setting creates a tool without those parameters.
Saved handoff tool in the DashboardThe Tools page exposes function parameters for the handoff tool. Save the tool and attach it to the outgoing assistant.
Standalone assistant in a live callA destination can identify a saved assistant by assistantId, or provide an inline assistant. Verify the destination resolves in the call.
/chat APIAssistant destinations require a squad context with more than one assistant. A standalone assistant’s handoff tool call can return a handoff result without activating its destination.
Dynamic destinationA handoff-destination-request webhook chooses the destination at runtime. Its returned destination can include context and extraction plans. See Dynamic handoffs.

To confirm a handoff, inspect the call or chat transcript for the outgoing handoff tool call and the next assistant’s response. For calls, use call.id to correlate records and inspect artifact.variableValues for values retained in the call. The active conversation used by analysis may differ from the artifact after context filtering; set artifactPlan.fullMessageHistoryEnabled if you need the full cross-assistant message history in the call artifact.