Found in AI answers?Hire Theory Road
Theory Road.

Twilio Dial Says Completed but Voicemail Answered? The Fix.

A ring-then-fallback call flow breaks the moment a person declines and their voicemail picks up. Twilio calls that completed. Here is how we screen the dialed leg so only a human keypress connects the caller.

By October 18, 202611 min read

When Twilio returns DialCallStatus=completed but no person ever spoke to the caller, the cause is almost always one of four things: the dialed person's carrier voicemail answered the leg (a declined call, a phone that is off, or a ring window shorter than your timeout), a call screening URL ended the leg with <Hangup>, which Twilio also reports as completed, a screening prompt fell through without a keypress and bridged the caller into the voicemail anyway, or your code treated completed as proof a human answered. The fix is to put a call screening whisper on the dialed <Number> that only bridges on a keypress, and to branch your action URL on DialBridged, not on DialCallStatus. Answering Machine Detection is the alternative when you cannot ask the person to press a key.

A quick definition. <Dial> is the TwiML verb that places a second call leg (the child call) from a live inbound call (the parent call) and connects the two. When the child leg ends, Twilio requests the URL in the action attribute and sends DialCallStatus, DialCallSid, DialCallDuration and DialBridged, and whatever TwiML you return controls what the caller hears next. DialCallStatus tells you how the child leg ended. DialBridged tells you whether it was ever connected to the caller. Those are different questions, and this bug lives in the gap between them.

We ran into this on one of our own lines. The flow rang a person's cell for a few seconds with <Dial> and, if nobody picked up, handed the caller to an AI receptionist through the action URL. When the person declined a call, their carrier voicemail answered, Twilio reported completed, and the caller sat in a voicemail box instead of reaching the agent. The same failure shows up in any ring-then-fallback flow: missed call text back, sales routing in a speed to lead system, or forwarding that keeps landing in personal voicemail, which we cover in Google Voice forwarded calls going to voicemail.

Why does DialCallStatus say completed when voicemail answers?

Twilio reports completed whenever the dialed leg is answered, and a carrier voicemail answering is an answer as far as the phone network is concerned. Twilio documents completed as the called party answering and being connected. Voicemail picks up the line exactly the way a person does, so Twilio cannot tell the two apart without extra work. no-answer only appears when nothing answers before your timeout, and a declined or unreachable mobile call is often answered by voicemail before that timeout ever arrives.

Glossary, in one line each. Whisper (call screening): TwiML that plays to the person you dialed after they answer and before the caller is connected. Bridged: the two legs are actually connected and can hear each other. AMD: Twilio Answering Machine Detection, which listens to the first seconds of the answered leg and guesses human or machine.

The four causes we find most often.

  • Carrier voicemail answered the leg: the person declined the call, the phone was off or out of coverage, or their ring-to-voicemail window is shorter than your timeout, so voicemail picks up and Twilio sees an answer
  • Whisper ended with Hangup: since a TwiML change dated 2020.12.09, a <Hangup> or <Reject> in the screening URL sets DialCallStatus to completed, where it used to be no-answer, so screened-out calls look answered too
  • Screening prompt fell through: <Gather> timed out with no keypress, control fell to the next verb, there was none, the whisper document ended, and the caller was bridged into the voicemail
  • Logic keyed on the wrong field: the action handler treats completed as a human answer and returns empty TwiML, so the call either ends or sits in voicemail instead of falling back

How do you verify what actually answered?

Read the parameters Twilio posted to your action URL and the child call's log, not the status label in your own database. Three checks, in this order.

The action URL request. Log the full request body your action endpoint receives. The fields that matter are DialCallStatus, DialBridged, DialCallDuration and DialCallSid. A voicemail answer without screening shows completed with DialBridged=true and a duration that matches how long the caller sat there. A screened-out call shows completed with DialBridged=false.

Call Logs in the Twilio Console. Open Monitor, then Logs, then Calls, find the parent call, and open the child call by the DialCallSid.

The Request Inspector and Debugger. In the same call detail view, read the requests Twilio made to your whisper and Gather URLs and the TwiML you returned. If the Gather action was never requested, nobody pressed a key. If your whisper document has no verb after <Gather>, you have found the fall-through.

Diagnose top to bottom.

This is the order we run. Each step stops at one layer.

Log the raw action request.
Log every parameter your action URL receives. You need DialCallStatus and DialBridged side by side for the failing call.
Check the timeout you actually get.
Twilio's timeout on <Dial> defaults to 30 seconds, accepts 5 to 600, and Twilio adds a five-second buffer, so a value of 10 rings for about 15. If the person's voicemail answers inside that window, lowering the timeout alone will not save you.
Call the line and decline it.
Reproduce the real failure: call in, decline on the dialed phone, and watch what the caller hears. In our tests a decline went to the carrier's voicemail and came back as completed.
Add a screening whisper on the Number.
Set url on the <Number> noun to a TwiML document with a <Gather numDigits="1"> that says press 1 to accept, followed by <Hangup/>. Set answerOnBridge="true" on the <Dial> so the caller keeps hearing ringing while the whisper runs.
Bridge only on the keypress.
In the Gather action, check that Digits is 1 and return TwiML that ends without a hangup, which lets the bridge proceed. Any other digit returns <Hangup/>. A voicemail greeting never presses 1, so the Gather times out, hits the Hangup, and the leg ends unbridged.
Branch the action URL on DialBridged.
Treat the call as answered only when DialBridged is true. Everything else, including completed with DialBridged=false, no-answer, busy, failed and canceled, goes to your fallback: the AI agent, a queue, or a callback flow.
Retest all four paths.
Answer and press 1, answer and do nothing, decline, and let it ring out. The first should connect. The other three should reach the fallback with DialBridged=false or no-answer.

