Skip to main content

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 StreamUrl in 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

ParameterTypeDescription
FromStringNumber to dial. E.164 (e.g. +919876543210)
CallerIdStringYour ExoPhone / virtual number (caller ID)
StreamUrlStringBot WebSocket URL (ws:// or wss://), max 600 chars
StreamTypeStringSet to bidirectional for two-way audio

Optional

ParameterTypeDescription
RecordBooleantrue to record the call. Default: false
RecordingChannelsStringsingle (merged) or dual. Default: single
TimeLimitIntegerMax call duration in seconds. Max: 14400
CustomFieldStringMetadata on the call record (max 128 chars)
StatusCallbackStringWebhook URL for call status updates
StatusCallbackEventsArrayanswered, terminal, and/or ringing (leg1). For multipart/form-data, send each value as StatusCallbackEvents[]=<event>
StreamNameStringOptional 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
}
}
StatusMeaning
queuedCall is being prepared
in-progressCall is active
completedCall ended normally
failedCall could not be placed
busyNumber was busy
no-answerNumber 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.

Try It