Reference
Voizbot API documentation
Use the public API to authenticate, place outbound calls, manage inbound routing, configure function tools, and inspect transcripts, recordings, and call logs.
Overview
Voizbot is API-first. Public endpoints live under https://api.voizbot.com/v1 (for example /v1/calls).
Use the API to place outbound calls, manage inbound templates, define function tools, and read call logs, transcripts, and recordings.
Response conventions
- Success payloads include
{ "ok": true }plus endpoint-specific fields (see each operation). - Simple deletes and some writes return only
{ "ok": true }— we do not repeat that shape on every endpoint below. - Errors use
{ "ok": false, "error": "<code>" }; validation issues may include adetailsobject (see Errors). 201 Createdis returned for some POSTs that create a resource; the body still hasok: trueplus the created object.
Authentication
Every request to /v1/* must send Authorization: Bearer VOIZBOT_TOKEN (token from Voizbot settings).
curl -X GET "https://api.voizbot.com/v1/calls?limit=20" -H "Authorization: Bearer VOIZBOT_TOKEN"Missing or invalid tokens receive 401 with { "ok": false, "error": "unauthorized" }.
Phone Numbers
/phone-numbersLists the phone numbers available to your organization. Use this endpoint to discover the phoneNumberId required by outbound calls.
Request
No query parameters.
Response
200 — ok, phoneNumbers array with id, e164, friendlyName, label, provider, status, inboundTemplateId, createdAt, and updatedAt.
Example
curl -X GET "https://api.voizbot.com/v1/phone-numbers" \
-H "Authorization: Bearer VOIZBOT_TOKEN"Voice Providers and Models
Choose the voice in Inbound or Outbound Calling when editing a template, or override it in Place call. The same selection is available through the API. Google/Gemini remains the default; OpenAI GPT-Live is an independent provider hosted on Azure Foundry.
Calls and both template APIs accept voiceProvider (google or openai), model (the AI model), and voiceModel (the voice timbre; legacy name). Omitted fields inherit from the template. Changing provider resets incompatible inherited model and timbre defaults. Explicit incompatible pairs return 400 invalid_voice_selection. Missing provider configuration returns 422 before dialing; dry runs do not require provider credentials.
/voice-modelsDiscover the voice provider/model catalog before creating a template or a call. Requires your organization API token.
Request
No query parameters. Azure credentials are never sent in call payloads.
Response
200 — ok and models, with provider, model, label, defaultVoice and configured. OpenAI readiness is gateway-managed; Google uses your organization key in Settings or the gateway fallback (configured is null).
Example
{
"phoneNumberId": "YOUR_PHONE_NUMBER_ID",
"to": "+34600000000",
"systemPrompt": "Habla en español y confirma la cita.",
"voiceProvider": "openai",
"model": "gpt-live-1",
"voiceModel": "marin",
"dryRun": true
}The JSON above is a POST /calls/outbound example: dryRun creates a job without dialing. GPT-Live uses a separate reasoning deployment and continues listening while speaking or running tools. Your administrator configures the Azure voice and reasoning deployments on the gateway. Voice minutes and backend reasoning are billed separately. The public landing demo remains on Google.
Outbound Calls
/calls/outboundStarts an outbound call from one of your phone numbers (Twilio must be configured unless dryRun is true).
Request
JSON body. Required: phoneNumberId (must belong to your organization), to (destination number).
Optional: templateId (outbound template), systemPrompt (direct prompt), extraSystemPrompt (appended to template/direct prompt), voiceModel or voice_model, metadata (string / number / boolean values), dryRun (boolean, no Twilio call), functionToolIds (tool IDs), extraFunctionToolIds (extra tool IDs added to the template tools), customTools (inline tool definitions with name, description, webhookUrl, optional schema and headers).
Response
200 — Real call: ok, jobId, sid (Twilio Call SID), status, statusLabel, to, from, webhookUrl, statusCallbackUrl, job (full job record).
200 — dryRun: true: ok, dryRun, jobId, job (no Twilio fields).
400 invalid_payload · 404 phone_not_found / template_not_found · 422 no_twilio (Twilio not configured) · 500 call creation failed (includes jobId when applicable).
Example
curl -X POST "https://api.voizbot.com/v1/calls/outbound" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phoneNumberId": "pn_123",
"to": "+14155550123",
"templateId": "out_tpl_01",
"extraSystemPrompt": "Mention the 10% discount if they confirm today.",
"extraFunctionToolIds": ["tool_check_availability"],
"metadata": { "customerId": "cus_7821" }
}'Outbound Templates
/outbound-templatesLists outbound templates for your organization.
Request
No query parameters.
Response
200 — { "ok": true, "templates": [...] }.
Example
curl -X GET "https://api.voizbot.com/v1/outbound-templates" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/outbound-templatesCreates an outbound template.
Request
JSON body: name, systemPrompt (required), optional voiceModel.
Response
201 — { "ok": true, "template": { ... } }.
Example
curl -X POST "https://api.voizbot.com/v1/outbound-templates" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Cold lead follow-up",
"systemPrompt": "Introduce yourself, qualify interest, and schedule a call if positive."
}'/outbound-templates/:idUpdates an outbound template.
Request
Path: template id. JSON body: any of name, systemPrompt, voiceModel (nullable), active.
Response
200 — { "ok": true, "template": { ... } }.
Example
curl -X PATCH "https://api.voizbot.com/v1/outbound-templates/out_tpl_01" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Updated name" }'/outbound-templates/:idDeletes an outbound template.
Request
Path: template id. No body.
Response
200 — minimal success (see conventions).
Example
curl -X DELETE "https://api.voizbot.com/v1/outbound-templates/out_tpl_01" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/outbound-templates/:id/function-toolsLists function tools linked to an outbound template.
Request
Path: template id.
Response
200 — { "ok": true, "tools": [...] }.
Example
curl -X GET "https://api.voizbot.com/v1/outbound-templates/out_tpl_01/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/outbound-templates/:id/function-toolsAssigns a function tool to an outbound template.
Request
Path: template id. JSON body: { "functionToolId": "<id>" }.
Response
201 — assigned. 200 with already_assigned if already linked.
Example
curl -X POST "https://api.voizbot.com/v1/outbound-templates/out_tpl_01/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "functionToolId": "tool_xyz" }'/outbound-templates/:id/function-toolsRemoves a function tool from an outbound template.
Request
Path: template id. JSON body: { "functionToolId": "<id>" }.
Response
200 — minimal success (see conventions).
Example
curl -X DELETE "https://api.voizbot.com/v1/outbound-templates/out_tpl_01/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "functionToolId": "tool_xyz" }'Inbound Templates
/inbound-templatesLists all inbound templates for your organization, with phone numbers assigned to each.
Request
No query parameters.
Response
200 — { "ok": true, "templates": [...] }. Each template includes DB fields (for example id, name, systemPrompt, voiceModel, timestamps) plus assignedNumbers (array of { id, e164, friendlyName }).
Example
curl -X GET "https://api.voizbot.com/v1/inbound-templates" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/inbound-templatesCreates a template.
Request
JSON body: name, systemPrompt (required); voiceModel optional.
Response
201 — { "ok": true, "template": { ...row, "assignedNumbers": [] } }.
Example
curl -X POST "https://api.voizbot.com/v1/inbound-templates" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Restaurant Inbound",
"systemPrompt": "Greet caller, collect date/time/party size, then confirm.",
"voiceModel": "alnilam"
}'/inbound-templates/:idUpdates a template you own.
Request
Path: id. JSON body: any of name, systemPrompt, voiceModel (nullable), active.
Response
200 — { "ok": true, "template": { ... } }.
Example
curl -X PATCH "https://api.voizbot.com/v1/inbound-templates/tpl_abc" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Updated name" }'/inbound-templates/:idDeletes a template and clears it from any assigned numbers.
Request
Path: template id. No body.
Response
200 — minimal success (see conventions).
Example
curl -X DELETE "https://api.voizbot.com/v1/inbound-templates/tpl_abc" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/inbound-templates/:id/function-toolsLists function tools linked to a template.
Request
Path: template id.
Response
200 — { "ok": true, "tools": [ ...functionTool rows ] }.
Example
curl -X GET "https://api.voizbot.com/v1/inbound-templates/tpl_abc/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/inbound-templates/:id/function-toolsAssigns a function tool to a template.
Request
Path: template id. JSON body: { "functionToolId": "<id>" }.
Response
201 — new link: minimal success. 200 — already linked: { "ok": true, "message": "already_assigned" }. 404 if template or tool is missing / not yours (not_found / tool_not_found).
Example
curl -X POST "https://api.voizbot.com/v1/inbound-templates/tpl_abc/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "functionToolId": "tool_xyz" }'/inbound-templates/:id/function-toolsRemoves a function tool from a template.
Request
Path: template id. JSON body: { "functionToolId": "<id>" } (same shape as POST).
Response
200 — minimal success.
Example
curl -X DELETE "https://api.voizbot.com/v1/inbound-templates/tpl_abc/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "functionToolId": "tool_xyz" }'Function Tools
/function-toolsLists your function tools and organization-level webhook defaults used when a tool omits its own URL or timeout.
Request
No query parameters.
Response
200 — { "ok": true, "tools": [...], "defaults": { "functionWebhookUrl", "functionWebhookTimeoutMs", "functionWebhookHeaders" } }.
Example
curl -X GET "https://api.voizbot.com/v1/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/function-toolsCreates a tool. name must match ^[a-z][a-z0-9_]*$ (snake_case, letter first).
Request
JSON: required name, description. Optional: parametersJsonSchema, webhookUrl (URL or empty string), webhookHeaders, webhookTimeoutMs (500–15000 ms).
Response
201 — { "ok": true, "tool": { ... } }. 409 — duplicate_name.
Example
curl -X POST "https://api.voizbot.com/v1/function-tools" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "check_availability",
"description": "Check available booking slots.",
"parametersJsonSchema": {
"type": "object",
"properties": {
"date": { "type": "string" },
"partySize": { "type": "integer" }
},
"required": ["date", "partySize"]
},
"webhookUrl": "https://api.example.com/tools/check-availability",
"webhookTimeoutMs": 5000
}'/function-tools/:idReturns one tool by ID.
Request
Path: tool id.
Response
200 — { "ok": true, "tool": { ... } }. 404 — not_found.
Example
curl -X GET "https://api.voizbot.com/v1/function-tools/tool_xyz" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/function-tools/:idUpdates any subset of fields.
Request
Path: id. JSON: optional name, description, parametersJsonSchema, webhookUrl, webhookHeaders, webhookTimeoutMs, enabled.
Response
200 — { "ok": true, "tool": { ... } }.
Example
curl -X PATCH "https://api.voizbot.com/v1/function-tools/tool_xyz" \
-H "Authorization: Bearer VOIZBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "enabled": false }'/function-tools/:idDeletes a tool.
Request
Path: tool id. No body.
Response
200 — minimal success.
Example
curl -X DELETE "https://api.voizbot.com/v1/function-tools/tool_xyz" \
-H "Authorization: Bearer VOIZBOT_TOKEN"Call Logs and Media
/callsLists calls visible to your organization.
Request
Query: filter = all | active | recent (default all); limit integer 1–200 (default 100).
Response
200 — { "ok": true, "calls": [ ... ] }. Each item includes id, direction, callSid, numbers, status, statusLabel, durations, timestamps, hasTranscript, transcriptCount, hasRecording, recordingStatus (not full transcript or URLs — use GET by id).
Example
curl -X GET "https://api.voizbot.com/v1/calls?filter=recent&limit=50" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/calls/:idFull call detail: transcript, recording view, metadata, events.
Request
Path: call id.
Response
200 — ok, id, direction, status, numbers, times, callSid, streamSid, transcript (array of entries), recording (artifacts / URLs), metadata, events, lastError. 404 — not_found.
Example
curl -X GET "https://api.voizbot.com/v1/calls/call_abc123" \
-H "Authorization: Bearer VOIZBOT_TOKEN"/calls/:id/transcriptTranscript-focused payload (smaller than full call detail).
Request
Path: call id.
Response
200 — ok, transcript, direction, status, statusLabel, recording, numbers, durationSeconds, createdAt, callSid.
Example
curl -X GET "https://api.voizbot.com/v1/calls/call_abc123/transcript" \
-H "Authorization: Bearer VOIZBOT_TOKEN"AI Agents
Voizbot publishes the phone-calls skill bundle publicly for Hermes, OpenClaw-style setups, and any agent that can run a Python CLI.
Full install and setup guide: https://voizbot.com/agents
The bundle is two public files: SKILL.md and voizbot_calls.py. Fetch both; your agent places them in its skill layout — there is no installer script.
curl -fsSL https://voizbot.com/skills/voizbot-phone-calls/SKILL.md -o SKILL.md
curl -fsSL https://voizbot.com/skills/voizbot-phone-calls/scripts/voizbot_calls.py -o voizbot_calls.py
chmod +x voizbot_calls.pyErrors
Failures return appropriate HTTP status codes and a JSON body with ok: false.
{
"ok": false,
"error": "invalid_payload",
"details": { "...": "zod-style field errors when applicable" }
}- 400 bad JSON, invalid query (
invalid_query), or body validation (invalid_payload) - 401
unauthorized - 404
not_found,phone_not_found,tool_not_found, etc. - 409
duplicate_name(function tool) - 422
no_twilio(outbound without Twilio config) - 500 server or Twilio errors (outbound may include
jobId)
