| name | vapi |
| description | 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. |
| allowed-tools | Bash, Read, Grep, Glob, WebFetch |
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
SCRIPTS=".claude/skills/vapi-platform/scripts"
bash $SCRIPTS/vapi-assistants.sh list
bash $SCRIPTS/vapi-assistants.sh list-summary
bash $SCRIPTS/vapi-assistants.sh get <id>
bash $SCRIPTS/vapi-assistants.sh create '{"name": "My Assistant", ...}'
bash $SCRIPTS/vapi-assistants.sh update <id> '{"name": "New Name"}'
bash $SCRIPTS/vapi-assistants.sh delete <id>
bash $SCRIPTS/vapi-files.sh upload /path/to/document.pdf
bash $SCRIPTS/vapi-logs.sh list "limit=10" "createdAtGt=2026-01-01T00:00:00Z"
Common Workflows
Create an assistant and make a call:
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"}
}'
bash $SCRIPTS/vapi-phone-numbers.sh list-summary
bash $SCRIPTS/vapi-calls.sh create '{
"assistantId": "ASSISTANT_ID",
"phoneNumberId": "PHONE_NUMBER_ID",
"customer": {"number": "+1XXXXXXXXXX"}
}'
Batch outbound calls:
bash $SCRIPTS/vapi-calls.sh create '{
"assistantId": "ASSISTANT_ID",
"phoneNumberId": "PHONE_NUMBER_ID",
"customers": [{"number": "+1XXXXXXXXXX"}, {"number": "+1YYYYYYYYYY"}]
}'
Scheduled call:
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 $SCRIPTS/vapi-calls.sh create '{"assistantId": "ASSISTANT_ID", "type": "webCall"}'
Import Twilio number:
bash $SCRIPTS/vapi-phone-numbers.sh create '{
"provider": "twilio",
"number": "+1XXXXXXXXXX",
"twilioAccountSid": "AC...",
"twilioAuthToken": "TOKEN",
"assistantId": "ASSISTANT_ID"
}'
Create function tool:
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 $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 $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 $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."}]
}
}
}
]
}'
bash $SCRIPTS/vapi-eval-runs.sh run '{
"type": "eval",
"evalId": "EVAL_ID",
"target": {"type": "assistant", "assistantId": "ASSISTANT_ID"}
}'
bash $SCRIPTS/vapi-eval-runs.sh poll <RUN_ID>
Run inline eval (without saving, type: "eval" is always required):
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
- Scripts use
grep-based key loading — not source .env (avoids side effects from other env vars)
- Always use the Private Key (
$VAPI_PRIVATE_API_KEY) — public key can list but not get/mutate
- 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.
- Always GET before PATCH — fetch the current assistant config first, then merge your changes into the full object before sending the update
- Confirm destructive operations (delete) before executing
- Validate IDs look like UUIDs before making requests
- Use
list-summary for quick overviews, list for full JSON
- Never expose the API key in output or logs
- 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:
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)