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_connectingleg_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

Scenario

Recommended Flow

Bot-first, IVR-style journeys

Approach 1

Sales / Collections (instant feel)

Approach 2

Contact center simulation

Approach 2

Tech support bot only

Approach 1


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.