Skip to main content

Programmable Voice APIs with AgentStream

Full runtime control via Legs API — per-call stream URLs, dynamic routing, and greeting + stream in parallel.

Works for outbound (POST /legs) and inbound (Exophone attached to a gRPC endpoint). See What to use when.

Authentication

HTTP Basic Auth — API Key as username, API Token as password.
Content-Type: application/json

Base URL: https://cpaas-api.in.exotel.com/v2/accounts/{account_sid}
(Singapore: cpaas-api.exotel.com)


Create leg (dial)

Request parameters

ParameterRequiredTypeDescription
contact_uriYesStringNumber to dial (E.164)
exophoneYesStringYour ExoPhone
leg_event_endpointYesStringgRPC endpoint for leg events
timeoutNoIntegerRing timeout in seconds

Example request

curl -u '<api_key>:<api_token>' -X POST \
'https://cpaas-api.in.exotel.com/v2/accounts/<account_sid>/legs' \
-H 'Content-Type: application/json' \
-d '{
"contact_uri": "+919876543210",
"exophone": "08047491899",
"leg_event_endpoint": "grpc://your-event-server.example.com",
"timeout": 30
}'

Try It

Exotel emits: leg_connectingleg_ringingleg_answered


Start stream

Call on leg_answered.

Request parameters

ParameterRequiredTypeDescription
directionYesStringbidirectional for Voice AI
urlYesStringBot WebSocket URL (wss://)
content_typeNoStringe.g. audio/x-mulaw;rate=8000

Example request

curl -u '<api_key>:<api_token>' -X POST \
'https://cpaas-api.in.exotel.com/v2/accounts/<account_sid>/legs/<leg_sid>/actions/start_stream' \
-H 'Content-Type: application/json' \
-d '{
"direction": "bidirectional",
"url": "wss://bot.example.com/stream",
"content_type": "audio/x-mulaw;rate=8000"
}'

Try It


Optional — greeting while stream initialises

Fire with start_stream on leg_answered to avoid dead air.

Start say

curl -u '<api_key>:<api_token>' -X POST \
'https://cpaas-api.in.exotel.com/v2/accounts/<account_sid>/legs/<leg_sid>/actions/start_say' \
-H 'Content-Type: application/json' \
-d '{ "text": "Please hold.", "loop": 0 }'

Try It

Stop say

Call on stream_started:

curl -u '<api_key>:<api_token>' -X POST \
'https://cpaas-api.in.exotel.com/v2/accounts/<account_sid>/legs/<leg_sid>/actions/stop_say'

Try It

ScenarioUse greeting?
Inbound IVR / tech supportUsually no
Outbound sales / collectionsYes

Inbound ExoML

  1. Implement a gRPC leg-event endpoint
  2. Attach the Exophone to that endpoint (not to an App Bazaar flow)
  3. On inbound leg_answered, issue start_stream (and optional say/play)

No Voicebot applet required — your service is the flow.