Inspiration

In Puerto Rico, getting a specialist appointment can take months. Patients call office after office from their insurance directory, only to hear "we're not taking new patients" or "call back next month." At the same time, those same offices lose appointments every day to cancellations and no-shows, and the staff simply doesn't have time to call around and fill them.

We saw two sides of the same problem: patients waiting with no slot, and slots going empty with no patient. TurnoListo connects them.

What it does

  • Patients talk, not type. A patient taps the mic and says something like "Necesito un cardiólogo en Arecibo, tengo Triple-S." A live AI voice assistant asks one question at a time for anything missing (area, preferred days, referral) and builds an anonymous request. No diagnosis is ever stored.
  • Instant openings, read out loud. As soon as the request is complete, the assistant searches real open slots from registered clinics and reads up to 3 options, closest first, with clinic, town, distance in miles, date and time. The patient says "el número 2" or taps Reservar, and it's booked.
  • Waiting list when nothing is open. If there's no match, the patient joins the waiting list. When a matching slot opens, the patient who has waited longest gets an SMS (or an in-app alert) and has 30 minutes to reply SÍ. If they decline or don't answer, it goes to the next person, and they keep their place in line.
  • Clinics set the plans they accept. In Puerto Rico, not every office accepts every insurance, so each clinic lists its accepted plans and only receives patients it can actually see.
  • Clinics open slots in seconds. At the end of the day, a clerk says "Abre tres turnos el martes de 2 a 4" or uses a simple form.
  • Privacy by design. The clinic sees the patient's name and phone only after a booking. Patient location is never shared, and the AI never sees the patient's name or phone.
  • Cancellations recycle slots. If a patient cancels, the slot is offered to the next person right away. If a clinic cancels, the patient is notified and keeps their original place in line.
  • Fair by design. Clinics never browse or pick patients. A slot $s$ is eligible for request $r$ when

$$ \text{spec}_r = \text{spec}_s,\quad \text{plan}_r \in P_s,\quad \big(\text{region}_r = \text{region}_s \ \lor\ d(r,s) \le 25 \text{ mi}\big) $$

where $P_s$ is the set of plans the office accepts and $d(r,s)$ is the straight-line distance. Instant search ranks eligible slots by distance, then by date. Waitlist offers go to the request that has waited longest:

$$ r^* = \arg\min_{r \in E(s)} t_r $$

where $E(s)$ is the set of eligible waiting requests and $t_r$ is when the request was created.

How we built it

  • SvelteKit 3 + Svelte 5 (runes) + TypeScript + Tailwind CSS v4, deployed on Vercel, with Turso (libSQL) as the database and a local JSON file for development.
  • Gemini Live API powers the real-time voice assistant for both patients and clinics. The browser connects with a short-lived, single-use token minted by our server, so the real API key never leaves the backend.
  • The assistant works through tool calls that our server executes with the user's own session: update_request, find_openings, choose_opening, join_waitlist and publish_slots. The AI can only book real slot IDs returned by our search, so it can't invent a doctor or an appointment.
  • A matching engine handles the instant top-3 search, waitlist offers, 30-minute offer windows, expiry, and cancellations. Slots are re-checked at booking time to prevent double-booking.
  • Twilio sends offers by SMS and receives replies through a webhook. The AI interprets natural replies like "sí, pero más tarde."
  • Distances are calculated from the patient's and clinic's coordinates, falling back to town centers.
  • Rule-based fallbacks for every AI task, so the app still works with no AI key, plus a browser-mic and typed chat fallback.
  • Username sign-in with separate patient and clinic roles. A clinic account can only ever act on its own clinic.

Challenges we ran into

  • Keeping the voice AI inside the system. Live voice models sometimes improvise, for example by suggesting a doctor who isn't registered. We tightened the prompts and made every booking go through real slot IDs, so even if the model says something wrong, it can't book anything that doesn't exist.
  • Secure real-time voice in the browser. Gemini Live connects straight from the browser, so we had to mint single-use, short-lived tokens with the prompt and tools locked in, instead of exposing the API key.
  • Concurrency. Two patients choosing the same opening, an offer expiring mid-reply, or a clinic cancelling during an offer all had to end in exactly one consistent result.
  • Natural Spanish. Puerto Rican town names, accents, and replies like "sí pero a las 2 no puedo" needed careful parsing and validation against fixed lists.
  • Framework changes. SvelteKit 3 had just changed imports (#lib instead of $lib) and tightened its form security rules, which affected the Twilio webhook.
  • Scope. Deciding what to leave out to finish a working prototype in under 48 hours.

Accomplishments that we're proud of

  • A patient can go from speaking one sentence to a booked appointment without typing, and without calling a single office.
  • Privacy that's built into the flow, not added on: no diagnosis stored, identity revealed only after booking, location never shared, and an API key that never reaches the browser.
  • A fair matching system where clinics can't cherry-pick patients by insurance.
  • An AI that stays honest: it only talks about real openings, sends emergencies to 911 / Línea PAS, and never gives medical advice.
  • Everything still works without an AI key, thanks to rule-based fallbacks.

What we learned

  • The hardest part of healthcare access often isn't medicine. It's coordination.
  • AI is most useful here as a translator between how people talk and the structured data systems need, not as a decision-maker.
  • The safest way to control an AI agent is to limit what its tools can do, not just what its prompt says.
  • Privacy decisions are much easier when they shape the design from day one.

What's next for TurnoListo

  • A phone-call voice line for patients without smartphones, so anyone can request an appointment with a regular call.
  • Two-factor sign-in (SMS code) and clinic verification against the NPI registry.
  • HIPAA-compliant hosting and business associate agreements with the AI and SMS providers.
  • Day-based booking for offices that see patients first come, first served, with a daily cap.
  • A patient-chosen maximum distance and driving-time estimates.
  • Partnerships with insurers and provider groups to bring their networks onto the platform. Unmatched requests also become useful data, showing where in Puerto Rico specialist demand isn't being met.

Built With

  • sveltekit
  • turso
Share this project:

Updates

Submission history