What I Learned While Trying to Build a Custom Voice Phone Agent with Twilio, ElevenLabs, and OpenAI

twillio and elevenlabs

Building a Phone Agent with Twilio and ElevenLabs: What I Learned

I wanted a phone number that people could call, talk to naturally, and get a response in a cloned voice. The stack sounded simple at first, but the actual architecture turned out to have a few very different paths, each with tradeoffs.

What I ended up learning is that Twilio and ElevenLabs can be combined in more than one way, and the choice changes who owns the conversation logic, who handles speech-to-text, and where the voice audio actually comes from.

The Goal

My goal was straightforward:

  • Twilio provides the phone number and call routing
  • the caller speaks into the phone
  • the system transcribes the speech
  • an LLM decides the response
  • the response is spoken back in a cloned voice

That sounds like one system, but there are really three different ways to build it.

Option 1, Twilio ConversationRelay

ConversationRelay is the lowest-friction path if you want to move fast. Twilio handles the phone side, and it gives you a tight voice loop with strong latency characteristics.

The catch is that it is opinionated. In my testing, it worked well with standard voices, but it did not fit my custom cloned ElevenLabs voice setup the way I wanted.

So the tradeoff is clear:

  • strong latency
  • simple Twilio integration
  • less flexibility around custom voice behavior

If your priority is speed and you are okay with the platform’s voice constraints, this is a solid path.

Option 2, ElevenLabs Agents

ElevenLabs Agents gave me the next best thing: low-latency voice-agent behavior, but with support for custom voices.

This was the first path where my cloned voice actually made sense. I had to get the ElevenLabs side configured correctly, including plan access for the cloned voice, and once that was in place, the agent could speak in my own voice.

What I learned here is important:

  • ElevenLabs can own the agent runtime
  • ElevenLabs can also own the LLM layer
  • Twilio becomes the transport layer for the phone call

That means if you use ElevenLabs Agents, you are not just buying text-to-speech. You are buying the whole voice agent stack.

The upside is simplicity. The downside is that your conversation logic lives more inside ElevenLabs than inside your own app.

Option 3, Build It Yourself

This is the path I originally assumed I would take: Twilio handles calls, my Node app handles STT, OpenAI handles the LLM, and ElevenLabs only does TTS.

That architecture is absolutely valid.

It looks like this:

  • Twilio receives the call
  • Twilio streams audio to my server
  • my server transcribes audio
  • OpenAI generates the response
  • ElevenLabs synthesizes the response in my cloned voice
  • audio is sent back into the call

This gives you the most control, because you own the logic, prompts, tool calls, business rules, and state.

But it also means you own the full media pipeline. That is where complexity shows up:

  • audio formats have to match
  • streaming has to stay real-time
  • you need a bridge between generated audio and the live Twilio call
  • latency depends on how well you implement every hop

So this is not automatically “better,” it is just more flexible.

The Key Architectural Difference

The main question is: who owns the conversation?

  • If you use ConversationRelay, Twilio manages a lot of the voice plumbing, but you lose flexibility around custom voices.
  • If you use ElevenLabs Agents, ElevenLabs manages the voice agent runtime, and custom voices work well.
  • If you build it yourself, you own everything, including the LLM, but you also own all the streaming and latency work.

My Takeaway

For a quick, managed setup, ConversationRelay is the easiest.

For custom voice with a managed agent stack, ElevenLabs Agents is the best fit.

For maximum control, roll your own, but expect more work.

The real lesson is that Twilio is the call layer, and ElevenLabs is either the voice layer or the full agent layer depending on how you use it.

Discover more from Mark Mun

Subscribe now to keep reading and get access to the full archive.

Continue reading