if there are 2 participants in a room with an agen...
# ask-ai
i
if there are 2 participants in a room with an agent, and the agent publishes a dtmf tone, do all participants receive it?
✅ 1
t
Thanks for reaching out, Ed. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — good question. Yes. When an agent publishes a DTMF tone in a LiveKit room, it’s sent as a signaling event (
dtmf_received
) and is broadcast to all participants in the room. Each participant can listen for the
dtmf_received
event (which includes the sender,
code
, and timestamp), so receiving the tone does not depend on subscribing to an audio track. Sources: Agent Console | LiveKit Documentation, with interactive elements
i
ok so lets say we have the following scenario: • agent is on a call with Participant A, at this point only Participant A and the agent are in the room • the agent decides to make an outbound call, using create_sip_participant, to add Participant B to the current room, in this CreateSIPParticipantRequest the agent dials Participant B's phone number with
dtmf
. This is basically so it can call Participant B while dialing an extension. Will this work? Will Participant B received the DTMF tone?
t
Thanks — I’m responding to your scenario about placing an outbound SIP call via
create_sip_participant
and including DTMF digits in the dial string so Participant B receives them while being called. Short answer: No — embedding DTMF in the
sip_call_to
dial string is not confirmed as supported, so Participant B will not reliably receive DTMF tones that way. LiveKit delivers DTMF as signaling events and supports sending DTMF to a connected telephony party using the
send_dtmf_events
tool (or sending
dtmf_received
events) after Participant B is added and the call is established. If you want, I can: • Outline the exact steps to call Participant B and then send DTMF after they join using
send_dtmf_events
, or • Help you test whether your SIP provider supports DTMF-in-dial-string behavior in your environment. Which would you prefer? Sources: Making calls overview | LiveKit Documentation | Preserving Caller ID During SIP Transfers in LiveKit Agents | send_dtmf_events | LiveKit Documentation | Prebuilt tools | LiveKit Documentation | GetDtmfTask | LiveKit Documentation, with interactive elements
i
why wouldnt using the
dtmf
field on CreateSIPParticipantRequest work?
t
Thanks — good question. You're asking why the
dtmf
field on
CreateSIPParticipantRequest
doesn’t reliably send DTMF to the remote phone during outbound call setup. Short answer:
CreateSIPParticipantRequest
is used to establish the SIP call (the dial/INVITE). It does not act as a DTMF transport; the API does not interpret or guarantee transmission of DTMF sequences embedded in the dial string. DTMF in LiveKit is modeled as discrete signaling events (
dtmf_received
) and handled separately from call setup. Why that matters: • SIP INVITE/dial strings with appended digits (pauses/commas or DTMF digits) are a dialing convention that may be interpreted by a PBX or phone client before the call is answered. LiveKit does not parse or translate those into guaranteed DTMF events to be delivered to the remote endpoint during call setup. • Telephony providers and SIP trunks differ in how (or whether) they accept in-dial-string DTMF or send DTMF before call connect (early media). Even if you put digits in the dial string, the provider may strip them or not transmit them to the callee. • LiveKit’s supported mechanism is to send DTMF as events to an already-established participant (for example using the
send_dtmf_events
tool). That ensures the DTMF is sent over the signaling path the provider/endpoint will accept after the call is active. What you can do: • Place the outbound call with
CreateSIPParticipantRequest
to add Participant B. • Once Participant B is connected, send DTMF using
send_dtmf_events
(or emit
dtmf
events) so the remote phone reliably receives the tones. If you’d like, I can outline the exact sequence/code to place the SIP participant then send DTMF after connect, or help you test whether your SIP provider supports DTMF-in-dial-string behavior. Which would you prefer? , with interactive elements
i
but isnt the dtmf field of CreateSIPParticipant used for dialing extensions for outbound calls? im not understanding the difference
t
Thanks — good follow-up. I’ll clarify the difference and why the
dtmf
field can be confusing. What the
dtmf
field is for • The
CreateSIPParticipantRequest
establishes the SIP call (INVITE) to add a remote phone as a participant. • The
dtmf
field is not a guaranteed transport for sending tones to a remote endpoint during the dialing/INVITE phase. It indicates or configures DTMF handling/capability for the session, but it does not ensure the remote phone will receive in‑call DTMF digits before the call is answered. Why dialing extensions via the dial string differs from sending DTMF events • Dial-string conventions (like appending commas and digits to a phone number to auto-fill extensions) are client/provider-side behaviors. LiveKit does not interpret or reliably transmit those appended digits as DTMF over the network during call setup. • Telephony providers and SIP trunks vary: some support sending DTMF in early media or via the dial string, others strip those characters or only accept DTMF after the call is established. • LiveKit models DTMF as discrete signaling events (
dtmf_received
) and provides an explicit mechanism to send DTMF after a participant is connected (e.g.,
send_dtmf_events
). That method reliably delivers tones to the telephony provider once the call is active. Practical recommendation • Use
CreateSIPParticipantRequest
to place the outbound call to Participant B. • After Participant B is connected, send the extension digits using
send_dtmf_events
(or emit
dtmf
events). That ensures the digits reach the remote phone and avoids provider-specific dial-string behavior. If you want, I can show the exact sequence or sample code to: 1. create the SIP participant, and 2. send DTMF once the participant is connected. Which would you like?, with interactive elements
i
so then why do you offer a dtmf field on CreateSIPParticipantRequest. also i've used that field for calling phone numbers that have phone menus upon connection and it works for dialing a phone menu option
t
Great question — you’re right to call that out. I’ll clarify the purpose of the
dtmf
field, why it can appear to work, and why it isn’t guaranteed. • Purpose of the
dtmf
field: it lets you include DTMF digits when creating the outbound SIP participant so dialing behavior can include extension-like digits or instructions at dial time. It exists because some call flows and providers accept dial-string digits or early‑media DTMF behavior during outbound call setup. • Why it may work in practice: some PSTN gateways, PBXs, or SIP trunks accept digits appended to the dial string (or honor early media) and will forward those digits to the destination or process them locally (e.g., navigate an IVR before answer). If your provider or the destination phone system supports that behavior, you’ll observe that the appended digits reach the menu. • Why it’s not reliable/universal: dial-string digit handling is provider- and network-dependent. Providers may: ◦ Strip appended characters, ◦ Not support sending DTMF before the call is answered (no early media), ◦ Interpret commas/pauses differently, or ◦ Require DTMF to be sent after call setup via RTP/Out‑of‑band methods. Because LiveKit models DTMF as signaling events and does not itself guarantee dial-string-to-DTMF translation during INVITE, behavior can vary across carriers and destinations. • Recommended approach for consistent results: place the outbound call with
CreateSIPParticipantRequest
, wait until Participant B is connected, then send the digits using
send_dtmf_events
(or emit
dtmf
events). That ensures the telephony provider receives DTMF using a supported mechanism once the call is established. If you’d like, I can: • Show a sample sequence (code) to create the SIP participant and then call
send_dtmf_events
when the participant is connected, or • Help you test whether your specific SIP provider supports dial-string DTMF/early media and what format works. Which do you prefer?, with interactive elements
i
ok so its not guaranteed but it works in practice but the 100% safe way is to somehow orchestrate a send_dtmf_event after call connection
t
Yes — that’s correct. The
dtmf
field can work in practice because some PSTN/SIP providers and destinations accept dial-string digits or early media, but it’s not guaranteed across providers or call setups. The reliable approach is to create the SIP participant, wait until Participant B is connected, then send the digits using
send_dtmf_events
(or emit
dtmf
events). Would you like a short code example or the exact sequence to implement that? , with interactive elements