A Deterministic Voice AI for Outbound Lead-Validation Calling, Built on Exotel
By Sameer Joshi
A real-time, bidirectional voice pipeline that dials leads sequentially over the phone network, asks a fixed script, and understands spoken answers with local speech recognition and rule-based matching, with no LLM anywhere in the loop.
Platform
Voice & Telephony
Duration
~1 week, build to verified live call
0
LLM calls in the pipeline
~300ms
Local transcription per answer, GPU production
38s
Full 4-question call, verified live end to end
Project overview
Delivered a fully auditable, zero-LLM voice AI that pre-qualifies leads over real phone calls, verified live end to end in under a week.
Platform
Voice & Telephony
Duration
~1 week, build to verified live call
Type
AI & Voice
Stack
7 technologies
The challenge
GS1 India needed to pre-qualify inbound leads: confirm the caller handles barcode registration, whether their company is already a GS1 member, roughly how many products need barcodes, and whether they want a callback, before handing the lead to a human sales team. Doing that by phone, for every lead, does not scale as a manual process, and the obvious "just add AI" answers all had a catch: commercial voice-AI platforms are typically LLM-driven, which means non-deterministic answers, per-call API cost, and caller audio leaving the premises to a third party, none of which sits well with an auditable qualification script. Telephony compounded the problem: the calling platform's only non-streaming way to capture a spoken answer was record-then-transcribe, which lagged 5 to 20 minutes behind the call, useless for a sequential dialer that needs the next question to depend on the last answer. The platform's real-time bidirectional streaming applet existed but was in Beta, undocumented in places that mattered, and gated behind account verification that hadn't been confirmed to actually apply to it.
Lead pre-qualification by phone was a manual, one-at-a-time human task with no automation path
Commercial voice-AI options are largely LLM-based: not deterministic, not auditable against a fixed script, and they send caller audio off-premises
The calling platform's record-then-transcribe path lags 5 to 20 minutes, incompatible with a live, sequential, question-by-question call flow
The real-time streaming applet needed for live speech was Beta, and its published setup documentation turned out to be wrong in ways that silently kill a call
The telephony account was Trial-tier: outbound dialling to any number other than one pre-registered test line was blocked until KYC, and every test call spent real prepaid balance
What we set out to do
- 01
Let an operator upload a list of numbers and have each one dialled automatically, strictly one live call at a time
- 02
Ask a fixed four-question lead-validation script over a real, bidirectional voice call
- 03
Understand the caller's spoken answer locally: no cloud speech API, no audio leaving the machine
- 04
Store every answer as raw audio, verbatim transcript, and parsed value, so any result can be checked by a human
- 05
Keep a keypad (DTMF) fallback on every question, so a bad line or an unclear answer never loses data
- 06
Guard the telephony account's limited prepaid balance with a hard, un-bypassable cap on batch size
How we solved it
Bidirectional Voice Streaming Over Exotel's Voicebot Applet
Integrated with Exotel's AgentStream (Voicebot) applet, a Beta real-time voice channel that streams the caller's audio in and plays synthesized audio back live, in place of the record-then-transcribe path that was too slow to use. The vendor's own published setup guide described the connection as working the same way in both directions; it doesn't. The outgoing audio silently needed to be formatted differently from the incoming audio, and getting that wrong meant the platform tore the connection down within 1 to 3 seconds with no error, so the caller just heard silence and the call dropped.
Key decision
Trust a real, already-working integration over the vendor's own documentation once that documentation was shown to be wrong
Result
Stable, two-way real-time audio streaming, confirmed on a live outbound call
Natural Turn-Taking, Driven by Voice Activity, Not Timers
Built the conversation flow around real voice activity detection rather than fixed timers, so the system knows when the caller has actually started and finished talking instead of guessing from a clock. A brief pause, roughly 800 milliseconds of quiet, is what tells the system the caller is done answering, and a short cushion at the start of each turn makes sure the caller's first word isn't cut off. A hard limit on how long any single answer can run, plus a no-response timeout, stop one difficult call from stalling the rest of the list.
Key decision
Half-duplex by default; the caller's own barge-in support exists but ships disabled
Result
On the first live call, the bot's own prompt echoed back and was misread as the caller interrupting, looping a mis-transcription of its own voice. Disabling barge-in by default fixed every later call, at the cost of not letting the caller interrupt.
Local Transcription and Rule-Based Answer Matching, No LLM
Every answer is transcribed on-premises using a local speech-recognition engine, running in the background so transcription never interrupts or delays the live call. Because the range of possible answers to each question is small and fixed, the transcript is turned into a value using rules alone: a spoken number is recognised and grouped into the right range, exact phrases are matched with the clearest signal in the sentence winning (so "no, we are new" is read as no, even though "we are" is the longer phrase), and a fuzzy-match fallback catches near-misses, like "yep" heard as "yup." Anything below that confidence level is stored as unclear, with the transcript kept, rather than being guessed.
Key decision
A rules engine over an LLM, because the answer space is closed and every decision needs to be explainable by pointing at one line of the question script
Result
Fully auditable matching with zero API cost and zero added network latency; nothing is ever silently misread
Pre-Rendered Prompts, a DTMF Safety Net, and a Spend Guard
Question audio is synthesized once, offline, with an on-prem TTS engine and cached: the live call path has no text-to-speech dependency or latency at all. Every question also keeps a keypad fallback that resolves to the exact same set of parsed values as the spoken path, so history and export don't need to know which one a caller used. On the operator side, a hard cap on how many numbers a single batch can contain protects the telephony account's limited prepaid balance: an oversized upload is rejected outright, never silently trimmed, so an operator can never believe a full list went out when part of it didn't.
Key decision
Reject oversized batches instead of truncating them
Result
Zero runtime text-to-speech cost, identical results whether the caller spoke or used the keypad, and no way to accidentally under-dial a list without knowing it
Measurable impact
0
LLM calls anywhere in the pipeline
~260-310ms
Local transcription per answer, GPU production
38s
Full 4-question call, verified live end to end
31
Automated tests covering the full call flow
Tech stack
What we learned
For a voice application with a closed, fixed set of possible answers, a deterministic rules engine beat an LLM on every axis that mattered for this POC: it cost nothing per call, added no network round trip, never hallucinated an answer, and, critically for a client validating leads, every single parsed result could be explained by pointing at one line of the question script rather than a model's internal state.
- 01
A simple, rules-based approach is the right tool when the answer space is closed: it is more accurate, faster, cheaper, and fully auditable compared to an LLM in the loop
- 02
Vendor documentation for a Beta telephony feature can be flatly wrong; the fastest way past an undocumented connection bug was comparing notes with someone else's already-working integration, not waiting on a support ticket
- 03
Half-duplex is the safer default on a real phone line until proper echo cancellation exists: a barge-in feature that can't tell your own voice from the caller's causes more harm than having no barge-in at all
- 04
A guardrail that rejects bad input outright is worth more than one that silently truncates it: an operator should never be able to believe a batch went out in full when it didn't
Want a system like this one?
Bring us the problem behind it - the constraint, the load, the deadline. You get an architecture opinion and a cost view from the engineers who built the work on this page, not a sales team.
Prefer we come to you? Fill in the form below.
Tell us where to reach you
Takes under a minute. An engineer reads it, not a lead-scoring tool.
More case studies
Building a Commission-Free QR Menu & Ordering Platform for Independent Restaurants
View case study PropTech & Construction ERPConstructIQ: Multi-Tenant Construction ERP
View case study Field Sales & Location IntelligenceGeofencing & Dwell-Time Verification for Field Sales Coverage
View case studyReady to build something that matters?
We solve problems that don't have Stack Overflow answers. Let's talk.
Book a Discovery Call