Skip to main content

Exotel Integration

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

Prerequisites

  • An Exotel 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 (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, 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
  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
  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
  4. Assign the number to a Flow
    • In the Exotel dashboard, attach the ExoPhone’s Voice URL to an App Bazaar flow (see 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 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 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:

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

Inbound

Bananaflow implements Flow-Based Inbound via the Voicebot Applet’s dynamic-URL contract. Exotel’s Stream and Voicebot Applet reference 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:
Exotel’s Voicebot Applet then opens the bidirectional WebSocket to that URL.

Voicebot Applet operational limits

Drawn from Exotel’s applet documentation:
  • 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) 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 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.
  • 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