---
title: Programmable Voice APIs with AgentStream
slug: exotel-agentstream/programmable-voice-apis-with-agentstream
docTags: 
createdAt: 2025-09-27T08:14:26.402Z
---

When you build bot-driven voice experiences, reducing perceived latency is critical. With Exotel ExoML, 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 [ExoML — Introduction](docId\:Ju_t9ACidAdHKkOAfYdWp)

## 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)

### Base URL

All ExoML Aare served from the Exotel CPaaS API host.

**Base URL format**

:::BlockQuote
https\://cpaas-api.in.exotel.com/v2/accounts/\{account\_sid}
:::

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

:::CodeblockTabs
Body

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

:::CodeblockTabs
Body

```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**

:::CodeblockTabs
POST

```curl
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**

:::CodeblockTabs
POST

```curl
POST /v2/accounts/{account_sid}/legs/{leg_sid}/actions/start_say
{
"text": "Hello",
"loop": 0
}
```
:::

- **Play**

:::CodeblockTabs
POST

```curl
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.

:::Heading{depth="2" indent="1"}
**Next Steps**
:::

- Get ExoML enabled for your account
- Explore StopSay/StopPlay timing to fine-tune transitions.

