Inspiration
Every clinic, pharmacy and school district in America already calls you automatically. Those calls play a recording and count a keypress: press 1 to confirm, press 2 to cancel.
There is no button for "I can't come Thursday, my ride fell through - can you do Friday?"
To say that, she has to hang up, call the main line, wait on hold, and hope somebody bilingual picks up. So she doesn't. She doesn't show up either. And the chart says no-show.
28.9 million people in the United States speak English less than "very well" (US Census Bureau, ACS 2024 1-Year Estimates, Table DP02). At a safety-net primary care clinic, patients with limited English proficiency had 32% higher adjusted odds of missing an appointment (J Gen Intern Med, 2023). And when Spanish-preferring patients switched to a Spanish-speaking primary care physician, good glycemic control rose 10 percentage points (JAMA Internal Medicine, 2017).
The problem is not that she cannot be reached. It is that nothing that reaches her can hear her answer, and nothing that speaks for her checks itself first.
What it does
Ringback turns a one-way robocall into a conversation, using nothing but phone calls.
- You click Call the inbox in the browser. That is a real call, placed with the Vonage Client SDK.
- The line answers with a recording notice and asks "Who is this for?" You say a name out loud. Speech recognition matches it against your directory; every person has a language.
- "Say your message now." You speak it in English.
- Claude translates it, back-translates it, and flags anything risky. Then the line reads the back-translation to you, in your own language: "You are about to send..." Press 1 to send, 2 to re-record, 3 to hear the Spanish yourself. Silence cancels.
- Press 1 and her ordinary phone rings. A voice says her name and the message in Spanish. No app, no login, no data plan. "Press 1 if you understood, or speak after the tone."
- She speaks her answer in Spanish. It is transcribed, translated, and rings your browser back - a banner, a ring tone, Answer, and you hear her answer in English.
- The board shows one word per message: sent, delivered, understood, replied, left on voicemail, unsupported language.
Every reminder system stops at delivered. The good ones reach confirmed. This one gets to "Friday morning."
Two things it refuses to do
It will not speak in your name without asking. The read-back gate is not a confirmation dialog, it is the product. When a machine translates emergency-department instructions, the meaning survives 82.5% of the time (Taira et al., J Gen Intern Med, 2021) - about one in six gets it wrong, and the person who would carry that error is the one who cannot check it. So the machine tells you what it is about to say, in your language, and waits.
It will not fake a language it does not have. Vonage text-to-speech covers en-US and es-US end to end. It has no Haitian Creole voice. So a Creole directory entry stops before dialing and says so out loud, rather than reading Creole in a French voice and hoping. On the board that row reads unsupported language. Two languages real, the rest honest.
Why someone would pay for this
This is not a new obligation looking for a budget. Under 45 C.F.R. 92.201(a), implementing Section 1557 of the Affordable Care Act, a covered entity "must take reasonable steps to provide meaningful access to each individual with limited English proficiency," and 92.201(b) requires that assistance be "accurate and timely." An automated call that plays English at someone who speaks none of it, and can accept nothing back but a keypress, is not meaningful access.
The lens I explored: Access
"How could you leverage the API to redefine who gets access to communication?"
The person Ringback is for owns a phone that rings. That is the whole device requirement. No app to install, no account to create, no portal to log into, no data plan, no English to read - and she gets a full two-way conversation, including the part where her answer is what changes the outcome. Access is not only being reached. It is being heard back.
Vonage Voice API features used
Every one of these is load-bearing. Remove any and the loop breaks.
- Client SDK in-app voice - the browser is the sender's phone: "Call the inbox", and the ring-back leg that delivers her reply
- Inbound call + answer webhook, NCCO - the whole IVR is server-generated NCCO
inputwith speech - "Who is this for?" matched against the directory, and the message captureinputwith DTMF - the 1 / 2 / 3 read-back gate, and "press 1 if you understood"talkwith per-language TTS - en-US to the sender, es-US to the recipient, name first- Outbound calls - the delivery leg to her phone, and the ring-back leg to the browser
record+ transcription - fallback capture when live speech recognition returns nothing usable- Advanced machine detection (
detect_beep) - voicemail path, stateleft on voicemail, one retry - Speech
contexthints - directory names and reply vocabulary per language
How I built it
Node.js and TypeScript, one Fastify process. @vonage/server-sdk for NCCO and outbound calls, @vonage/client-sdk for the browser leg. Claude for translation with structured output - one frozen system prompt returning translation, back-translation and flags. SQLite via better-sqlite3, no ORM. The board is static HTML plus a small TypeScript bundle with state pushed over server-sent events. Deployed on Fly.io. 47 unit tests over the state machine and the NCCO scripts.
Challenges I ran into
The recogniser could not hear the name. "Marisol" came back as "Mary Sol", "Maricel", even "merry soul" - and often only in the second or third alternative. Exact-match lookup failed every run. Fixed with a five-tier matcher over all recogniser alternatives (exact, word-in-sentence, despaced, length-aware Levenshtein, per-word) that returns undefined on ambiguity rather than guessing the wrong person.
Replies were being cut in half. endOnSilence: 2 ended the capture on a natural mid-sentence pause - the server had recorded only a fragment. Raising it to 4 with a 30-second maxDuration and per-language vocabulary hints fixed it.
The ring-back was invisible. The Client SDK auto-answered the incoming call instantly, so the most important moment in the product arrived as silence. The board now names the caller, plays a generated ring tone, and offers Answer or Decline.
Speaking English into a Spanish recogniser returns nothing at all, and the first version did nothing with silence, so the call simply ended on her. Now it re-prompts in her language, guarded so a redelivered webhook cannot loop the call.
Accomplishments that I'm proud of
The loop closes. A person with no app, no account and no data plan received a message in her language and answered it in her own words, and those words arrived as speech in a browser on the other side - over the public telephone network, with a machine that checked itself before it spoke in someone else's name.
What I learned
That the interesting problem in machine translation is not accuracy, it is accountability. The read-back gate started as a nicety and became the thing the whole product rests on.
What's next for Ringback
Group broadcast with per-person states; batching routine messages into one call per shift; more live languages (pt-BR and bn-IN are already supported by Vonage TTS and ASR); a PSTN number for the sender as a fallback to the in-app call; a scheduling or EHR hook so the directory is not seeded by hand.
Real calls, real translation, real transcription, real speech recognition. The scenario is staged: the directory is seeded demo data and "Marisol" is a composite played by the builder. Built with AI-assisted coding (Claude Code); the product decisions, the testing, the phone-side verification and the Vonage account are my own.
Built With
- anthropic
- claude
- fastify
- fly.io
- ncco
- node.js
- sqlite
- typescript
- vonage
- vonage-client-sdk
- vonage-voice-api
- webrtc

Log in or sign up for Devpost to join the conversation.