Cozzo-tested · Round 6 · October 26, 2026
AI receptionist benchmark, round 6: a dental office, 9 voice agents, 3 calls per test
Round 6 called 9 voice agents with a dental-office prompt (Riverside Family Dental), 3 calls per test (Bland 2). We also tested callbacks, finished the OpenAI Realtime run from Round 5, and tested Pipecat before and after a read-back fix.
Verdict
- The $189 price: ElevenLabs, Retell, Ultravox, Vapi, LiveKit, Pipecat and Millis quoted it on every call (Bland 2/2). OpenAI quoted $899 once (2/3).
- Number read-back is still the weak spot. On the quote call, LiveKit read the number back correctly 0 of 3 times, Retell 1 of 3, Millis 2 of 3 and Pipecat 2 of 3. ElevenLabs, Ultravox, Vapi and OpenAI got 3 of 3.
- Fastest median reply: ElevenLabs (1070 ms), Retell (1300) and Ultravox (1460). Millis was slowest (1940 ms).
- Triage: Vapi told the caller to go to the ER or call 911 on all 3 calls, but offered cleaning slots on one of them. Every other agent passed.
- Interruptions: every agent stopped within 2.44 s except Bland, which took 3.16 s and 2.26 s (1 of 2 within the line).
- Talking over the caller: Vapi 12 times, Bland 9, Millis 5, ElevenLabs 4. The others, 0.
- Pipecat: our own build dropped digits when reading a number back. After we fixed how it pronounces digits, 10 of its 12 read-backs were correct and none dropped a digit. The other 2 had no read-back at all.
- Callbacks: only Ultravox and Bland can call back on our setup. Ultravox rang in 1.1 s and 1.7 s with every detail right. Bland rang in 5.6 s and 9.7 s and missed one item on each call.
Three calls per test is a first screen. Test your own script before you go live.
Dental office
Calls passed out of calls made. 3 per test, except Bland (2). Interrupt = the agent stopped within 2.44 s of the caller cutting in and answered the Friday-afternoon question.
| Vendor | Quote $189 | Quote read-back | Booking + read-back | Triage | After-hours | Interrupt (≤ 2.44 s) | Median ms (turns) | Talk-overs |
|---|---|---|---|---|---|---|---|---|
| ElevenLabs | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 1070 (30) | 4 |
| Retell | 3/3 | 1/3¹ | 3/3 | 3/3 | 3/3 | 3/3 | 1300 (30) | 0 |
| Ultravox | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 1460 (30) | 0 |
| Vapi | 3/3 | 3/3 | 3/3 | 2/3² | 3/3 | 3/3 | 1670 (30) | 12 |
| OpenAI (dental-only) | 2/3³ | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 1720 (30) | 0 |
| LiveKit | 3/3 | 0/3⁴ | 2/3⁴ | 3/3 | 3/3 | 3/3 | 1800 (31) | 0 |
| Pipecat (fixed)⁵ | 3/3 | 2/3 | 2/3 | 3/3 | 3/3 | 3/3 | 1800 (29) | 0 |
| Bland (2 calls)⁶ | 2/2 | 2/2 | 2/2 | 2/2 | 2/2 | 1/2 | 1910 (16) | 9 |
| Millis | 3/3 | 2/3⁷ | 2/3⁷ | 3/3 | 2/3⁷ | 3/3 | 1940 (31) | 5 |
- Quote $189
- Stated the listed price
- Quote read-back
- Read the callback number back correctly while taking a message
- Booking + read-back
- Confirmed Wednesday 2:30 and read the number back correctly
- Triage
- Sent the caller to the ER or 911 without offering cleaning slots
- After-hours
- Said the office was closed
- Interrupt
- Stopped within the pass line and answered the Friday question
- Median ms (turns)
- Gap from end of caller speech to agent speech, pooled over all turns (number of turns)
- Talk-overs
- Times the agent started speaking over the caller
¹ Retell read the number back as “412-550-87” and as “4-pole-555-0187”; the second could be our speech-to-text garbling it. ² Vapi said ER/911, then offered cleaning slots (1 of 3 calls).
³ OpenAI quoted “$899” instead of $189 on one call. Its read-backs were correct on all 6 calls where they were tested.
⁴ LiveKit read back “412-5587”, “412-555-White-7” and “412-555-087” on the quote calls, and “412-55-187” on one booking call. It drops digits, the same kind of fault as Pipecat’s.
⁵ Pipecat is our own build, scored after the digit fix (see the Pipecat section). On one quote call the agent trailed off at “your number…” and the caller hung up; on one booking call it went silent after the number and the call hit Twilio’s 120 s limit with no confirmation.
⁶ Bland has 2 calls per test instead of 3, so its cells aren’t directly comparable. It also gave a garbled insurance answer (“out of network for Friday”) on its interruption call.
⁷ Millis: one booking call never reached the number (the agent greeted after the caller’s opening line, asked who the caller was, and the recording ends about 14 s in), one quote call read the number back as “412-555-50187”, and on one after-hours call the agent never answered the Saturday question before the caller hung up. These are scored as Millis misses but may partly be caller-versus-greeting timing.
OpenAI’s dental results are from a dental-only prompt. In the first run, on a combined four-business prompt, it failed the interruption test by asking which business the caller meant. That failure went away with the dental-only prompt (see the OpenAI section). Talk-overs count each time the agent started speaking over the caller.
Interruption stop times
Seconds the agent kept talking after the caller cut in. The pass line is 2.44 s.
| Vendor | Stops (s) | Within 2.44 s |
|---|---|---|
| ElevenLabs | 0.54, 0.60, 1.36 | 3/3 |
| Retell | 0.44, 0.46, 0.54 | 3/3 |
| Ultravox | 0.34, 0.42, 0.44 | 3/3 |
| Vapi | 1.06, 0.30, 1.04 | 3/3 |
| OpenAI (dental-only) | 0.10, 0.16, 0.06 | 3/3 |
| LiveKit | 1.18, 1.24, 0.78 | 3/3 |
| Pipecat (after fix) | 0.64, 0.54, 0.56 | 3/3 |
| Millis | 0.46, 0.14, 0 (agent already silent) | 3/3 |
| Bland (2 calls) | 3.16, 2.26 | 1/2 |
Pass line = the slowest stop we measured in Round 5 (2.44 s, Bland, coaching). It is set by our own slowest result, so it ranks the agents against each other, not against an outside standard. Every agent that stopped within it also answered the Friday question correctly (8 a.m. to 1 p.m., closed in the afternoon). Pipecat’s replies after the interruption were slow on two calls (4.5 s and 4.7 s).
Callbacks
A message call, then a callback to the caller. Two cycles per vendor.
| Vendor | Cycles | Trigger to ring | Name | Price | Number | Slots |
|---|---|---|---|---|---|---|
| Ultravox | 2 | 1.1 s, 1.7 s | 2/2 | 2/2 | 2/2 | 2/2 |
| Bland | 2 | 5.6 s, 9.7 s | 2/2 | 2/2 | 1/2 | 1/2 |
- Trigger to ring
- Time from our trigger to the caller’s phone ringing
- Name, Price, Number, Slots
- Details given correctly on the callback
Not supported on our setup: Vapi, Retell, ElevenLabs, Millis, LiveKit and OpenAI.
Our script starts each callback (about 47 s after the message call ends), so this measures callback quality, not whether the vendor calls back on its own. Bland skipped the number on one callback. Ultravox’s number was scored from its own transcript; Bland’s callbacks from our speech-to-text only.
OpenAI Realtime
OpenAI first ran on one combined prompt covering four businesses. We then reran dental on a dental-only prompt, so the dental table above uses the rerun.
| Run | Calls | Median reply ms |
|---|---|---|
| Career coach (combined prompt) | 5 | 1930 |
| Gym, after-hours and interrupt (combined prompt) | 2 | 1680 |
| Dental, first run (combined prompt) | 5 | 2000 |
| Dental, rerun (dental-only prompt) | 15 | 1720 |
Change: on the combined prompt, OpenAI’s one dental interruption call failed because it asked which business the caller meant. With a dental-only prompt, all 3 interruption calls passed (stops of 0.10, 0.16 and 0.06 s) and every call had 0 talk-overs. The coaching and gym runs above are still on the combined prompt.
Gym after-hours passed. On the gym interruption call, our speech-to-text heard the Basic plan quoted as “20” (the listed price is $29), so we count it as a likely miss.
Pipecat, before and after a fix
Pipecat is open-source software, and this is our own build of it (pipecat-ai 1.14.0 with Deepgram nova-3, gpt-4o-mini, ElevenLabs flash v2.5 and Silero VAD), not a hosted product. It joined calls through LiveKit Cloud phone rooms.
| Read-back | Before the fix (1 call each) | After the fix (3 calls each) |
|---|---|---|
| Dental quote | 0/1 | 2/3 |
| Dental booking | 0/1 | 2/3 |
| Gym booking (Spin Thursday 6 PM) | 0/1 | 3/3 |
| Gym quote ($49) | Not scored separately | 3/3 |
In the first run, 4 of 5 of our Pipecat bot’s number read-backs had missing digits. The cause was our text-to-speech voice (ElevenLabs flash v2.5) dropping digits when it read “412-555-0187”. The text the model wrote was always correct. The fix was to digit pronunciation: a text filter that spells the digits out. This is a fault in our own build, not in Pipecat or a vendor. In an offline test, 2 of 4 raw samples were fully correct and 3 of 4 were correct with the fix.
After the fix, no read-back dropped a digit: 10 of 12 read-backs were correct, and the other 2 had no read-back at all (the dental calls in footnote 5). Dental is only 3 calls, so treat it as a small sample. Median reply 1800 ms (29 turns) on dental. Its cost and speed include LiveKit Cloud, not a direct phone path.
Methodology
On Oct 26, 2026, Cozzo placed real phone calls. We picked dental over plumbing because three of four Google Trends comparisons (US, 12 months) favored dental. Each vendor got the same dental prompt plus one message-taking instruction. Each test was 3 calls: the first valid call from the original round plus follow-up calls (Bland has 2).
A scripted AI caller (built on Ultravox) played the customer from one test number. Every call was recorded on separate caller and agent channels and transcribed with Whisper small.en. Read-backs were scored against what the caller actually said (4125550187, all 10 digits in order). Tests: quote ($189 and number read-back), booking (Wednesday 2:30 plus read-back), triage (ER or 911 with no cleaning slots), after-hours (said closed) and an interruption test.
Reply time is the gap from the end of the caller’s speech to the agent’s reply, pooled over every turn in every included call. Stop time is how long the agent kept talking after the caller cut in. Pass line = 2.44 s (see above).
LiveKit and Pipecat are our own self-hosted pipelines, not hosted products. Cozzo paid for every call; no vendor sponsored or reviewed these results (see our disclosure).
Limits
- Small samples: 3 calls per test, 2 for Bland. One bad call moves a cell by a third.
- Read-backs were scored from Whisper small.en transcripts, which can drop or garble digits. That can penalize a vendor (see Retell, footnote 1). We did not round in any vendor’s favor.
- Two Ultravox calls (after-hours and interruption) failed outright on the phone network, so we excluded them and redid them. A first Ultravox quote call was also excluded because its greeting was a “[Your Name]” placeholder.
- We have no vendor-side call IDs for LiveKit, OpenAI or Pipecat, because their calls run through rooms or SIP rather than a vendor API. We have call IDs for the others.
- Five call records showed a stale status and zero duration. We corrected them from Twilio and scored them on their transcripts.
- Extra valid calls from our callback tests and one redo are not in the tables. Counting them would give Bland a quote read-back of 3 of 4 and Ultravox 5 of 6.
- Callbacks were started by our script, so they measure quality, not autonomy.
- Reply times come from recordings and are pooled over turns. After-hours calls have a single turn each.
- Bland was tested on its remaining credit only, so it has 2 calls per test.