Skills create-squad
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.
git clone https://github.com/VapiAI/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/VapiAI/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/create-squad" ~/.claude/skills/vapiai-skills-create-squad && rm -rf "$T"
create-squad/SKILL.mdVapi 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
is set. See theVAPI_API_KEYskill if needed.setup-api-key
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" }, "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" }, "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" } } ] } }
Member Overrides
Apply configuration to ALL members simultaneously:
{ "members": [ { "assistant": { "name": "Agent A", "..." : "..." } }, { "assistantId": "agent-b-id" } ], "memberOverrides": { "voice": { "provider": "vapi", "voiceId": "Elliot" }, "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" } } }, { "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
# List squads curl https://api.vapi.ai/squad -H "Authorization: Bearer $VAPI_API_KEY" # Get a squad curl https://api.vapi.ai/squad/{id} -H "Authorization: Bearer $VAPI_API_KEY" # Update a squad 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"}' # Delete a squad curl -X DELETE https://api.vapi.ai/squad/{id} \ -H "Authorization: Bearer $VAPI_API_KEY"
References
- Vapi Squads Docs — Official documentation
- Squad Examples — More patterns
- Handoff Configuration — Detailed handoff guide
Additional Resources
This skills repository includes a Vapi documentation MCP server (
vapi-docs) that gives your AI agent access to the full Vapi knowledge base. Use the searchDocs tool to look up anything beyond what this skill covers — advanced configuration, troubleshooting, SDK details, and more.
Auto-configured: If you cloned or installed these skills, the MCP server is already configured via
.mcp.json (Claude Code), .cursor/mcp.json (Cursor), or .vscode/mcp.json (VS Code Copilot).
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 README for full setup instructions across all supported agents.