What DialCallStatus values can Twilio return?

Twilio documents six values: completed, answered, busy, no-answer, failed and canceled, and only DialBridged tells you whether the caller was ever connected. As of October 2026 the docs define them as follows, and the last column is how we read each one in a ring-then-fallback flow.

DialCallStatus values on the Dial action URL, and how to treat them
DialCallStatusTwilio's meaningHow we treat it
completedCalled party answered and was connectedAnswered only if DialBridged is true. Voicemail and screened-out calls also land here
answeredCalled party answered, when dialing into a ConferenceOnly relevant to Conference dials
busyTwilio received a busy signalFallback
no-answerCalled party did not pick up before the timeoutFallback
failedTwilio could not route to the numberFallback, and alert on it, since it is usually a bad number
canceledCall canceled via the REST API before it was answeredFallback, unless your own code canceled it on purpose

Symptoms, causes and fixes.

A completed status with DialBridged=false means the dialed leg answered but was never connected to the caller. The table below is the reference we use when a ring-then-fallback flow misbehaves.

Twilio Dial reports completed but no human answered: symptom, likely cause, fix
SymptomLikely causeFix
Caller hears a personal voicemail greetingCarrier voicemail answered the child legAdd a keypress whisper on the Number url
Status is completed, no conversation happenedCode trusts DialCallStatusBranch on DialBridged instead
Status completed, DialBridged falseWhisper ended with Hangup (expected since 2020.12.09)Route to fallback; this is the screen working
Caller bridged into voicemail despite a whisperNo Hangup after Gather, so it fell throughPut Hangup as the verb after Gather
Declined calls never reach the fallbackDecline sends the call to carrier voicemailKeypress whisper plus DialBridged check
Fallback fires later than expectedFive-second buffer added to timeoutSet timeout about 5 seconds below your target
Real person answers, call dropsThey did not press the key in timeClear prompt, longer Gather timeout, repeat once
Caller hears silence while the dialed person screensanswerOnBridge not setSet answerOnBridge to true on Dial

Should you use Answering Machine Detection instead?

AMD works on <Dial><Number> through the machineDetection attribute, but it is a guess, it costs time, and Twilio warns it can misread very short voicemail greetings as a human.

How it works. Set machineDetection to Enable to get a result as soon as Twilio decides, with AnsweredBy values of human, machine_start, fax or unknown. Set it to DetectMessageEnd to wait for the end of the greeting, which adds machine_end_beep, machine_end_silence and machine_end_other. The results arrive at amdStatusCallback. machineDetectionTimeout runs from 3 to 59 seconds with a default of 30, and returns unknown when it expires. The speech and silence thresholds (machineDetectionSpeechThreshold default 2400 ms, machineDetectionSpeechEndThreshold default 1200 ms, machineDetectionSilenceTimeout default 5000 ms) trade accuracy against speed.

The tradeoffs we weigh. AMD adds a per-call charge on answered calls (check Twilio's voice pricing page for your country). Synchronous detection holds the call until a result comes back, and the caller is waiting through that. You still have to act on the result yourself, for example by ending the child leg when AnsweredBy starts with machine, and you need a rule for unknown. A keypress screen is deterministic: no keypress, no bridge. For your own team's phones we use the screen. For outbound calls to the public, AMD is the practical choice.

What is normal and what is a red flag?

A ring window about five seconds longer than your timeout value is normal, because Twilio adds a five-second buffer to every <Dial>. Also normal once screening is live: some calls return completed with DialBridged=false. Those are declines and voicemails your screen caught.

Red flags: any completed call with DialBridged=true and no conversation in the recording, which means voicemail got bridged and your whisper is falling through. And a whisper URL that never appears in the request log, which means the url attribute is on the wrong element or returning an error. If these calls also feed ad reporting, check the downstream side with website call conversions showing zero and CallRail GA4 integration, because a voicemail counted as an answered call inflates call conversions too.

Why does Twilio say completed when the call went to voicemail?

Because voicemail answered the dialed leg, and Twilio documents completed as the called party answering and being connected. The network does not tell Twilio whether a person or a voicemail system picked up. Use a keypress whisper or Answering Machine Detection to tell them apart.

What is DialBridged in Twilio?

DialBridged is a parameter Twilio sends to the Dial action URL. It is true only if the dialed call was actually connected to the parent call. Twilio added it in a TwiML change dated 2020.12.09 so you can tell a screened-out call apart from a bridged one, since both can report completed.

How do I make Twilio only connect a call when a human answers?

Add a url attribute on the Number noun that returns a Gather asking the person to press 1, followed by Hangup. Set answerOnBridge to true on Dial. In the Gather action, let the call proceed only when the digit is 1. A voicemail never presses a key, so it never gets bridged.

What is the default timeout for Twilio Dial?

30 seconds. The minimum is 5 and the maximum is 600. Twilio adds a five-second buffer, so the real ring time is about five seconds longer than the value you set.

Does Answering Machine Detection work with Dial?

Yes. The Number noun supports machineDetection, machineDetectionTimeout, the speech and silence thresholds, and amdStatusCallback. Detection is a guess, it can misread very short greetings, it adds a charge on answered calls, and you still have to act on the AnsweredBy result yourself.

Why does my screened call still connect to voicemail?

Almost always because nothing follows the Gather in the whisper TwiML. When Gather times out without input, Twilio moves to the next verb, and when the whisper document ends, the call connects. Add Hangup after the Gather.

Work with us

Let’s talk about what’s next.

A short note on where the business is and where it needs to go. A senior partner replies within one business day.

t@theoryroad.com

Step 1 of 2

How can we help you get found?

What do you need help with?

Next: name, email and budget. That’s it.