create-squad

$npx mdskill add VapiAI/skills/create-squad

Create multi-assistant squads with handoffs between specialized voice agents.

  • Solves complexity and hallucination in large single-assistant voice workflows.
  • Requires internet access and a Vapi API key (VAPI_API_KEY).
  • Breaks workflows into focused assistants with specific roles like triage or booking.
  • Returns a squad configuration that orchestrates context-preserving handoffs.

SKILL.md

.github/skills/create-squadView on GitHub ↗
---
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

```bash
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)

```typescript
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: "..."`

```json
{
  "members": [
    { "assistant": { "name": "Inline Assistant", "..." : "..." } },
    { "assistantId": "saved-assistant-id" }
  ]
}
```

### Handoff Tools

Handoff tools define how assistants transfer between each other:

```json
{
  "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:

```json
{
  "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:

```json
{
  "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:

```json
{
  "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

```bash
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

```json
{
  "squad": {
    "members": [
      { "assistant": { "..." : "..." } },
      { "assistantId": "..." }
    ]
  },
  "phoneNumberId": "phone-number-id",
  "customer": { "number": "+11234567890" }
}
```

## Common Patterns

### Clinic Triage → Scheduling

```json
{
  "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

```json
{
  "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

1. **Keep assistants focused** — Each assistant should have 1-3 goals maximum
2. **Minimize squad size** — Split only when there's a clear functional boundary
3. **Write specific handoff descriptions** — The LLM uses these to decide when to transfer
4. **Mention handoffs in system prompts** — Tell each assistant what departments exist
5. **Use member overrides** — Apply consistent voice and transcriber settings across the squad

## Managing Squads

```bash
# 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",
    "members": [
      { "assistantId": "first-assistant-id" },
      { "assistantId": "second-assistant-id" }
    ]
  }'

# Delete a squad
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

- [Vapi Squads Docs](https://docs.vapi.ai/squads) — Official documentation
- [Squad Examples](https://docs.vapi.ai/squads-example) — More patterns
- [Handoff Configuration](https://docs.vapi.ai/squads/handoff) — Detailed handoff guide

## 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:
```bash
claude mcp add vapi-docs -- npx -y mcp-remote https://docs.vapi.ai/_mcp/server
```

See the [Vapi MCP integration guide](https://docs.vapi.ai/cli/mcp) for setup instructions across supported agents.

More from VapiAI/skills

SkillDescription
create-assistantCreate Vapi voice AI assistant payloads or assistants through the Vapi API. Use when building phone or web call agents, generating assistant JSON, choosing safe default model/voice/transcriber settings, attaching existing Vapi tool IDs, adding assistant hooks, configuring HIPAA/compliance only when explicitly requested, or fixing Vapi assistant API validation errors.
create-callCreate outbound phone calls, web calls, and batch calls using the Vapi API. Use when making automated calls, testing voice assistants, scheduling call campaigns, or initiating conversations programmatically.
create-phone-numberSet up and manage phone numbers in Vapi for inbound and outbound voice AI calls. Use when importing Twilio, Vonage, or Telnyx numbers, buying Vapi numbers, or configuring phone numbers for assistants.
create-toolCreate custom tools for Vapi voice assistants including function tools, API request tools, transfer call tools, end call tools, and integrations with Google Calendar, Sheets, Slack, and more. Use when adding capabilities to voice agents, building tool servers, or integrating external APIs.
setup-api-keyGuide users through obtaining and configuring a Vapi API key. Use when the user needs to set up Vapi, when API calls fail due to missing keys, or when the user mentions needing access to Vapi's voice AI platform.
setup-webhookConfigure Vapi server URLs and webhooks to receive real-time call events, transcripts, tool calls, and end-of-call reports. Use when setting up webhook endpoints, building tool servers, or integrating Vapi events into your application.
vapi-bootstrap-frameworkScaffold a complete Vapi voice-agent project from a ROUGH_DRAFT.md spec. Generates package.json, tsconfig.json, .env.example, .gitignore, and the full TypeScript framework — scenario registry, per-language voice/transcriber stack, prompt composer, assistant builder, and an idempotent bootstrap script — plus one rough first-draft body.md per scenario. Drop this skill in any project's .cursor/skills/ folder (or ~/.cursor/skills/ for global use), write a ROUGH_DRAFT.md at the project root, name the skill, and `bun run bootstrap` puts the entire fleet live in dashboard.vapi.ai. Use when the user asks to scaffold or bootstrap Vapi voice agents from a rough draft, build a Vapi assistant fleet, or invokes this skill by name. Targets Bun + TypeScript + @vapi-ai/server-sdk.
vapi-prompt-builderCreate, improve, or audit Vapi voice agent and Squad system prompts for production phone and web based voice agents. Use when the user wants help designing a Vapi assistant prompt, multi-assistant Squad prompt set, refining an existing prompt, creating prompt sections, building an intake or handoff workflow, improving tool-use instructions, adding guardrails, or optimizing voice-agent behavior for brevity, turn-taking, error handling, caller data collection, escalation, handoffs, and spoken formatting.