Register Twilio calls

Use your own Twilio infrastructure to connect calls to ElevenLabs agents.
Advanced

This guide covers an advanced integration pattern for developers who need full control over their Twilio infrastructure. For a simpler setup, consider using the native Twilio integration which handles configuration automatically.

When to use each approach

Before diving in, understand the trade-offs between the native integration and the register call approach:

FeatureNative integrationRegister call
Ease of setupEasierMore complex
Call transfersSupportedNot supported
Custom Twilio logicLimitedFull control
Phone number managementThrough ElevenLabsThrough Twilio

Overview

The register call endpoint allows you to use your own Twilio infrastructure while leveraging ElevenLabs agents for the conversation. Instead of importing your Twilio number into ElevenLabs, you maintain full control of your Twilio setup and use the ElevenLabs API to register calls and receive TwiML for connecting them to your agents.

This approach is ideal when you:

  • Need to maintain your existing Twilio infrastructure and workflows
  • Want programmatic control over call routing and handling
  • Have complex call flows that require custom Twilio logic before connecting to an agent
  • Need to integrate ElevenLabs agents into an existing telephony system

How it works

  1. Your server receives an inbound call or initiates an outbound call via Twilio
  2. Your server calls the ElevenLabs register call endpoint with agent and call details
  3. ElevenLabs returns TwiML that connects the call to your agent via WebSocket
  4. You return this TwiML to Twilio to establish the connection

When using the register call endpoint, call transfer functionality is not available as ElevenLabs does not have direct access to your Twilio account credentials.

Prerequisites

Agent configuration

Before using the register call endpoint, configure your agent to use the correct audio format supported by Twilio.

1

Configure TTS Output

  1. Navigate to your agent settings
  2. Go to the Voice section
  3. Select “μ-law 8000 Hz” from the dropdown
2

Set Input Format

  1. Navigate to your agent settings
  2. Go to the Advanced section
  3. Select “μ-law 8000 Hz” for the input format

API reference

The register call endpoint accepts the following parameters:

ParameterTypeRequiredDescription
agent_idstringYesThe ID of the agent to handle the call
from_numberstringYesThe caller’s phone number
to_numberstringYesThe destination phone number
directionstringNoCall direction: inbound (default) or outbound
conversation_initiation_client_dataobjectNoDynamic variables and configuration overrides

The endpoint returns TwiML that you should pass directly to Twilio.

Implementation

1import os
2from fastapi import FastAPI, Request
3from fastapi.responses import Response
4from elevenlabs import ElevenLabs
5
6app = FastAPI()
7
8elevenlabs = ElevenLabs()
9AGENT_ID = os.getenv("ELEVENLABS_AGENT_ID")
10
11@app.post("/twilio/inbound")
12async def handle_inbound_call(request: Request):
13 form_data = await request.form()
14 from_number = form_data.get("From")
15 to_number = form_data.get("To")
16
17 # Register the call with ElevenLabs
18 twiml = elevenlabs.conversational_ai.twilio.register_call(
19 agent_id=AGENT_ID,
20 from_number=from_number,
21 to_number=to_number,
22 direction="inbound",
23 conversation_initiation_client_data={
24 "dynamic_variables": {
25 "caller_number": from_number,
26 }
27 }
28 )
29
30 # Return the TwiML directly to Twilio
31 return Response(content=twiml, media_type="application/xml")
32
33if __name__ == "__main__":
34 import uvicorn
35 uvicorn.run(app, host="0.0.0.0", port=8000)

Outbound calls

For outbound calls, initiate the call through Twilio and point the webhook URL to your server, which then registers with ElevenLabs:

1from twilio.rest import Client
2import os
3from fastapi import Request
4from fastapi.responses import Response
5from elevenlabs import ElevenLabs
6
7# Initialize clients
8twilio_client = Client(
9 os.getenv("TWILIO_ACCOUNT_SID"),
10 os.getenv("TWILIO_AUTH_TOKEN")
11)
12elevenlabs = ElevenLabs()
13AGENT_ID = os.getenv("ELEVENLABS_AGENT_ID")
14
15def initiate_outbound_call(to_number: str):
16 call = twilio_client.calls.create(
17 from_=os.getenv("TWILIO_PHONE_NUMBER"),
18 to=to_number,
19 url="https://your-server.com/twilio/outbound"
20 )
21 return call.sid
22
23@app.post("/twilio/outbound")
24async def handle_outbound_webhook(request: Request):
25 form_data = await request.form()
26 from_number = form_data.get("From")
27 to_number = form_data.get("To")
28
29 twiml = elevenlabs.conversational_ai.twilio.register_call(
30 agent_id=AGENT_ID,
31 from_number=from_number,
32 to_number=to_number,
33 direction="outbound",
34 )
35
36 return Response(content=twiml, media_type="application/xml")

Personalizing conversations

Use the conversation_initiation_client_data parameter to pass dynamic variables and override agent configuration:

1{
2 "agent_id": "your-agent-id",
3 "from_number": "+1234567890",
4 "to_number": "+0987654321",
5 "direction": "inbound",
6 "conversation_initiation_client_data": {
7 "dynamic_variables": {
8 "customer_name": "John Doe",
9 "account_type": "premium",
10 "order_id": "ORD-12345"
11 }
12 }
13}

For more information about dynamic variables and overrides, see the dynamic variables and overrides documentation.

Twilio configuration

Configure your Twilio phone number to point to your server:

1

Create a public URL

For local development, use ngrok to expose your server:

$ngrok http 8000
2

Configure your Twilio number

  1. Go to the Twilio Console
  2. Navigate to Phone Numbers > Manage > Active numbers
  3. Select your phone number
  4. Under “Voice Configuration”, set the webhook URL to your server endpoint (e.g., https://your-ngrok-url.ngrok.app/twilio/inbound)
  5. Set the HTTP method to POST

Limitations

When using the register call endpoint instead of the native integration:

  • No call transfers: Transfer functionality is not available as ElevenLabs does not have access to your Twilio credentials
  • Manual configuration: You must configure audio formats and handle TwiML routing yourself
  • No dashboard import: Phone numbers registered this way do not appear in the ElevenLabs phone numbers dashboard