NNabeel Hassan

Blog · August 14, 2026 · 9 min read

The Hardest Part of a Voice Agent Is Writing Down an Email Address

By Nabeel HassanAI Engineer · ICPC World Finalist

TL;DR: The hard part of a production voice agent is not holding a conversation. It is writing down an email address correctly. Speech recognition is tuned for words, and names, emails, postcodes and reference numbers are not words. My rules: never ask for a field you can already look up, ask for the fewest fields the next step actually needs, confirm identifiers in chunks rather than all at once, validate the shape in the pipeline instead of trusting the model's ears, move spelling into text where text belongs, and always give the repair loop an exit. A booking that saves with a slightly wrong name is fine. A booking that saves with a wrong phone number is lost revenue nobody notices.

A garage agent I reviewed had a beautiful conversation flow. Warm greeting, good scheduling logic, clean handoffs. It was also emailing confirmations into the void roughly a third of the time, because "gmail" had been transcribed as "g mail", "hotmail" as "hot mail", and one caller's surname had been heard four different ways across a two minute call.

Nobody complained. That is the whole problem. Failed capture is silent. The call sounds successful, the transcript reads successful, the dashboard counts it as successful, and the lead never receives anything.

I have written about keeping the call fast, booking against a real calendar and what the agent should know. This is the layer people skip: getting structured, correct data out of a noisy phone line.

Why identifiers are harder than conversation

Speech models are extraordinarily good at language and mediocre at strings. Language has redundancy, so context repairs errors. If the model mishears one word in "can I book my car in for Thursday morning", the sentence still resolves. Identifiers have no redundancy at all. Every character carries information, so a single mistake destroys the whole value, and there is no context to recover it from.

Then add the phone line. Telephony audio is narrowband, and the frequencies it discards are exactly where the consonants that distinguish letters live. "M" and "N", "S" and "F", "B" and "P" are hard for humans on a bad line, which is why the military invented a phonetic alphabet in the first place. Your model is listening through the same pipe.

So capture failures cluster in predictable places: email local parts, surnames, street names, alphanumeric references, postcodes, and any digit sequence spoken quickly.

Rule one: do not ask for what you can already know

The cheapest capture is the one that never happens.

Most inbound calls arrive with caller ID. If that number matches a record in the CRM, the agent should not be asking for a name, an email or a phone number at all. It should be confirming: "I have you as Sarah at 14 Oakfield Road, is that still right?" One yes replaces three risky fields.

On the CallSetter AI work at Tested Media, the same principle applies in reverse for outbound and callbacks. If the lead came from a form fill or a missed call, the record already holds most of the fields. The agent's job on that call is to verify one or two things, not to re-collect a profile that already exists.

Every field you can look up instead of ask removes a failure mode and shortens the call. That is two wins from one decision.

Rule two: collect the minimum the next step needs

Ask what the downstream system genuinely requires to act, and nothing else.

To book an appointment you usually need a name, a callback number and an appointment type. You do not need an email address unless something is actually going to be emailed. You do not need a full postal address unless someone is driving to it. Every optional field is another chance to fail silently, another twenty seconds of call time, and another moment where the caller decides this is taking too long.

I make the client justify each field before it goes in the script. In practice about a third of the fields on a first draft turn out to be there because the old paper form had them.

Rule three: confirm in chunks, not in one long readback

The instinct is to collect everything and read it all back at the end. That is the worst possible design, because a caller listening to a twelve second recital of their own details stops paying attention halfway through and says yes to a wrong digit.

Confirm each identifier as you take it, in chunks small enough to check:

One useful habit: have the agent read letters back phonetically when confirming an unusual spelling, but never demand phonetics from the caller. Asking a customer to spell their name in NATO alphabet is a support-desk experience, not a receptionist one.

Rule four: validate the shape in the pipeline, not in the prompt

Never trust the model to be the validator. Models will happily accept "sarah at gmail" as an email address and pass it on.

Structural validation belongs in the n8n workflows behind the call, where it is code and it is deterministic. What that layer does on every capture:

The agent should be told the result of that check while the caller is still on the line where possible, so a genuinely broken value can be retried once. But the check itself must live in the pipeline.

Rule five: give the repair loop an exit

Two failed attempts at the same field is the signal. A third attempt does not work, it just annoys someone who is now certain the machine is broken.

