This guide covers theDocumentation Index
Fetch the complete documentation index at: https://docs.pipecat.ai/llms.txt
Use this file to discover all available pages before exploring further.
provider="daily" SIP mode, where Daily directly connects its SIP leg to your telephony carrier (Twilio, Telnyx, Five9, Genseys, Cisco, …). This SIP mode with provider="daily" gives you:
- Static egress IPs you can allow-list on the carrier side for tighter ACLs.
- One SIP configuration that works across carriers — the bot code doesn’t change when you swap providers.
The reference implementation lives in the Twilio SIP examples because Twilio
is the most common carrier, but the same bot code works with any SIP-capable
provider — only the carrier-side webhook / SIP URI changes.
SIP Dial-in Example
Inbound calls routed from a carrier into a Daily room via
provider="daily" SIPSIP Dial-out Example
Outbound calls initiated from Daily and routed out through the carrier
Things you’ll need
- A Daily API key.
- An account with a SIP-capable carrier (Twilio, Telnyx, Plivo, Exotel, …) with at least one provisioned number.
Environment Setup
.env
Creating a Daily room with provider="daily"
The key difference from the carrier-default SIP flow is a single field on the room SIP config:
server_utils.py
sip_endpoint you hand to your carrier for call forwarding, and (for dial-out) a room configured to accept start_dialout with {"provider": "daily", ...}. Daily’s SIP address are of the format: sip:$roomName.$index@$domainName.sip-us.daily.co.
Dial-in
Dial-in lets a caller reach your bot by calling a carrier-owned phone number. The carrier forwards the audio into Daily over SIP.Flow
- Carrier receives the incoming call and hits your webhook server.
- Your server creates a Daily room with
sip_provider="daily"and spawns the bot. - Your server responds to the carrier with hold music. So the caller isn’t in silence while the bot boots.
- The bot fires
on_dialin_readywith a Daily SIP endpoint URI. - The bot calls the carrier’s API to update the in-progress call, forwarding its audio to that SIP endpoint.
- Caller and bot are connected; Daily carries the media over WebRTC.
Bot configuration
bot.py
Complete dial-in server + bot
Full FastAPI server, bot, and README with setup instructions
Dial-out
Dial-out initiates an outbound call from Daily, routed out through the carrier.Flow
- Your app triggers a dial-out (API call, agent decision, scheduled task).
- Server creates a Daily room with
sip_provider="daily"andenable_dialout=True. - Bot joins the Daily room and sets up the WebRTC transport.
- Bot calls
transport.start_dialout(...)withprovider="daily"and a SIP URI pointing at the carrier. - Carrier places the PSTN call to the destination number.
- Recipient answers; media flows through Daily’s WebRTC transport to the bot.
Bot configuration
bot.py
Complete dial-out server + bot
Full FastAPI server, bot, and README with setup instructions
DTMF
Whenprovider="daily" is in use, Daily surfaces DTMF tones from the connected carrier leg and lets you send tones back out over the same session.
Receiving DTMF
Registeron_dtmf_event on the transport. The event fires once per keypress and the payload contains the sessionId of the calling leg and the pressed tone:
bot.py
InputDTMFFrame into the pipeline, so processors like DTMFAggregator can collect a sequence and feed it to an LLM as context; use that path if you want the bot to “hear” DTMF alongside speech.
Sending DTMF
To send DTMF tones back to the caller, send them through Daily’s native DTMF channel. Use the session id from the inbound event (or the dial-out session id captured inon_dialout_connected) as the target. The default methodto send the DTMF tones is auto, determined in the SIP offer/answer negotiation. However, if you already know what the remote party supports, then pick the appropriate option: telephone-events which are in-band RTP packets (RFC2833/4733) or as a sip-info message.
bot.py
OutputDTMFFrame / OutputDTMFUrgentFrame through the pipeline for cases where the tones are part of your bot’s conversational logic (IVR navigation, confirming a menu choice) rather than a direct invocation:
Best Practices
Guard against duplicate forwarding
on_dialin_ready can fire more than once when you have multiple sip endpoints defined on a room, for example for supervisory actions (silent monitoring, barge-in). In this case, you will need to keep track of which sip endpoint is assigned to which incoming call. Daily’s SIP address are of the format: sip:$roomName.$index@$domainName.sip-us.daily.co.
Allow-list Daily’s static IPs
One of the main reasons to pickprovider="daily" is that Daily publishes static IPs that you can allow-list on the carrier side, tightening SIP ACLs. Fetch the current list from Daily’s Networking Guide and configure your SIP trunk / IP access control list accordingly. There are different Static IP addresses for SIP signaling and media traffic.
Next Steps
- See Daily + Twilio SIP for the carrier-specific walkthrough (Twilio webhooks, TwiML, call forwarding).
- See Daily PSTN to skip the carrier entirely and have Daily provision the number.
- For simpler carrier-hosted telephony (no SIP), see Twilio WebSockets, Telnyx WebSockets, Plivo WebSockets, or Exotel WebSockets.