Dial-in: WebRTC (Twilio + Daily)
Connect phone calls to your Pipecat bot using Twilio and Daily’s SIP integration
Things you’ll need
- An active Twilio developer key
- One or more Twilio provisioned phone numbers (covered below)
- The Twilio Python client library (
pip install twilio
)
Prefer to look at code? See the example project!
We have a complete example project using Daily as a transport with Twilio as a phone provider. This guide walks through the important components and best practices when integrating voice calls.
How It Works
Here’s the sequence of events when someone calls your Twilio number:
- Twilio receives an incoming call to your phone number
- Twilio calls your webhook server (
/call
endpoint) - Your server creates a Daily room with SIP capabilities
- Your server starts the bot process with the room details
- Your server responds to Twilio with TwiML that puts the caller on hold with music
- Upon receiving the
on_dialin_ready
event, the bot forwards the call to the Daily SIP endpoint - The caller and bot are connected, and the bot handles the conversation
Getting a phone number
- Visit console.twilio.com and purchase a new phone number (or via the API)
- Ensure your purchased number supports Voice capabilities
- Ensure your purchased number appears in your ‘active numbers’ list
Project setup
You’ll need to set two environment variables for your project: TWILIO_ACCOUNT_SID
and TWILIO_AUTH_TOKEN
, which you can obtain from the Twilio console.
Configuring your bot runner
You’ll need a HTTP service that can receive incoming call hooks and trigger a new agent session. We discussed the concept of a bot runner in the deployment section, which we’ll build on here to add support for incoming phone calls.
Here’s how to implement this with FastAPI:
Creating a SIP-enabled room
We’ll need to configure the Daily room to be setup to receive SIP connections. In our example project, utils/daily-helpers.py
demonstrates how to set up the Daily room using the Daily REST helpers available in Pipecat. We just need to pass through new SIP parameters as part of room creation:
Configuring your bot
Your bot needs to handle the on_dialin_ready
event to forward the call at the right time:
Setting up the Twilio webhook
Configure your Twilio phone number to use your server’s webhook URL:
- Go to the Twilio Console
- Navigate to Phone Numbers → Manage → Active Numbers
- Click on your phone number
- Under “Configure”, set “A Call Comes In” to:
- Webhook:
https://your-server.com/call
(your server’s URL) - HTTP Method: POST
- Webhook:
Testing locally
For local development, you can use ngrok to expose your local server:
Best Practices and Common Pitfalls
✅ Best Practice: Put the call on hold
Always respond to Twilio’s initial webhook with hold music. This gives your bot time to initialize and the Daily SIP endpoint to become ready.
❌ Pitfall: Using <Pause>
instead of hold music
Don’t use the TwiML <Pause>
element to wait for the bot to initialize:
Twilio can only pause a call for a short duration (~5 seconds), which may not be enough time for the Daily SIP setup to complete.
✅ Best Practice: Handle multiple on_dialin_ready
events
If your Daily room has multiple SIP endpoints, use a flag to ensure you only forward the call once:
A single SIP endpoint is sufficient for the initial connection. A second SIP endpoint is needed only if you plan to forward the call.