When you build bot-driven voice experiences, reducing perceived latency is critical. With Exotel Legs APIs, you can control call legs and media actions in real time. This guide explains two recommended approaches:
Approach 1: Create a customer leg and immediately start a stream.
Approach 2: Create a leg, start a stream, and optionally play a short greeting (say/play) in parallel while the bot connects.
Both flows are supported with existing Exotel Legs APIs.
Prerequisites
An Exotel account and valid account_sid, key and Token
An exophone configured for outbound calls
A gRPC endpoint to receive leg events.
A WebSocket bot server that supports Exotel streaming and events
Approach 1: Create Leg + Start Stream (Bot-First)
This is the simplest flow: connect the customer leg, then hand it directly to your bot.
Step 1. Create the leg
POST /v2/accounts/{account_sid}/legs
Content-Type: application/json
{
"contact_uri": "074xxxxx773",
"exophone": "0204xxxxx38",
"leg_event_endpoint": "grpc://<your-example-endpoint>",
"timeout": 30
}
You will receive events such as leg_connecting, leg_ringing, and finally leg_answered.
Step 2. Start the stream
On leg_answered, start the stream:
POST /v2/accounts/{account_sid}/legs/{leg_sid}/actions/start_stream
Content-Type: application/json
{
"direction": "bidirectional",
"url": "wss://bot.example.com/stream",
"content_type": "audio/x-mulaw;rate=8000"
}
At this point, audio flows between the customer and your bot.
Approach 2: Create Leg + Start Stream + Say/Play (Parallel)
In many customer-facing scenarios, even a 1–2s delay feels like silence. To improve perception, you can play a short greeting while the stream session is warming up.
Step 1. Create the leg
Same as Approach 1.
Step 2. Start actions in parallel
On leg_answered, issue two actions:
Start stream
POST /v2/accounts/{account_sid}/legs/{leg_sid}/actions/start_stream
{
"direction": "bidirectional",
"url": "wss://bot.example.com/stream",
"content_type": "audio/x-mulaw;rate=8000"
}
Start greeting (choose one):
Say
POST /v2/accounts/{account_sid}/legs/{leg_sid}/actions/start_say
{
"text": "Hello",
"loop": 0
}
Play
POST /v2/accounts/{account_sid}/legs/{leg_sid}/actions/start_play
{
"url": "https://example.com/contact-center-tone.wav",
"loop": 0
}
Step 3. Stop greeting when the stream is ready
As soon as you receive the stream_started event, stop the placeholder:
POST /v2/accounts/{account_sid}/legs/{leg_sid}/actions/stop_say
or
POST /v2/accounts/{account_sid}/legs/{leg_sid}/actions/stop_play
This ensures the bot audio seamlessly takes over without overlap.
When to Use Each Approach
Key Notes
Parallelism: Exotel supports issuing start_stream and start_say/start_play together on the same event.
Greeting length: Keep placeholder audio short (200–500 ms) so the bot can take over naturally.
Stop timing: Always stop say/play when you receive stream_started.
Next Steps
Get Legs APIs enabled for your account
Explore StopSay/StopPlay timing to fine-tune transitions.