Skip to Content
DocsIntegrationsAPI & Webhooks

API & Webhooks

The API & Webhooks integration gives you programmatic access to BuildVoiceAI. Use the API to trigger outbound calls from your own applications, and configure webhooks to receive real-time call event data in Zapier, Make, n8n, or any custom endpoint.

Prerequisites

  • A BuildVoiceAI account on the Agency plan (or a client with API access enabled)
  • A server or application capable of making HTTP requests (for the API) and receiving them (for webhooks)

Setup

Generate an API Key

  1. Navigate to Settings → API & Webhooks (agency-level) or Client Detail → API Keys (client-level)
  2. Click Generate API Key
  3. Copy the API key and store it securely

Your API key is shown only once when generated. If you lose it, you will need to generate a new one, which invalidates the previous key.

Enable/Disable API Access

You can toggle API access on or off without deleting your API key:

  1. Go to Settings → API & Webhooks
  2. Use the Enable/Disable toggle

When disabled, all API requests will return a 403 Forbidden response.

Set a Webhook URL

To receive call event data, configure a webhook endpoint:

  1. On the API & Webhooks section, find Webhook URL
  2. Enter the HTTPS URL of your endpoint (e.g., from Zapier, Make, n8n, or your own server)
  3. Click Save

A webhook signing secret is automatically generated when you save your configuration. Use this secret to verify that incoming webhooks are authentically from BuildVoiceAI.

Client-level webhook URLs override the agency default. If a client has its own webhook URL configured, call events for that client’s agents are sent to the client URL instead of the agency URL.

Test Your Webhook

After saving your webhook URL, click Send Test Webhook to verify the connection:

  1. Click the Send Test Webhook button
  2. A sample call_ended payload is sent to your configured URL
  3. The test payload includes "test": true so your automation can distinguish test from live events
  4. Check the result — success or failure — displayed immediately

Default Agent

Select the default agent for API-triggered calls:

  1. Find Default Agent on the integration page
  2. Select an agent from the dropdown
  3. Click Save

This agent is used when an API call request does not specify an agent_id.

API Authentication

Include your API key in the Authorization header of every request:

Authorization: Bearer your_api_key_here

All API requests must be made over HTTPS.

Triggering Outbound Calls

To trigger an outbound call via the API, send a POST request:

curl -X POST https://app.buildvoiceai.com/api/trigger-call \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "phone": "+15551234567", "name": "Jane Smith", "email": "jane@example.com", "agent_id": "optional-agent-uuid" }'

Request Fields

FieldTypeRequiredDescription
phonestringYesPhone number in E.164 format
namestringNoCaller name, passed to the agent’s prompt context
emailstringNoCaller email
agent_idstringNoUUID of the agent to use. Falls back to the default agent if omitted.
metadataobjectNoArbitrary key-value pairs passed through to webhooks

Response

A successful request returns:

{ "success": true, "call_id": "uuid-of-the-initiated-call" }

Webhook Events

When a webhook URL is configured, BuildVoiceAI sends POST requests to your endpoint when call events occur.

Supported Events

EventWhen It FiresProviders
call_startedA call begins ringing/connectingRetell, Vapi
call_endedA call finishes (completed, failed, or no-answer)Retell, Vapi, Bland, ElevenLabs
testManual test from the Send Test Webhook buttonAll

Bland AI and ElevenLabs only fire webhooks on call completion — there is no call_started event for Bland or ElevenLabs.

call_ended Payload

