@voice-ai-labs/web-sdk) provides a unified JavaScript/TypeScript interface for building voice-enabled web applications.
Installation
Source code: The SDK is open source on GitHub. View examples, report issues, or contribute.
Quick Start
Features
| Area | Description |
|---|---|
| Real-time Voice | Connect to voice agents with live transcription |
| Text-to-Speech | Generate speech and manage voices |
| Agent Management | Create, update, deploy, and manage agents |
| Knowledge Base | Manage RAG documents for your agents |
| Phone Numbers | Search and manage phone numbers |
| Analytics | Access call history, transcripts, and recordings |
| Webhooks | Receive event notifications, inbound personalization requests, and callable tool invocations |
| Security | Backend token exchange, endToken, CORS handling |
| Error Handling | Connection and API error handling |
Real-time Voice
Connect to an Agent
connect() supports these top-level request shapes:
agentIdfor a saved agentdynamicVariablesfor optional runtime variables passed at call startagentOverridesfor optional call-scoped runtime config overridestestModeto preview paused agents before deploying
Events
Each handler returns a function to unsubscribe:
const stop = voiceai.onTranscription(...); stop();Microphone Control
Send Text Message
Disconnect
Text-to-Speech
The TTS API provides speech generation and voice management.Generate Speech
Voice Management
Pronunciation Dictionaries
Agent Management
Outbound access control: POST /api/v1/calls/outbound is restricted to approved accounts.
If you need outbound enabled for your account/workspace, please contact Voice.ai support.
Update behavior:voiceai.agents.update()is a partial update. Omit a field to leave it unchanged. For nullable scalar fields likeprompt,greeting,phone_number, or nestedtts_paramsfields, passnullto clear the current value. See section-specific notes below for webhook clearing behavior.
Recording:config.recording_enableddefaults totruefor new agents. Set it tofalseto disable recording for future calls.
Dynamic Variables
Pass optionaldynamic_variables at call start and reference them in your prompt or greeting with {{variable_name}}:
dynamic_variablesmust be a flat object of string, number, or boolean values.- Extra variables are allowed.
- Variables that are not referenced by the runtime prompt or greeting are ignored.
- The runtime is responsible for interpolating these variables into the prompt and greeting.
- If the same placeholder appears multiple times, the same runtime value is used for every occurrence.
Runtime Agent Overrides
Pass optionalagentOverrides at call start when you need a call-scoped config patch rather than prompt interpolation:
agentOverridesis separate fromdynamicVariables.dynamicVariablesis for prompt and greeting interpolation.agentOverridesis for allowlisted runtime config changes.- v1 supports only
tts_params.voice_id,temperature,top_p,dictionary_id, anddictionary_version. - TTS
modelandlanguageare agent configuration fields, not per-call runtime override fields. agentOverridesuses the same nested shape as agent config, so voice overrides live undertts_params.
Knowledge Base
Phone Numbers
Analytics
Webhooks
Configure webhooks when creating or updating an agent. For backend payload details and signing guidance, see the dedicated Webhooks guide.webhooks.events[], webhooks.inbound_call, and webhooks.tools use different contracts:
webhooks.events[]supportssecret(write-only on create/update) andhas_secret(read-only on fetch), with fan-out across enabled endpoints.webhooks.inbound_callsupportssecret(write-only on create/update) andhas_secret(read-only on fetch).webhooks.toolsdefine outbound API calls and do not usesecret.
Configure Webhook Events and Tools
Webhook configuration requiredness
webhooks.events[]- Required:
url - Optional:
secret,events,timeout(default5),enabled(defaulttrue) - On update: omit
webhooks.eventsto preserve the current list, setwebhooks.events: nullto clear it, or pass a full array to replace it - Within a replacement array: omitted
secretvalues are preserved only for entries whoseurlexactly matches an existing endpoint,secret: nullclears that endpoint’s signing secret, duplicate URLs are invalid, andevents: []means that endpoint receives all event types
- Required:
webhooks.inbound_call- Required:
url - Optional:
secret,timeout(default5),enabled(defaulttrue) - On update: omit
inbound_callto preserve it, setinbound_call: nullto remove it, and setsecret: nullto clear only the signing secret
- Required:
webhooks.tools- Required per tool:
name,description,parameters,url,method,execution_mode,auth_type - Optional per tool:
auth_token,headers,response,timeout(default10) - On update: omit
toolsto leave the current tool list unchanged, settools: nullto clear all tools, or pass a new array to replace the current list
- Required per tool:
null unless you explicitly intend to clear behavior in a supported way.
Event Types
| Event | Description |
|---|---|
call.started | Call connected, agent ready |
call.completed | Call ended, includes transcript and usage data |
call.failed | Call initiation was blocked before call.started |
Event Webhook Payload
Your event webhook URL receives POST requests with this structure:Webhook Tool Request Shape
For webhook tools, Voice.ai makes outbound HTTP requests directly to each toolurl.
method: 'GET': tool arguments are sent as query parameters.method: 'POST' | 'PUT' | 'PATCH' | 'DELETE': tool arguments are sent as JSON body.- Metadata headers are always sent:
X-VoiceAI-Request-IdX-VoiceAI-Tool-NameX-VoiceAI-Agent-IdX-VoiceAI-Call-Id
Webhook Tool Authentication
auth_type: 'none': no auth headers added.auth_type: 'bearer_token': sendsAuthorization: Bearer <auth_token>.auth_type: 'api_key': sendsX-API-Key: <auth_token>.auth_type: 'custom_headers': sends your configuredheadersmap.
Webhook Tool Response Behavior
execution_mode: 'sync': waits for downstream response body; non-2xx fails the tool call.execution_mode: 'async': treats any 2xx as accepted and does not require a response payload.
Signature Verification (Event Webhooks)
If you configurewebhooks.events[].secret, verify the HMAC-SHA256 signature:
Inbound Call Webhook Payload
If you configurewebhooks.inbound_call, Voice.ai sends inbound call personalization requests with this shape:
webhooks.inbound_call.secret, verify the HMAC-SHA256 signature using the same
X-Webhook-Timestamp and X-Webhook-Signature headers shown above for event webhooks.
Use inbound_call for personalization only. It is not a routing hook. It may run before call validation, so call initiation can still fail afterward. Subscribe to call.failed event webhooks to notify your backend when a phone call is blocked before call.started. See the Webhooks guide for request examples and HMAC verification details.
Security
connect() fetches connection details and connects in one call. To keep your API key off the browser, split into two steps:
endToken from your backend to the frontend. The SDK uses it on disconnect() to free the concurrency slot immediately.
REST methods (agents.*, tts.*, analytics.*, etc.) require an API key and are CORS-blocked from browsers.
Error Handling
Connection errors
Theconnect() method throws an Error if connection fails. Common error cases:
CALL_VALIDATION_FAILED and include a structured reason such as insufficient_credits, subscription_inactive, or max_concurrent_calls_exceeded. For phone calls, subscribe to call.failed event webhooks because the caller does not receive a spoken failure reason.
Errors are also emitted via onError and reflected in onStatusChange:
REST API errors (agents, TTS, analytics, etc.)
REST methods throwVoiceAIError:
TypeScript
Full TypeScript support. Exported types:Browser Support
Chrome, Firefox, Safari (latest versions). Requires microphone permission for voice features.Package Links
- GitHub repository — Source code, issues, and contributions
- npm package
- License: MIT