By Sagar Shankaran, Founder of CallSphere
DTMF tone capture during agent speech, IVR-style menus, key suppression. How CallSphere handles DTMF via Twilio + custom logic vs Vapi defaults.
Key takeaways
DTMF (touch-tone) handling looks trivial until you realize agents speak over user inputs, carriers compress audio in ways that mangle tones, and users press keys at unpredictable moments. Vapi offers basic DTMF capture during silent listening windows. CallSphere uses Twilio's native DTMF event stream with custom in-flight logic to capture digits even while the agent is speaking, debounce carrier echoes, and route to IVR-style menus when needed.
This is the engineer-level guide to not letting "press 1 for English" eat your call quality.
Voice AI is great at speech recognition; DTMF still wins for:
Stripping DTMF support to look more "AI-native" is a downgrade.
Vapi exposes DTMF through assistant config and webhook events:
{
"voicemailDetection": {...},
"endCallFunctionEnabled": true,
"dtmfReceivedFunction": {
"name": "on_dtmf",
"url": "https://your-app.com/dtmf"
}
}
Default behavior: DTMF is captured during silent listening. If the agent is mid-utterance, DTMF events may be dropped, captured on next pause, or arrive without context.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
Strengths: simple to set up.
Weaknesses:
CallSphere subscribes to Twilio's native DTMF event stream on the Media Stream WebSocket. Twilio delivers DTMF as discrete events independently of audio, so CallSphere captures them whether or not the agent is speaking.
async def media_stream_handler(ws):
async for raw in ws:
event = json.loads(raw)
if event["event"] == "dtmf":
digit = event["dtmf"]["digit"]
await handle_dtmf(digit, ctx)
elif event["event"] == "media":
await forward_audio(event["media"]["payload"])
When a DTMF event arrives while the agent is speaking, CallSphere:
async def handle_dtmf(digit: str, ctx: CallContext):
ctx.dtmf_buffer.append(digit)
# Pause TTS if agent is speaking
if ctx.agent_speaking:
await ctx.realtime_session.cancel_response()
# Reset debounce window
ctx.dtmf_window_task and ctx.dtmf_window_task.cancel()
ctx.dtmf_window_task = asyncio.create_task(
finalize_dtmf_after_silence(ctx, silence_ms=1500)
)
Some carriers echo DTMF tones back as audio, which speech-to-text occasionally transcribes as words like "two" or "five." CallSphere maintains a 200ms suppression window after each DTMF event during which speech transcripts are filtered for digit-words paired with the just-pressed digit.
def is_echo_transcript(transcript: str, recent_dtmf: list[tuple[str, float]]) -> bool:
word_to_digit = {"one": "1", "two": "2", ...}
now = time.monotonic()
for digit, ts in recent_dtmf:
if now - ts > 0.2:
continue
for word, d in word_to_digit.items():
if word in transcript.lower() and d == digit:
return True
return False
For verticals that need traditional IVR fallback (Healthcare, After-Hours), CallSphere supports a config-driven menu mode:
ivr_menu:
prompt: "For appointments, press 1. For billing, press 2. To speak with someone, press 0."
options:
"1": handoff:scheduling_specialist
"2": handoff:billing_specialist
"0": handoff:human
timeout_ms: 8000
on_timeout: handoff:human
on_invalid: replay_prompt
The agent can drop into menu mode mid-call ("I'll switch to a touch-tone menu") and exit back to conversational mode after the routing decision.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
For credit card capture, CallSphere flips into PCI mode: speech transcript is dropped (no logging, no LLM forwarding), only DTMF events are captured into a tokenization service (Stripe / Square), and the agent only knows the card was captured successfully or not.
async def collect_card_pci_mode(ctx: CallContext):
ctx.pci_mode = True # disables transcript logging
ctx.realtime_session.disable_speech_input()
digits = await collect_dtmf(ctx, count=16, timeout_ms=30000)
cvv = await collect_dtmf(ctx, count=3, timeout_ms=10000)
expiry = await collect_dtmf(ctx, count=4, timeout_ms=10000)
token = await stripe.tokenize(digits, cvv, expiry)
ctx.pci_mode = False
ctx.realtime_session.enable_speech_input()
return token
| Dimension | Vapi | CallSphere |
|---|---|---|
| In-flight capture (during agent speech) | Limited | Yes (TTS pauses) |
| Echo debounce | None | 200ms suppression |
| IVR menu mode | DIY | Config-driven |
| PCI mode (card capture) | DIY | Built-in |
| Multi-digit sequences | Webhook per digit | Buffered with debounce |
| Carrier compatibility | Vendor-side | Twilio native, all carriers |
| Custom action per digit | Webhook | Inline handler or handoff |
sequenceDiagram
participant User
participant Twilio
participant Agent
participant Realtime as OpenAI Realtime
participant Tokenize as Stripe Tokenize
Agent->>Realtime: Generate "Please enter your card"
Realtime-->>Twilio: PCM16 audio
Twilio-->>User: "Please enter your card..."
User->>Twilio: Press 4
Twilio->>Agent: dtmf event "4"
Agent->>Realtime: cancel_response()
Agent->>Agent: pci_mode=true, disable speech
User->>Twilio: Press 1, 2, 3, ... (16 digits)
Twilio->>Agent: dtmf events
Agent->>Tokenize: tokenize(digits, cvv, expiry)
Tokenize-->>Agent: token_xyz
Agent->>Agent: pci_mode=false
Agent->>Realtime: "Card captured. Confirm?"
Realtime-->>Twilio: PCM16
Twilio-->>User: "Card captured. Confirm?"
No — pulse dialing is rare in 2026 and Twilio does not deliver pulse events. Pulse callers must dial differently or use voice.
Twilio's signaling-channel DTMF events bypass audio, so this is not an issue. Inband DTMF (rare) is detected separately.
Yes — the dtmf event handler can cancel an in-flight tool call if the user presses the universal cancel key (configurable, default 0).
Compliance posture is your call; CallSphere's PCI mode is designed to support a SAQ A scope by never persisting PAN data. Confirm with your QSA.
DTMF after voicemail prompts ("press 1 to skip greeting") is captured the same way; CallSphere's voicemail detector uses a separate signal cascade (covered in another post).
The /features page lists DTMF-supported verticals, and /demo includes a credit-capture flow that shows PCI mode live.

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
Tbilisi professional-services firms serving relocating founders and IT companies use CallSphere AI voice and chat agents to answer enquiries 24/7 in English, Georgian and Russian and book consultations.
A how-to for Colombian education and tutoring SMBs to answer parents and students instantly, book trial classes 24/7 in Spanish and English, and grow enrollment with a CallSphere AI agent.
Ethiopian coffee exporters and cooperatives lose buyer enquiries across time zones. See how a CallSphere AI voice and chat agent answers international coffee buyers 24/7 in Amharic and English.
A practical how-to for Palau eco-resorts and dive operators on capturing every high-value, multilingual enquiry with a CallSphere AI voice and chat agent, while honouring Palau’s marine-conservation commitments.
How salons, spas and wellness SMBs across the UAE, Saudi Arabia and Qatar use CallSphere AI voice and chat agents to capture every booking 24/7 in Arabic, English and expat languages, and cut no-shows.
How estate agents and property managers in Luxembourg City and across the Grand Duchy use CallSphere to capture multilingual viewing and enquiry calls 24/7, GDPR compliant.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI