Inspiration

Walk into any primary care clinic at 8 a.m. and the voicemail light is already blinking. Refill requests, "can I move my Thursday appointment," messages for the doctor — dozens of them, each requiring a staff member to pull a chart, check insurance, decide, act, and call back.

The burden is well-documented: physicians spend only 27% of their day on direct patient care versus 49% on EHR and desk work — roughly two hours of administrative work for every hour with patients (Sinsky et al., Annals of Internal Medicine, 2016). Administrative activity accounts for an estimated 25% of U.S. hospital costs (Himmelstein et al., Health Affairs, 2014).

Here's the insight that started Otomedi: most of these voicemails are routine and mechanically verifiable. Whether a refill is allowed, whether a slot is open, whether insurance is accepted — these are checks against data, not judgment calls. The genuinely hard cases ("chest pain") are the minority. So why is a human doing all of it by hand?

¹ Sinsky C, et al. "Allocation of Physician Time in Ambulatory Practice: A Time and Motion Study in 4 Specialties." Annals of Internal Medicine, 2016. doi:10.7326/M16-0961. ² Himmelstein DU, et al. "A Comparison of Hospital Administrative Costs in Eight Nations." Health Affairs, 2014. doi:10.1377/hlthaff.2013.1327.

What it does

Otomedi turns a clinic's voicemails into a one-click approval queue.

Voicemail → Transcription → Eligibility checks → Proposed action → One human click → Patient confirmation
  1. A patient leaves a voicemail. It's transcribed automatically.
  2. An intake agent extracts the structured request — who, what, insurance, preferred times.
  3. Eligibility agents verify against the patient's record: insurance acceptance, visit recency, dosage match, drug conflicts, schedule availability.
  4. The system produces a concrete proposed action ("Refill Lisinopril 10mg, send to pharmacy") and routes the task:
    • Clear → ready to approve with one click
    • ⚠️ Iffy (e.g. last visit > 6 months ago) → flagged for judgment, with full context surfaced
    • 🚨 Emergency (e.g. "chest pain") → escalated immediately, bypasses automation entirely
  5. A certified health worker reviews and approves in one click. Otomedi then executes: writes the prescription, books the appointment, or relays the message to the provider's inbox — and texts the patient a confirmation.

Rejected items get an auto-sent "please call us" text. Everything is logged for audit. A human is always the approver — Otomedi does the legwork, not the deciding.

How we built it

Otomedi is built as a plugin to the EHRs clinics already use, not a replacement.

Claude Code was the primary development environment and orchestration engine throughout the build. We used it to scaffold the multi-agent pipeline, iterate on the eligibility logic, and wire together the full stack under time pressure. The agents themselves run on Claude's API: the intake agent parses raw transcripts into structured requests, the eligibility agents reason over patient record fields to produce a proposed action and a triage classification, and the message relay agent composes provider-inbox notes from unstructured voicemail content. Tasks that don't fit a known pattern are flagged rather than guessed — a behavior we prompted and tested explicitly with Claude.

  • Speech & intake — Deepgram for speech-to-text; Claude (intake agent) for structured extraction and emergency classification
  • Orchestrator (Python) — routes each voicemail through type-specific eligibility gates (prescription / scheduling / message relay); Claude agents handle the reasoning at each gate
  • Backend (FastAPI) — single source of truth and the only holder of DB credentials; exposes one decision executor that dispatches approved actions and chains the confirmation SMS
  • CHW dashboard (Next.js / React / Tailwind) — review queue, history log, one-click decisions; talks only to the backend over HTTP with no DB credentials in the frontend
  • berkapp — a mock eClinicalWorks-style EHR reading the same database, so an approved refill or relayed message appears in the chart and provider inbox automatically, closing the loop end-to-end

Challenges we ran into

Three correctness problems we had to solve — not paper over:

  • Idempotency. An early double-approve inserted two prescriptions. We added a guard so any already-completed task is a no-op.
  • Credential separation. Our first version had the frontend writing directly to the database — a service-role key living in a web app. We re-architected so the backend owns all reads and writes and the dashboard holds no credentials.
  • Schema alignment. Live tables didn't match our mental model (patient names were joined, not stored on tasks; audit columns were missing). We aligned the data model to reality so wiring became a thin mapping layer.
  • Safe human-in-the-loop. It's tempting to fully automate. We deliberately built the opposite: emergencies bypass automation, "iffy" cases demand judgment, and nothing clinical executes without a person's click.
  • Reproducible demo. Testing against a shared database kept dirtying the data. We built a snapshot-based reset so any scenario reruns cleanly.

Accomplishments that we're proud of

  • A working end-to-end pipeline: voicemail → transcription → eligibility → review → one-click execution → patient confirmation → reflected in the EHR
  • Safety-first triage that correctly separates routine work from emergencies across every demo scenario we tested
  • A clean architecture with one executor and a backend as the single source of truth — no duplicated logic, no credentials in the frontend
  • A polished, accessible dashboard themed to feel like a native part of the EHR

What we learned

Automation in healthcare is about trust, not just throughput. The product only works if the worker can approve in one glance and believe the escalation logic has their back.

The boring infrastructure decisions matter most. Idempotency, a single source of truth, and a clean data contract made the demo solid — more than any single feature.

The right unit of automation is the check, not the decision. Agents verify; humans decide. That's what makes this both fast and safe.

The payoff

At conservative inputs (40 voicemails/day, 70% routine, 4 minutes saved per task), Otomedi recovers roughly 1.9 staff-hours per clinic per day. Over a 250-day working year at a median medical-assistant wage (~$20/hr), that's ~$9,500 recovered per clinic annually — before counting faster turnaround for patients.

What's next for Otomedi

The three request types in this build — refills, reschedules, message relays — are the beachhead. The real mission: become the automation layer for every routine, verifiable front-desk task, so staff spend their time on people instead of paperwork.

  • Expand the playbook: prior-auth follow-ups, lab-result callbacks, referral coordination, billing questions — anything checkable against the record
  • Configurable eligibility engine: clinic-defined rules (controlled substances, visit intervals, payer policies) without code changes
  • Confidence scoring: transparent explanations for every routing decision, so the CHW always knows why a task was flagged
  • A learning loop: CHW approve/reject decisions tune the eligibility gates to each clinic's real-world patterns
  • Production EHR integrations: Epic, eClinicalWorks, athenahealth via native APIs — no rip-and-replace
  • Multi-request handling: one voicemail asking for a refill and a message → two separately approvable tasks
  • Multi-channel intake: patient portal messages, texts, web forms — one queue for every inbound request

Built With

Share this project:

Updates