Integrations / Twilio
Twilio to an AI voice agent
Answer a Twilio number with an AI voice agent by pointing a Media Stream at a WebSocket. Setu handles the Twilio dialect and hands the voice engine plain PCM16, including the flush that makes barge-in work.
path /twilio · 8 kHz · written from the vendor's published reference
What Twilio sends and expects
- Wire format
- JSON text frames, base64 μ-law inside media.payload
- Sample rate
- 8 kHz
- Flush playback on interruption
{"event":"clear","streamSid":…}Carriers queue seconds of audio ahead of the caller. Without this frame, an interrupted caller keeps hearing a sentence the agent gave up on two seconds ago.
The trap
The <Stream url> attribute accepts no query string. Anything you append is dropped, so per-call configuration has to travel in <Parameter> children or in the streamSid lookup on your side — not in the URL.
Wiring it up
Return TwiML from your voice webhook that opens a bidirectional stream against the bridge.
1 · run the bridge
export DVAARIK_API_KEY=dvk_live_...
export AGENT_PROMPT="You are Riya, the receptionist at Sunrise Dental."
npx @dvaarik/setu2 · point Twilio at it
<Response>
<Connect>
<Stream url="wss://your-host/twilio" />
</Connect>
</Response>Then call the number. Audio goes to the Voice API, the agent answers from your prompt, and the reply streams back on the same socket — billed from your prepaid balance at ₹1.50 to ₹3.75 a minute depending on the voice grade. Nothing about your Twilio account changes: the number, the trunk and the per-minute connectivity stay billed by Twilio.
Prefer to write it yourself?
You do not have to use the bridge. The protocol reference is one REST call and one WebSocket, and Setu is MIT licensed — the twilio.ts adapter is about a hundred readable lines. Copy it, port it, or read it to find out what the vendor docs left out. There is also a complete Python and FastAPI implementation in the repository's examples folder, covering the whole protocol including barge-in.
Other providers