Connect Voice AI API
Dial a phone number and connect the answered call to your conversational AI bot over a bidirectional WebSocket. No App Bazaar flow required.
Typical use cases: outbound campaigns, virtual agents, surveys, and appointment reminders.
When to use
- Bot is the whole experience (campaigns, surveys, reminders)
- Fixed
StreamUrlin the request is fine - No IVR, compliance applet, or agent transfer in Exotel
For multi-step journeys, use Connect with Flow. For per-call dynamic control, use Programmable Voice.
Authentication
HTTP Basic Auth — API Key as username, API Token as password (Dashboard → API credentials).
Base URL: https://api.in.exotel.com (India) · https://api.exotel.com (Singapore)
Request parameters
Required
| Parameter | Type | Description |
|---|---|---|
From | String | Number to dial. E.164 (e.g. +919876543210) |
CallerId | String | Your ExoPhone / virtual number (caller ID) |
StreamUrl | String | Bot WebSocket URL (ws:// or wss://), max 600 chars |
StreamType | String | Set to bidirectional for two-way audio |
Optional
| Parameter | Type | Description |
|---|---|---|
Record | Boolean | true to record the call. Default: false |
RecordingChannels | String | single (merged) or dual. Default: single |
TimeLimit | Integer | Max call duration in seconds. Max: 14400 |
CustomField | String | Metadata on the call record (max 128 chars) |
StatusCallback | String | Webhook URL for call status updates |
StatusCallbackEvents | Array | answered, terminal, and/or ringing (leg1). For multipart/form-data, send each value as StatusCallbackEvents[]=<event> |
StreamName | String | Optional stream label, max 32 chars |
Example request
curl -u '<api_key>:<api_token>' -X POST \
'https://api.in.exotel.com/v1/Accounts/<AccountSid>/Calls/connect' \
-F 'From=+919876543210' \
-F 'CallerId=0XXXXXXXXXX' \
-F 'StreamUrl=wss://your-bot.example.com/media' \
-F 'StreamType=bidirectional' \
-F 'Record=true' \
-F 'StatusCallback=https://your-server.com/callback' \
-F 'StatusCallbackEvents[]=terminal'
Response
{
"Call": {
"Sid": "a1b2c3d4e5f6...",
"Status": "in-progress",
"From": "+919876543210",
"PhoneNumberSid": "0XXXXXXXXXX",
"Direction": "outbound-api",
"DateCreated": "2025-06-01 10:00:00",
"RecordingUrl": null
}
}
| Status | Meaning |
|---|---|
queued | Call is being prepared |
in-progress | Call is active |
completed | Call ended normally |
failed | Call could not be placed |
busy | Number was busy |
no-answer | Number did not answer |
After connect
On answer, Exotel opens WSS to StreamUrl. Implement the WebSocket protocol on your bot. Append ?sample-rate=16000 (or 8000 / 24000) to the URL when needed.