# Vapi

> Manages the Vapi voice AI platform API. Use when the user wants to create, list, update, or delete Vapi resources (assistants, calls, phone numbers, squads, tools, files, knowledge bases, blocks, sessions, campaigns, logs, evals, eval runs), make outbound calls, configure voice pipelines, run eval tests against assistants, or manage their Vapi account. Handles all CRUD operations against the Vapi REST API.

- Skill: `profsynapse/vapi` (Agent Skill, multi-file: 20 files)
- Install (CLI): `npx skillmds@latest add profsynapse/vapi`
- Raw SKILL.md: https://api.skillmd.com/api/skills/profsynapse/vapi/raw
- Safety review: pending (external: skill-scanner WARNING, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: ProfSynapse (https://skillmd.com/u/profsynapse)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/profsynapse/vapi

---


# Vapi Platform Skill

Manage the full Vapi voice AI platform through CLI scripts wrapping the REST API (`https://api.vapi.ai`).

## Authentication

| Key | Env Variable | Use For |
|-----|-------------|---------|
| **Private Key** | `VAPI_PRIVATE_API_KEY` | All API operations (required) |
| **Public Key** | `VAPI_PUBLIC_API_KEY` | Client-side SDK only |

Add to `.env`:
```
VAPI_PRIVATE_API_KEY=your-private-key-here
```

Scripts auto-load from `.env` using `grep` (not `source`). Override path with `VAPI_ENV_FILE=/path/to/.env`.

## CLI Scripts

All scripts live in `.claude/skills/vapi-platform/scripts/`. Each handles one resource type with subcommands.

### Quick Reference

| Script | Resource | Operations |
|--------|----------|------------|
| `vapi-assistants.sh` | Assistants | list, list-summary, get, create, update, delete |
| `vapi-calls.sh` | Calls | list, get, create, update, delete |
| `vapi-phone-numbers.sh` | Phone Numbers | list, list-summary, get, create, update, delete |
| `vapi-squads.sh` | Squads | list, list-summary, get, create, update, delete |
| `vapi-tools.sh` | Tools | list, list-summary, get, create, update, delete |
| `vapi-files.sh` | Files | list, list-summary, get, upload, delete |
| `vapi-knowledge-bases.sh` | Knowledge Bases | list, list-summary, get, create, update, delete |
| `vapi-blocks.sh` | Blocks | list, list-summary, get, create, update, delete |
| `vapi-sessions.sh` | Sessions | list, get, create |
| `vapi-chats.sh` | Chats | list, create |
| `vapi-campaigns.sh` | Campaigns | list, list-summary, get, create, update |
| `vapi-logs.sh` | Logs | list, get |
| `vapi-evals.sh` | Evals | list, list-summary, get, create, update, delete |
| `vapi-eval-runs.sh` | Eval Runs | list, list-summary, get, run, poll |

### Usage Pattern

```bash
SCRIPTS=".claude/skills/vapi-platform/scripts"

# List resources
bash $SCRIPTS/vapi-assistants.sh list
bash $SCRIPTS/vapi-assistants.sh list-summary

# Get by ID
bash $SCRIPTS/vapi-assistants.sh get <id>

# Create (pass JSON body)
bash $SCRIPTS/vapi-assistants.sh create '{"name": "My Assistant", ...}'

# Update (pass ID + JSON body)
bash $SCRIPTS/vapi-assistants.sh update <id> '{"name": "New Name"}'

# Delete
bash $SCRIPTS/vapi-assistants.sh delete <id>

# Upload file (special case)
bash $SCRIPTS/vapi-files.sh upload /path/to/document.pdf

# Filter with query params
bash $SCRIPTS/vapi-logs.sh list "limit=10" "createdAtGt=2026-01-01T00:00:00Z"
```

### Common Workflows

**Create an assistant and make a call:**
```bash
# 1. Create assistant
bash $SCRIPTS/vapi-assistants.sh create '{
  "name": "Receptionist",
  "firstMessage": "Hello! How can I help?",
  "transcriber": {"provider": "deepgram", "model": "nova-3", "language": "en"},
  "model": {"provider": "openai", "model": "gpt-4o", "systemPrompt": "You are a helpful receptionist."},
  "voice": {"provider": "11labs", "voiceId": "rachel"}
}'

# 2. List phone numbers
bash $SCRIPTS/vapi-phone-numbers.sh list-summary

# 3. Make outbound call
bash $SCRIPTS/vapi-calls.sh create '{
  "assistantId": "ASSISTANT_ID",
  "phoneNumberId": "PHONE_NUMBER_ID",
  "customer": {"number": "+1XXXXXXXXXX"}
}'
```

**Batch outbound calls:**
```bash
bash $SCRIPTS/vapi-calls.sh create '{
  "assistantId": "ASSISTANT_ID",
  "phoneNumberId": "PHONE_NUMBER_ID",
  "customers": [{"number": "+1XXXXXXXXXX"}, {"number": "+1YYYYYYYYYY"}]
}'
```

**Scheduled call:**
```bash
bash $SCRIPTS/vapi-calls.sh create '{
  "assistantId": "ASSISTANT_ID",
  "phoneNumberId": "PHONE_NUMBER_ID",
  "customer": {"number": "+1XXXXXXXXXX"},
  "schedulePlan": {"earliestAt": "2026-03-01T10:00:00Z", "latestAt": "2026-03-01T12:00:00Z"}
}'
```

**Web call (no phone number):**
```bash
bash $SCRIPTS/vapi-calls.sh create '{"assistantId": "ASSISTANT_ID", "type": "webCall"}'
```

**Import Twilio number:**
```bash
bash $SCRIPTS/vapi-phone-numbers.sh create '{
  "provider": "twilio",
  "number": "+1XXXXXXXXXX",
  "twilioAccountSid": "AC...",
  "twilioAuthToken": "TOKEN",
  "assistantId": "ASSISTANT_ID"
}'
```

**Create function tool:**
```bash
bash $SCRIPTS/vapi-tools.sh create '{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get weather for a location",
    "parameters": {
      "type": "object",
      "properties": {"location": {"type": "string", "description": "City name"}},
      "required": ["location"]
    }
  },
  "server": {"url": "https://your-server.com/api/weather"}
}'
```

**Upload file and create knowledge base:**
```bash
bash $SCRIPTS/vapi-files.sh upload /path/to/faq.pdf
bash $SCRIPTS/vapi-knowledge-bases.sh create '{
  "name": "Product FAQ",
  "fileIds": ["FILE_ID_1"],
  "provider": "google"
}'
```

**Create multi-assistant squad:**
```bash
bash $SCRIPTS/vapi-squads.sh create '{
  "name": "Customer Service Squad",
  "members": [{"assistantId": "GREETER_ID"}, {"assistantId": "BOOKING_ID"}]
}'
```

**Create eval and run it against an assistant:**
```bash
# 1. Create an eval definition
bash $SCRIPTS/vapi-evals.sh create '{
  "name": "Greeting test",
  "type": "chat.mockConversation",
  "messages": [
    {"role": "user", "content": "Hello"},
    {
      "role": "assistant",
      "judgePlan": {
        "type": "ai",
        "model": {
          "provider": "openai",
          "model": "gpt-4o",
          "messages": [{"role": "system", "content": "Did the assistant greet warmly and offer help? Output pass or fail."}]
        }
      }
    }
  ]
}'

# 2. Run eval against assistant (type: "eval" is required)
bash $SCRIPTS/vapi-eval-runs.sh run '{
  "type": "eval",
  "evalId": "EVAL_ID",
  "target": {"type": "assistant", "assistantId": "ASSISTANT_ID"}
}'

# 3. Poll for results
bash $SCRIPTS/vapi-eval-runs.sh poll <RUN_ID>
```

**Run inline eval (without saving, type: "eval" is always required):**
```bash
bash $SCRIPTS/vapi-eval-runs.sh run '{
  "type": "eval",
  "eval": {
    "type": "chat.mockConversation",
    "messages": [
      {"role": "user", "content": "Book me for tomorrow at 10am"},
      {
        "role": "assistant",
        "judgePlan": {
          "type": "exact",
          "toolCalls": [{"name": "bookAppointment", "arguments": {"date": "2026-03-07", "time": "10:00"}}]
        }
      }
    ]
  },
  "target": {"type": "assistant", "assistantId": "ASSISTANT_ID"}
}'
```

## Argument Handling

When the user provides arguments like `/vapi list assistants`, map to scripts:
- `list {resource}` → `bash $SCRIPTS/vapi-{resource}.sh list`
- `get {resource} {id}` → `bash $SCRIPTS/vapi-{resource}.sh get {id}`
- `create {resource}` → Guide through creation, then `bash $SCRIPTS/vapi-{resource}.sh create '<json>'`
- `update {resource} {id}` → Guide through update, then `bash $SCRIPTS/vapi-{resource}.sh update {id} '<json>'`
- `delete {resource} {id}` → Confirm, then `bash $SCRIPTS/vapi-{resource}.sh delete {id}`
- `call {number}` → Create outbound call (ask for assistant/phone number IDs)
- `status` → `bash $SCRIPTS/vapi-calls.sh list` + `bash $SCRIPTS/vapi-assistants.sh list-summary`

## Operational Guidelines

1. **Scripts use `grep`-based key loading** — not `source .env` (avoids side effects from other env vars)
2. **Always use the Private Key** (`$VAPI_PRIVATE_API_KEY`) — public key can list but not get/mutate
3. **PATCH replaces nested objects entirely** — when updating any field inside `model` (e.g., temperature, provider), you MUST include the **full `model` object** including `messages`, `toolIds`, etc. Otherwise they get wiped. Top-level fields (`firstMessage`, `voice`, `transcriber`) are safe to patch individually.
4. **Always GET before PATCH** — fetch the current assistant config first, then merge your changes into the full object before sending the update
5. **Confirm destructive operations** (delete) before executing
6. **Validate IDs** look like UUIDs before making requests
7. **Use `list-summary`** for quick overviews, `list` for full JSON
8. **Never expose the API key** in output or logs
9. **On 401 errors** — verify using Private Key, check `.env` file has the key

## Configuration Reference

For detailed schemas, voice pipeline config, transcribers, LLM providers, TTS providers, hooks, and analysis plans:
- [api-reference.md](references/api-reference.md) — Full endpoint schemas and response formats
- [configuration-guide.md](references/configuration-guide.md) — Voice pipeline, hooks, analysis plans

## Provider Quick Reference

**Transcribers (STT):** `deepgram` (nova-3), `assembly-ai`, `azure`, `gladia`, `google`, `elevenlabs`, `openai` (whisper), `speechmatics`, `custom`

**LLM:** `openai` (gpt-4o, gpt-4o-mini), `anthropic` (claude-3-5-sonnet), `google` (gemini-1.5-pro), `groq` (llama, mixtral), `custom`

**Voice/TTS:** `11labs`, `playht`, `azure`, `deepgram`, `lmnt`, `cartesia`, `rime`, `neets`, `custom`

**Telephony:** `twilio`, `vonage`, `telnyx`, `vapi` (built-in, limited)

