Orbit Dental AI: patient acquisition.
Site, dashboard, AI voice agent.

A complete patient-acquisition system for a Toronto dental lead-gen and rewards operation. Three systems shipped: a marketing site with 6 SEO articles, a dashboard tracking leads through a 6-stage funnel, and an AI voice agent that calls and qualifies new leads. The whole thing runs in code, not a no-code tool.

CLIENT
Dental Lead-Gen · Toronto
SCOPE
Site + Dashboard + Voice Agent
SHIPPED
2026 · LIVE
ROLE
Solo · Full build
01 / 06THE PROBLEM

Leads arrive fast. Follow-up was manual.

Facebook Lead Ads bring patients in at volume. The gap was everything after the form: a lead that sits for an hour goes cold. Sending each lead to the right clinic by location, qualifying it, booking, then sending a reward all ran on people and a tangle of no-code triggers.

The brief was to own the whole path in code, from the ad to the text to the AI call to the clinic hand-off to the reward. Three things had to ship: the site that converts the click, the dashboard the operator watches, and the voice agent that runs the qualifying call.

  • Slow follow-up: manual replies let warm leads go cold
  • No single view: lead status was scattered across tools
  • Routing by hand: picking the clinic was a manual lookup
  • No-code sprawl: the automation lived across stacked Zapier steps
  • Compliance: calling and texting had to follow Canada's CASL and CRTC rules
02 / 06SYSTEM 1 · MARKETING SITE

Astro 6 site plus 6 SEO articles.

I rebuilt the brand on a blue #447EF7 scale and moved every line of real copy off the old site. The offer centers an Apple Watch SE 3 rewards hook with a live deadline countdown. An insurance and clinic marquee, a branded link-preview card, a blue favicon set, and an accessibility pass round out the static build on Vercel.

On top of the site sit 6 SEO articles. The topics: dental check-ups, costs and the Canadian Dental Care Plan, choosing a dentist, how often to visit, dental anxiety, and teeth whitening. Each ships with search markup, hand-built on-brand diagrams, and AI-generated hero images.

  • Brand system: blue #447EF7 scale, full copy migration
  • Offer: Apple Watch SE 3 rewards hook, live deadline countdown
  • Polish: insurance and clinic marquee, link-preview card, favicon set, accessibility pass
  • Content: 6 SEO articles, each with search markup
  • Assets: hand-built on-brand diagrams, AI-generated hero images
03 / 06SYSTEM 2 · LEAD-OPS DASHBOARD

A dashboard over the funnel.

A Next.js 16 and React 19 dashboard on Supabase. It shows the lead funnel as 6 stages, with each lead's call history, recording and transcript links, reward status, and which Facebook ad it came from. A sortable, filterable table, CSV export, hourly auto-refresh, and manual reload give the operator one place to watch every lead move.

The operator (admin) sees everything, behind a secure login. Each clinic gets its own login showing only its leads: patient name, phone, email, and stage, with the ability to move a lead forward. Rewards, the text thread, and the activity log stay admin-only. The limits are enforced on the server, not just hidden in the UI: a clinic can only set the stages it owns, and the rest are rejected. An admin-only diagram shows how the phone and text channels run into the clinic and out to reward.

  • Funnel view: all 6 stages shown with a pipeline diagram
  • Access by role: admin sees all; clinic logins see only their leads (name, phone, email, stage), no rewards, no texting, no activity log
  • Limits enforced server-side: a clinic can only change the stages it owns, checked on the server, not just the UI
  • Per-lead detail: call history, recording and transcript links, two-way text thread
  • Attribution: source ad and reward status tracked per lead
  • Operator tools: sortable, filterable, mobile-friendly table, CSV export, auto and manual refresh
  • Security: data access is server-side only, sessions are signed and verified, and the database is locked down by row
Orbit lead-ops dashboard: funnel stat cards across the six stages and the live leads table, showing the stage, whether each lead was handed off by call or text, reward, and clinic. Patient names and phones are blurred.
The live dashboard. Funnel counts across the six stages up top, every lead in one table — stage, whether it was handed off by call or text, reward, and clinic. Patient names and phones are blurred.
Per-lead detail drawer: contact and handed-off-via fields, qualification, and the full call history with the Anna call transcript and a play-recording link. Patient name and phone blurred.
The per-lead drawer. Every lead's qualification, whether it handed off by call or text, and the full call history — the Anna transcript and the recording — read in one place. Name and phone blurred.
Admin-only lifecycle view: the automatic capture-to-hand-off phase, then the manual clinic and Orbit phases, with the full/partial and reward rules.
The admin-only lifecycle view. Automatic from Facebook lead to clinic hand-off, then the manual clinic and Orbit steps the system can't sense.
04 / 06SYSTEM 3 · AI VOICE AGENT

Anna: qualifies by phone and text, all in code.

"Anna" qualifies leads on two channels at once. The voice agent uses Vapi for the call, Claude Haiku for the reasoning, Deepgram Nova-3 to turn speech into text, and ElevenLabs for the voice. The text qualifier runs the same script over SMS, driven by Gemini (gemini-2.5-flash-lite), 24/7. It keeps the conversation going on its own: anyone who replies by text gets followed up until hand-off. Both read and write one shared lead record, so neither re-asks what the other already learned, and the two never fall out of sync.