The ladder I use, in order:

  1. Retry once, differently. Not "sorry, can you repeat that", but a changed strategy: ask for it slower, or in parts, or ask them to spell just the first half.
  2. Switch channel. For emails specifically, the best move is to stop trying. "I will text you a link to confirm your email, is this number good for a text?" A phone number captured by voice is far more reliable than an email captured by voice, and the link collects the email in the medium where people type accurately. This requires the SMS half of the stack to be properly set up, including A2P registration, or the text quietly never arrives.
  3. Use the keypad. DTMF is the honest fallback for pure digit fields such as account numbers, reference numbers and dates of birth. It is not a failure to ask someone to type it, and it is close to error free.
  4. Hand off. If identity or an exact reference is required and voice capture has failed twice, that is a transfer, with everything already captured attached so the human does not start from zero.

The one thing the agent must never do is loop. A repair loop with no exit is the single most common reason a caller hangs up on an otherwise decent agent.

Names are a different problem

Names deserve their own rule because the usual instinct is wrong.

There is no correct spelling the model can infer, transcription accuracy on surnames is much worse than on common words, and accent variation makes it worse still. Building UK agents at Fortell AI for vet clinics and medical practices, name capture was the most consistent source of dirty records.

What works: capture the name as heard, do not fight for character accuracy, and key the record on the phone number instead. The phone number is the reliable identifier. The name is a label for a human to read.

The exception is anywhere the name is the lookup key into a system of record, patient records being the obvious case. There, the correct design is not better name capture, it is a different key entirely: a phone number, a date of birth, a reference number, or a human.

I picked this up building clinical eye-tracking diagnostics at Nystag. If a measurement's confidence is low, you record the confidence alongside the value rather than laundering the uncertainty away. Same thing here. A captured field with a "low confidence, unverified" marker is far more useful to the business than the same field presented as clean data.

Test it where it actually breaks

Standard agent testing uses clear speakers reading tidy values. That is a demo, not a test. The scenarios that find real bugs:

I batch these through the Claude Code and Comet pipeline rather than dialing by hand, and I score per field rather than per call, because a 90 percent success rate on calls can hide a 60 percent success rate on emails.

Then measure it in production. Field-level capture accuracy belongs on the dashboard next to booking rate: what percentage of captured emails were deliverable, what percentage of numbers connected on the first callback attempt. Those two numbers expose a class of failure that no conversation metric will ever show you.

The short version

Conversation quality is what wins the demo. Whether the confirmation email actually arrives is what decides if the client renews.


I build production voice and chat agents on Retell, wired into n8n, GoHighLevel and Twilio, with the capture, CRM and reporting layer behind them actually working. More about my background here, or book a call.

FAQ

Why do AI voice agents get email addresses wrong so often?

Because speech models are built for language and an email address is not language. A sentence has redundancy, so context repairs a misheard word, while an identifier has none: every character carries information and one error destroys the whole value. Telephony makes it worse, since narrowband phone audio cuts off exactly the frequencies that distinguish consonants like M and N or S and F. The practical fixes are to confirm the local part and the domain separately rather than as one string, normalize common mistranscriptions such as 'g mail' in code rather than in the prompt, and after one failed retry stop trying by voice and text the caller a link so they type the address themselves.

Should an AI voice agent use the keypad (DTMF) instead of speech?

For pure digit fields, yes, as a fallback rather than a default. Account numbers, reference numbers and dates of birth are close to error free on the keypad and genuinely risky by voice on a noisy line. The right structure is a ladder: retry once with a changed strategy, then switch channel by texting a link for anything typed like an email, then offer the keypad for digit strings, then transfer to a human with everything already captured attached. What the agent must never do is loop on the same field, because an unbounded repair loop is the most common reason a caller hangs up on an otherwise good agent.

How do you stop bad data from a voice agent reaching the CRM?

By validating structure in the automation layer rather than trusting the model's ears. In the n8n workflows behind the call I normalize first (strip spaces from spoken emails, turn literal 'dot' and 'at' into symbols, format the phone number for the region, re-space postcodes), then shape check against the expected pattern, then correct known near-misses of the top email providers from an explicit list. Crucially, a failed check flags the record instead of blocking it: losing a booking because an optional email was mangled is a far worse outcome than a saved booking with a field marked unverified for a human to fix.

Building something in this space?

I take on AI-agent, automation and product work directly — scoped fast, shipped fast.

Book a discovery call →

Keep reading