{ "event": "call_ended", "call_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210", "agent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "agent_name": "Sales Qualifier", "status": "completed", "direction": "outbound", "duration_seconds": 185, "cost_cents": 28, "from_number": "+15551234567", "to_number": "+15559876543", "transcript": "Agent: Hello, how can I help you today?\nUser: I was wondering about your pricing.", "recording_url": "https://storage.example.com/recordings/abc123.mp3", "summary": "Caller expressed interest in the enterprise plan and requested a follow-up demo.", "sentiment": "positive", "started_at": "2026-03-16T14:30:00.000Z", "ended_at": "2026-03-16T14:33:05.000Z", "metadata": {}, "provider": "retell" }

call_started Payload

{ "event": "call_started", "call_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210", "agent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "agent_name": "Sales Qualifier", "status": "in-progress", "direction": "inbound", "from_number": "+15551234567", "to_number": "+15559876543", "started_at": "2026-03-16T14:30:00.000Z", "metadata": {}, "provider": "vapi" }

Payload Fields

FieldTypePresent InDescription
eventstringBothcall_started, call_ended, or test
call_idstringBothUnique call identifier
agent_idstringBothProsody agent UUID
agent_namestringBothHuman-readable agent name
statusstringBothin-progress, completed, failed, no-answer
directionstringBothinbound or outbound
from_numberstringBothCaller phone number (E.164)
to_numberstringBothRecipient phone number (E.164)
started_atstringBothISO 8601 timestamp
duration_secondsnumbercall_endedCall length in seconds
cost_centsnumbercall_endedCall cost in cents
transcriptstringcall_endedFull conversation transcript
recording_urlstring|nullcall_endedLink to call recording
summarystringcall_endedAI-generated call summary
sentimentstringcall_endedpositive, neutral, or negative
ended_atstringcall_endedISO 8601 timestamp
metadataobjectBothCustom metadata attached to the call
providerstringBothretell, vapi, bland, elevenlabs, or test
testbooleanTest onlytrue on test webhooks

Webhook Signing

Every webhook request is signed with HMAC-SHA256 when a signing secret is configured. Two headers are included:

HeaderDescription
X-Prosody-SignatureHMAC-SHA256 hex digest of the payload
X-Prosody-TimestampUnix timestamp (seconds) when the signature was generated

The signature is computed as:

HMAC-SHA256(signing_secret, "${timestamp}.${body}")

Verification Example (Node.js)

const crypto = require('crypto'); function verifyWebhook(rawBody, signature, timestamp, signingSecret) { // Reject old payloads to prevent replay attacks const age = Math.floor(Date.now() / 1000) - parseInt(timestamp); if (age > 300) throw new Error('Webhook too old'); const expected = crypto .createHmac('sha256', signingSecret) .update(`${timestamp}.${rawBody}`) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); }
⚠️

Always use a timing-safe comparison function to prevent timing attacks. Do not use === for signature comparison.

The signing secret is separate from your API key. You can find it in Settings → API & Webhooks — click the eye icon to reveal it.

Retry Policy

If your webhook endpoint returns a non-2xx status code or does not respond within 10 seconds, BuildVoiceAI retries the request with exponential backoff:

AttemptDelay
1st attemptImmediate
2nd attempt (1st retry)1 second after failure
3rd attempt (2nd retry)2 seconds after failure

Only server errors (5xx) and rate limits (429) are retried. Client errors (4xx except 429) fail immediately since retrying will not help.

After 3 failed attempts, the delivery is marked as failed. All delivery attempts are logged in the Delivery Log.

Delivery Log

View recent webhook delivery attempts in Settings → API & Webhooks → Recent Deliveries. Each entry shows:

  • Event type (call_started, call_ended, test)
  • Timestamp
  • HTTP status code returned by your endpoint
  • Success or failure status
  • Error message (if applicable)
  • Attempt number

Use the delivery log to debug failed webhooks, verify test payloads were received, and monitor overall delivery health.

Troubleshooting

API Returns 403

  • Verify API access is enabled on the integration page
  • Check that the API key in your Authorization header is correct
  • Ensure you are using Bearer token format

Webhook Not Receiving Events

  • Confirm your webhook URL is publicly accessible (not behind a firewall or VPN)
  • Verify the URL returns a 200 status code within 10 seconds
  • Use the Send Test Webhook button to verify connectivity
  • Check the Delivery Log for error details
  • Ensure HTTPS is used (HTTP endpoints are rejected)

Signature Verification Failing

  • Use the signing secret (not the API key) for HMAC verification
  • Use the raw request body (not parsed JSON) when computing the signature
  • Include the timestamp: the signature covers "${timestamp}.${body}"
  • Reject payloads older than 5 minutes to prevent replay attacks

Calls Not Being Placed

  • Verify the phone field is in E.164 format (e.g., +15551234567)
  • Check that the default agent is set (or a valid agent_id is provided)
  • Ensure the agent has a phone number assigned
  • Confirm the calling window allows calls at the current time
Last updated on