The behind-the-scenes pieces all run in code on Supabase: intake, a scheduled dialer, a scheduled text follow-up, a handler for call results, a handler for incoming texts, and a clinic-notify mailer. The right clinic is picked from the lead's postal code, and every status change is written to a running log that can't be edited after the fact. A missed call retries an hour later, then the next business day, then two days out, with text qualifying running alongside. After the last retry, calling stops. An incoming text still sends the lead straight to the clinic.

On a qualified lead, Anna transfers the live call to the clinic. If the front desk doesn't pick up, the clinic gets an automatic email (Resend) with the patient's details and the lead gets a "they'll call you back" text. After a completed visit, the patient gets an automatic text asking for a Google review of both the clinic and Orbit. Twilio carries the texts; Giftogram handles the rewards. Anna stays strictly on-script. The Canadian calling rules are built in: consent capture, a 9am-8pm ET calling window (seven days), live transfer only when the clinic front desk is staffed (Mon-Fri 12-4pm ET), and STOP handling.

  • Two channels: phone (Vapi, Claude Haiku, Deepgram, ElevenLabs) and a 24/7 Gemini text qualifier, both working one shared record until hand-off
  • Behind the scenes: code on Supabase for intake, dialer, call results, incoming texts, and the clinic mailer
  • Retries: a missed call retries +1hr, next business day, +2 days, then stops, with text qualifying alongside
  • Live transfer: hand-off to the clinic; on no-answer, an auto email (Resend) plus a callback text to the lead
  • Reviews: a completed visit triggers one Google review request for the clinic and Orbit, sent once and only on confirmed delivery
  • Routing and status: clinic picked from postal code, status changes written to a log that can't be edited after the fact
  • Compliance: consent, a 9am-8pm ET calling window (seven days), STOP handling, strictly on-script

The flow, start to finish: Facebook lead ad to instant text to AI call (text qualifying in parallel) to live clinic hand-off to reward and reviews.

ANNA · ORBIT DENTAL AI 0:00 / 0:34
0:00
AnnaHi Jordan, it's Anna, a virtual assistant calling from Orbit about the promotion you signed up for. Is now an okay time?
CallerYeah, sure.
0:07
0:08
AnnaGreat — first, do you have dental insurance?
CallerYeah, with Sun Life.
0:11
0:13
AnnaPerfect, Sun Life. We've got a few rewards: an Apple Watch, AirPods, or a gift card. Which sounds best to you?
CallerThe Apple Watch.
0:20
0:22
AnnaGreat choice. What city are you in, so I can find your closest clinic?
CallerDowntown Toronto.
0:26
0:27
AnnaPerfect — I'll connect you to our partner clinic now to book your new-patient visit. One moment.
QUALIFIED Sun Life · Apple Watch · Toronto → live-transferred to clinic
Plays as you scroll to it (tap play if your browser holds the audio). Anna's real flow: AI disclosure, insurance, reward, clinic, then a live transfer. Voices are ElevenLabs — Anna's is the exact voice the live agent uses; the call is scripted for the case study, synthetic, no real patient.
System architecture: one Facebook lead into two parallel qualification channels, voice and SMS, over a single shared record, then hand-off, clinic, and reward.
The architecture, admin-only. One lead, two qualification channels in parallel over a single shared record, then hand-off to the clinic and out to reward.
05 / 06THE STACK

Code-first across three systems.

One rule held across all three: keep the automation in code, so it stays easy to debug, easy to test, and free of no-code lock-in. The site, the dashboard, and the voice agent all run on Vercel and Supabase.

Astro 6 Next.js 16 React 19 TypeScript Supabase Edge Functions pg_cron Vapi Claude Haiku Gemini Deepgram ElevenLabs Twilio Giftogram Resend Tailwind Vercel FB Lead Ads API
06 / 06THE OUTCOME

What shipped.

Scope facts from the build, technical only. Business results are the client's to share. The site, dashboard, and voice agent are all live.

SYSTEMS SHIPPED
3
Marketing site, dashboard, AI voice agent. One person, the whole build.
SEO ARTICLES
6
6 SEO articles, each with search markup.
FUNNEL STAGES
6
All 6 lead stages tracked in the dashboard.
ZAPIER FOOTPRINT
1 ZAP
Automation moved into code. One trigger left, the rest is code.
VOICE STACK
4
Vapi, Claude Haiku, Deepgram Nova-3, ElevenLabs. The qualifying caller.
DEPLOY
LIVE
Site, dashboard, and Anna all live. The dialer runs 9am–8pm ET, seven days.

Every lead can be followed from the ad click to the reward. Clinic routing is automatic. The calling window and STOP handling run in code, not on a checklist.

Note: Conversion, lead-volume, and revenue numbers are the client's to disclose and aren't shown here.

View the live site → · View the blog →

Similar work: a funnel to track, a voice agent to build, no-code sprawl to move into code. Discuss the project →