| name | create-squad |
| description | Create multi-assistant squads in Vapi with handoffs between specialized voice agents. Use when building complex voice workflows that need multiple assistants with different roles, like triage-to-booking or sales-to-support handoffs. |
| license | MIT |
| compatibility | Requires internet access and a Vapi API key (VAPI_API_KEY). |
| metadata | {"author":"vapi","version":"1.0"} |
Vapi Squad Creation
Create squads that orchestrate multiple specialized assistants with context-preserving handoffs. Break complex workflows into focused assistants that transfer calls between each other.
Setup: Ensure VAPI_API_KEY is set. See the setup-api-key skill if needed.
Why Squads?
Single assistants with large prompts cause higher hallucination rates, increased costs, and greater latency. Squads solve this by creating focused assistants with specific roles:
- Triage → Booking → Confirmation
- Sales → Technical Support → Billing
- Receptionist → Department Specialist
Quick Start
cURL
curl -X POST https://api.vapi.ai/squad \
-H "Authorization: Bearer $VAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Support Squad",
"members": [
{
"assistant": {
"name": "Receptionist",
"firstMessage": "Hello! How can I direct your call today?",
"model": {
"provider": "openai",
"model": "gpt-4.1",
"messages": [
{
"role": "system",
"content": "You are a receptionist. Determine if the caller needs sales or support, then transfer them to the right department."
}
],
"tools": [
{
"type": "handoff",
"destinations": [
{
"type": "assistant",
"assistantId": "sales-assistant-id",
"description": "Transfer when the caller asks about pricing, plans, or wants to purchase"
},
{
"type": "assistant",
"assistantId": "support-assistant-id",
"description": "Transfer when the caller has a technical issue or needs help"
}
]
}
]
},
"voice": { "provider": "vapi", "voiceId": "Lily", "version": 2 },
"transcriber": { "provider": "deepgram", "model": "nova-3", "language": "en" }
}
},
{
"assistantId": "sales-assistant-id"
},
{
"assistantId": "support-assistant-id"
}
]
}'
TypeScript (Server SDK)
import { VapiClient } from "@vapi-ai/server-sdk";
const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! });
const squad = await vapi.squads.create({
name: "Support Squad",
members: [
{
assistant: {
name: "Receptionist",
firstMessage: "Hello! How can I direct your call today?",
model: {
provider: "openai",
model: "gpt-4.1",
messages: [
{
role: "system",
content:
"You are a receptionist. Determine if the caller needs sales or support, then transfer them.",
},
],
tools: [
{
type: "handoff",
destinations: [
{
type: "assistant",
assistantId: "sales-assistant-id",
description: "Transfer for pricing and purchasing questions",
},
{
type: "assistant",
assistantId: "support-assistant-id",
description: "Transfer for technical issues",
},
],
},
],
},
voice: { provider: "vapi", voiceId: "Lily" },
transcriber: { provider: "deepgram", model: "nova-3", language: "en" },
},
},
{ assistantId: "sales-assistant-id" },
{ assistantId: "support-assistant-id" },
],
});
console.log("Squad created:", squad.id);
Squad Structure
Members
The first member in the array starts the call. Each member is either:
- Transient — Defined inline with
assistant: { ... }
- Persistent — References a saved assistant via
assistantId: "..."
{
"members": [
{ "assistant": { "name": "Inline Assistant", "..." : "..." } },
{ "assistantId": "saved-assistant-id" }
]
}
Handoff Tools
Handoff tools define how assistants transfer between each other:
{
"type": "handoff",
"destinations": [
{
"type": "assistant",
"assistantId": "target-assistant-id",
"description": "Clear description of WHEN to transfer. Be specific about trigger conditions."
}
],
"function": {
"name": "handoff_to_sales"
}
}
Assistant Overrides
Override saved assistant settings within the squad context without modifying the original:
{
"assistantId": "saved-assistant-id",
"assistantOverrides": {
"voice": { "provider": "vapi", "voiceId": "Elliot", "version": 2 },
"firstMessage": "Overridden greeting for this squad"
}
}
Appending Tools via Overrides
Add squad-specific tools to a saved assistant:
{
"assistantId": "saved-assistant-id",
"assistantOverrides": {
"tools:append": [
{
"type": "handoff",
"destinations": [
{
"type": "assistant",
"assistantId": "another-assistant-id",
"description": "Transfer when customer needs billing help"
}
],
"function": { "name": "handoff_to_billing" }
}
]
}
}
Members Overrides
Apply configuration to ALL members simultaneously:
{
"members": [
{ "assistant": { "name": "Agent A", "..." : "..." } },
{ "assistantId": "agent-b-id" }
],
"membersOverrides": {
"voice": { "provider": "vapi", "voiceId": "Elliot", "version": 2 },
"transcriber": { "provider": "deepgram", "model": "nova-3", "language": "en" }
}
}
Using Squads in Calls
Outbound call with a squad
curl -X POST https://api.vapi.ai/call \
-H "Authorization: Bearer $VAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"squadId": "your-squad-id",
"phoneNumberId": "your-phone-number-id",
"customer": {
"number": "+11234567890"
}
}'
Transient squad in a call
{
"squad": {
"members": [
{ "assistant": { "..." : "..." } },
{ "assistantId": "..." }
]
},
"phoneNumberId": "phone-number-id",
"customer": { "number": "+11234567890" }
}
Common Patterns
Clinic Triage → Scheduling
{
"name": "Clinic Squad",
"members": [
{
"assistant": {
"name": "Triage Nurse",
"firstMessage": "Hello, this is the clinic. How can I help you today?",
"model": {
"provider": "openai",
"model": "gpt-4.1",
"messages": [
{
"role": "system",
"content": "You are a clinic triage assistant. Assess the caller's needs: if they need an appointment, transfer to scheduling. If it's urgent, transfer to the nurse line."
}
],
"tools": [
{
"type": "handoff",
"destinations": [
{
"type": "assistant",
"assistantId": "scheduling-assistant-id",
"description": "Transfer when caller wants to book, reschedule, or cancel an appointment"
},
{
"type": "assistant",
"assistantId": "nurse-assistant-id",
"description": "Transfer for urgent medical questions or symptoms"
}
]
}
]
},
"voice": { "provider": "vapi", "voiceId": "Lily", "version": 2 }
}
},
{ "assistantId": "scheduling-assistant-id" },
{ "assistantId": "nurse-assistant-id" }
]
}
E-commerce: Sales → Support → Returns
{
"name": "E-commerce Squad",
"members": [
{
"assistant": {
"name": "Sales Agent",
"firstMessage": "Welcome to our store! Are you looking to make a purchase today?",
"model": {
"provider": "openai",
"model": "gpt-4.1",
"messages": [
{ "role": "system", "content": "You are a sales assistant. Help customers find products and make purchases. Transfer to support for order issues or returns." }
],
"tools": [
{
"type": "handoff",
"destinations": [
{ "type": "assistant", "assistantId": "support-id", "description": "Transfer for order status, shipping, or account issues" },
{ "type": "assistant", "assistantId": "returns-id", "description": "Transfer for returns, refunds, or exchanges" }
]
}
]
}
}
},
{ "assistantId": "support-id" },
{ "assistantId": "returns-id" }
]
}
Best Practices
- Keep assistants focused — Each assistant should have 1-3 goals maximum
- Minimize squad size — Split only when there's a clear functional boundary
- Write specific handoff descriptions — The LLM uses these to decide when to transfer
- Mention handoffs in system prompts — Tell each assistant what departments exist
- Use member overrides — Apply consistent voice and transcriber settings across the squad
Managing Squads
curl https://api.vapi.ai/squad -H "Authorization: Bearer $VAPI_API_KEY"
curl https://api.vapi.ai/squad/{id} -H "Authorization: Bearer $VAPI_API_KEY"
curl -X PATCH https://api.vapi.ai/squad/{id} \
-H "Authorization: Bearer $VAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Squad Name",
"members": [
{ "assistantId": "first-assistant-id" },
{ "assistantId": "second-assistant-id" }
]
}'
curl -X DELETE https://api.vapi.ai/squad/{id} \
-H "Authorization: Bearer $VAPI_API_KEY"
The update API requires the complete members array. Retrieve the current squad first and preserve every member when changing its name or overrides.
References
Additional Resources
Vapi provides a documentation MCP server that gives compatible AI agents access to the Vapi knowledge base. Use its documentation search for advanced configuration, troubleshooting, SDK details, and anything beyond this skill.
Manual setup: If your agent doesn't auto-detect the config, run:
claude mcp add vapi-docs -- npx -y mcp-remote https://docs.vapi.ai/_mcp/server
See the Vapi MCP integration guide for setup instructions across supported agents.