> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bananaflow.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Exotel Integration

> Configure Exotel for voice communication in Bananaflow AI

# Exotel Integration

Exotel places and receives calls with bidirectional AgentStream media streaming into Bananaflow agents.

## Prerequisites

* An [Exotel](https://my.exotel.com/) account with AgentStream / Connect Voice AI enabled
* **KYC verification completed** – mandatory for all Indian accounts post-signup before ExoPhones can carry live voice traffic. Follow [KYC Verification – Indian Accounts](https://docs.exotel.com/business-phone-system/kyc-verification-indian-accounts) (typically \< 30 minutes online).
* Account SID, API Key, and API Token (Dashboard -> Settings -> API Settings)
* At least one ExoPhone assigned to your account (see provisioning below – don't assume one already exists)

## Supported Exotel front-doors

Per [AgentStream: what to use when](https://docs.exotel.com/exotel-agentstream/agentstream-what-to-use-when), Exotel exposes five entry points to AgentStream (Connect Voice AI, Connect + Flow, ExoML outbound, Flow-Based inbound, ExoML inbound). Bananaflow's Exotel provider supports **exactly two** of these today:

* **Outbound: Connect Voice AI API** – `POST /v1/Accounts/{sid}/Calls/connect.json` with `StreamUrl` in the API body. No App Bazaar flow involved.
* **Inbound: Flow-Based via Voicebot Applet** – ExoPhone → App Bazaar flow → Voicebot Applet with an HTTPS dynamic-URL pointing at Bananaflow.

Together these cover the "answer → bot" use case without requiring a gRPC control plane.

### Not currently supported

* **Connect Voice AI with Flow API** (outbound + App Bazaar journey). Bananaflow cannot dial into an App Bazaar flow, and call transfers are not supported on Exotel. If you need IVR, greeting, DTMF or agent-handoff journeys, start Connect + Flow calls directly against Exotel's API from outside Bananaflow; the flow's Voicebot Applet can still hand the call to Bananaflow's inbound endpoint.
* **ExoML / Programmable Voice APIs** (gRPC leg events + leg actions), for both outbound and inbound.

## ExoPhone provisioning and activation

Provision ExoPhones before configuring Bananaflow. All calls use HTTP Basic Auth with your API Key / API Token.

1. **List available numbers**
   * `GET /v2_beta/Accounts/{account_sid}/AvailablePhoneNumbers/{country}/{type}`
   * `{type}` is one of `Landline`, `Mobile`, or `TollFree`.
   * Optional filters: `IncomingSMS`, `InRegion`, `Contains`.
   * Response fields include `phone_number`, `capabilities`, `country`, `region`, `rental_price`.
   * Docs: [Available numbers](https://developer.exotel.com/docs/exophones/api-reference/available-numbers)
2. **Purchase a number**
   * `POST /v2_beta/Accounts/{account_sid}/IncomingPhoneNumbers`
   * Request body: `PhoneNumber` (required); `VoiceUrl`, `SMSUrl`, `FriendlyName` (all optional).
   * Response fields include `sid`, `phone_number`, `friendly_name`, `capabilities`, `country`, `rental_price`, `currency`.
   * Docs: [Purchase number](https://developer.exotel.com/docs/exophones/api-reference/purchase-number)
3. **Verify a purchased number**
   * `GET /v2_beta/Accounts/{account_sid}/IncomingPhoneNumbers/{exophone_sid}`
   * Returns `sid`, `phone_number`, `friendly_name`, `capabilities`, `country`, `region`, `voice_url`, `sms_url`.
   * Docs: [Number details](https://developer.exotel.com/docs/exophones/api-reference/number-details)
4. **Assign the number to a Flow**
   * In the Exotel dashboard, attach the ExoPhone's Voice URL to an App Bazaar flow (see [Inbound](#inbound) below for the Voicebot Applet wiring).
   * **Required before the number can carry inbound traffic.**

> **KYC (mandatory for Indian accounts):** Complete KYC in the Exotel dashboard before expecting purchased numbers to become fully active for voice traffic. A purchased ExoPhone can appear in the API but silently fail on real calls until KYC clears. See [KYC Verification – Indian Accounts](https://docs.exotel.com/business-phone-system/kyc-verification-indian-accounts) for the three-step flow (PAN confirmation → business details → authorised signatory) and the "help me verify" escape hatch if automated checks fail.

## Bananaflow telephony configuration

1. Navigate to **/telephony-configurations** and click **Add configuration**
2. Select **Exotel**
3. Enter:
   * **Account SID**
   * **API Key** / **API Token** (HTTP Basic auth for Exotel APIs)
   * **API Base URL** – default `https://api.in.exotel.com` (India); use `https://api.exotel.com` for other regions
4. Save, then add your ExoPhone under **Phone numbers** in [E.164](https://en.wikipedia.org/wiki/E.164) format (e.g. `+9180XXXXXXXX`)
5. Set an **Inbound workflow** on that phone number in Bananaflow.

### Programmatic configuration

When creating an Exotel configuration through the API rather than the UI, the provider config accepts:

| Field | Purpose |
| - | - |
| `account_sid` | Exotel Account SID |
| `api_key` | Exotel API Key (HTTP Basic username) |
| `api_token` | Exotel API Token (HTTP Basic password) |
| `api_base_url` | `https://api.in.exotel.com` (default) or `https://api.exotel.com`; any other origin is rejected |
| `from_numbers` | List of ExoPhones (E.164) available as `CallerId` |
| `default_from_number` | Default `CallerId` when a workflow does not specify one |

## Outbound

Bananaflow dials using Exotel Connect Voice AI (the "simplest outbound" pattern – bot is the whole experience, no App Bazaar flow):

`POST {api_base}/v1/Accounts/{AccountSid}/Calls/connect.json`

Request fields:

* `From` – the recipient (callee)
* `CallerId` – the ExoPhone
* `StreamUrl` – Bananaflow's WSS endpoint for this call
* `StreamType=bidirectional`
* `StatusCallback` and `StatusCallbackEvents[]=terminal` – **only attached when a `workflow_run_id` is present**

For Indian ExoPhones, Bananaflow maps the stored E.164 `CallerId` to Exotel's 0-prefixed national form (Exotel's [Connect Voice AI example](https://docs.exotel.com/exotel-agentstream/connect-voice-ai-api) uses `CallerId=0XXXXXXXXXX`). Example: `+917314852338` → `07314852338`. The destination `From` stays in E.164 per the same example (`From=+91XXXXXXXXXX`). Non-India numbers pass through unchanged.

Test from a workflow **Call** button. Confirm two-way audio and that hangup marks the run completed.

Outbound calls that run through an Exotel dashboard flow are not supported; see [Supported Exotel front-doors](#supported-exotel-front-doors).

## Inbound

Bananaflow implements **Flow-Based Inbound via the Voicebot Applet's dynamic-URL contract**. Exotel's [Stream and Voicebot Applet reference](https://developer.exotel.com/docs/agentstream/stream-voicebot-applet) explicitly documents the applet's URL parameter as "a WebSocket URL … **or an HTTPS endpoint that dynamically returns the WSS URL**" – that is the contract Bananaflow implements.

### Wiring

1. In Exotel, open or create an **App Bazaar flow**.
2. Drop a **Voicebot Applet** into the flow.
3. Configure the applet:
   * **URL** = `https://app.bananaflow.ai/api/v1/telephony/inbound/run`
   * **Authentication** = HTTP Basic; username = your Exotel API Key, password = your Exotel API Token. Bananaflow checks these against the credentials in your Exotel configuration.
   * **Sample Rate** = `8000`. Bananaflow's Exotel audio runs at 8 kHz; do not append `?sample-rate=…`, or the applet will negotiate a rate Bananaflow does not decode and audio breaks.
4. Assign the ExoPhone's Voice URL to this flow in Exotel.
5. In Bananaflow, assign the matching **inbound workflow** to the number.

### Response contract

On invocation, Bananaflow validates auth and route mapping, creates a workflow run, and returns JSON:

```json theme={null}
{ "url": "wss://app.bananaflow.ai/api/v1/telephony/ws/..." }
```

Exotel's Voicebot Applet then opens the bidirectional WebSocket to that URL.

### Voicebot Applet operational limits

Drawn from Exotel's [applet documentation](https://developer.exotel.com/docs/agentstream/stream-voicebot-applet):

* **Audio format**: raw/slin – 16-bit PCM little-endian, mono, base64-encoded.
* **Sample rate**: `8000` (PSTN). Exotel's applet also supports `16000` and `24000` via `?sample-rate=…`, but Bananaflow's Exotel audio runs at 8 kHz, so leave the sample rate at the default.
* **Chunk size**: min 3.2 KB (100 ms of audio), max 100 KB, must be a multiple of 320 bytes. Smaller chunks risk audio distortion; larger cause timeouts.
* **Custom parameters**: up to 3 key-value pairs appended to the URL (`?param1=value1&param2=value2`, 256 chars total).

## Status callbacks

Outbound registers a per-run status callback URL:

`/api/v1/telephony/exotel/status-callback/{workflow_run_id}?exotel_auth=...`

The `exotel_auth` token is an HMAC signature derived from your API token, so Exotel's POST does not need an `Authorization` header. Bananaflow also rejects callbacks whose `CallSid` does not match the call it placed for that run.

Terminal events update the workflow run status.

> **Inbound calls:** Bananaflow does not register a status callback for inbound calls, so Exotel's terminal call events are sent to Bananaflow for outbound calls only.

## Phone ownership validation

When you add an ExoPhone in Bananaflow, Bananaflow lists the numbers on your Exotel account (through [`GET /v2_beta/Accounts/{account_sid}/IncomingPhoneNumbers`](https://developer.exotel.com/docs/exophones/api-reference/list-numbers)) and checks that your number is one of them. It matches E.164 and India's `0`-prefixed national form, with or without a leading `+`.

If the number is not on the account, Bananaflow rejects it with a message that the number is not owned by this Exotel account. Add the number in the Exotel dashboard first.

## Troubleshooting

* **Connect fails** – verify Account SID, API key/token, base URL region (`api.in.exotel.com` or `api.exotel.com` only), and AgentStream entitlement.
* **No inbound agent** – confirm the ExoPhone has an inbound workflow in Bananaflow and the Exotel Voicebot Applet points to `/api/v1/telephony/inbound/run`.
* **Auth failed on inbound** – ensure the Voicebot Applet is configured with HTTP Basic (username = API Key, password = API Token) matching the credentials stored in Bananaflow.
* **Number rejected when you add it** – the ExoPhone is not on the Exotel account, the wrong `api_base_url` region is selected, or the number was purchased but has not cleared [KYC](https://docs.exotel.com/business-phone-system/kyc-verification-indian-accounts) yet.
* **One-way audio** – check that the sample rate on the Voicebot Applet matches what your bot pipeline expects.
* **Choppy or dropped audio** – the outgoing chunk size may be out of range; keep chunks ≥ 3.2 KB and ≤ 100 KB, in multiples of 320 bytes. See Exotel's [WSS errors and handling](https://docs.exotel.com/exotel-agentstream/agentstream-wss-errors-and-handling).
* **Status callback 401** – the `exotel_auth` token is tied to the Account SID and API Token saved in Bananaflow when the call was placed. If you changed either one while the call was in progress, callbacks for that call are rejected; new calls are unaffected.

## References

* [KYC Verification – Indian Accounts](https://docs.exotel.com/business-phone-system/kyc-verification-indian-accounts) (mandatory post-signup step for Indian accounts)
* [ExoPhone – Available numbers](https://developer.exotel.com/docs/exophones/api-reference/available-numbers)
* [ExoPhone – Purchase number](https://developer.exotel.com/docs/exophones/api-reference/purchase-number)
* [ExoPhone – Number details](https://developer.exotel.com/docs/exophones/api-reference/number-details)
* [AgentStream – What to use when](https://docs.exotel.com/exotel-agentstream/agentstream-what-to-use-when) (context for why Bananaflow uses these two front-doors and not ExoML)
* [AgentStream – Overview & Quickstart](https://docs.exotel.com/exotel-agentstream/overview-and-quickstart)
* [AgentStream – WSS errors and handling](https://docs.exotel.com/exotel-agentstream/agentstream-wss-errors-and-handling)
* [Working with the Stream and Voicebot Applet](https://developer.exotel.com/docs/agentstream/stream-voicebot-applet)
* [Connect Voice AI API](https://docs.exotel.com/exotel-agentstream/connect-voice-ai-api)
* [Exotel Agent-Stream reference implementation](https://github.com/exotel/Agent-Stream)
* [Exotel Agent-Stream echobot](https://github.com/exotel/Agent-Stream-echobot)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.