A voice AI agent that answers a hospital's appointment line and helps callers book, reschedule, and cancel doctor appointments — built with Retell AI (Conversation Flow Agent), a FastAPI backend, and a PostgreSQL (Neon) database.
Repo: https://github.com/avantikaaa01/cinic-voice-receptionist
Caller (voice)
│
▼
Retell AI — Conversation Flow Agent
• Global Prompt: hospital receptionist persona + response guidelines
• Conversation Flow: Book / Reschedule / Cancel subflows
• Custom Functions (5): find_doctor, check_slots, book_appointment,
reschedule_appointment, cancel_appointment
│ HTTPS POST (JSON, args-only payload)
▼
FastAPI Backend (Python) — deployed on Render
• Pydantic request/response schemas per endpoint
• SQLAlchemy ORM
│
▼
PostgreSQL Database — hosted on Neon
• doctors, patients, slots, appointments tables
| Layer | Technology |
|---|---|
| Voice AI Platform | Retell AI (Conversation Flow Agent) |
| Backend Framework | FastAPI (Python) |
| ORM | SQLAlchemy |
| Database | PostgreSQL (Neon, serverless) |
| Deployment | Render (Web Service, free tier) |
| Function | Endpoint | Required Fields | Purpose |
|---|---|---|---|
find_doctor |
POST /find_doctor |
(optional) specialty, department |
Look up doctors by specialty/department |
check_slots |
POST /check_slots |
doctor_name (optional date) |
List a doctor's open appointment slots |
book_appointment |
POST /book_appointment |
doctor_name, slot_id, patient_name, patient_phone |
Book a slot for a patient |
reschedule_appointment |
POST /reschedule_appointment |
patient_phone, appointment_id, new_slot_id |
Move an existing appointment to a new slot |
cancel_appointment |
POST /cancel_appointment |
patient_phone, appointment_id |
Cancel an existing appointment |
All functions are configured in Retell with "Payload: args only" enabled, so the FastAPI backend receives clean, flat JSON matching its Pydantic models directly (no Retell call-metadata wrapper).
app/
├── __init__.py
├── main.py # FastAPI app + all 5 route handlers
├── models.py # SQLAlchemy models (Doctor, Patient, Slot, Appointment)
├── schemas.py # Pydantic request/response schemas
├── database.py # DB engine/session setup (reads DATABASE_URL)
└── seed_data.py # Seeds 3 doctors + slots across 5 weekdays
- Clone the repo:
git clone https://github.com/avantikaaa01/cinic-voice-receptionist cd cinic-voice-receptionist - Install dependencies:
pip install -r requirements.txt
- Set your database connection (optional — defaults to a local SQLite file if unset):
export DATABASE_URL="postgresql://user:pass@host/dbname?sslmode=require"
- Seed the database:
python -m app.seed_data
- Run the server locally:
uvicorn app.main:app --reload
- Health check:
GET http://localhost:8000/health→{"status": "ok"}
- Backend: Deployed on Render as a Python 3 Web Service, connected to the
mainbranch of this repo. - Database: Hosted on Neon (serverless Postgres).
DATABASE_URLis set as a Render environment variable. - Live backend URL:
https://cinic-voice-receptionist-1.onrender.com
Note: Render's free tier spins down on inactivity; the first request after idle time may take 30–60 seconds to respond while the instance wakes up.
- Agent type: Conversation Flow Agent, built with Retell's Conductor
- Global Prompt defines the receptionist persona, response style (one question per turn, short natural replies), and guardrails (no medical advice; emergencies are redirected to hang up and call emergency services)
- Flow includes dedicated subflows for Book Appointment, Reschedule Appointment, and Cancel Appointment, each chaining the relevant Custom Functions with
wait_for_result: true - Dynamic variables (
doctor_name,slot_id,patient_name,patient_phone,appointment_id, etc.) are captured via extract-variable steps and passed between nodes
See TESTING.md for full test evidence — all 5 backend functions were individually tested against the live Render + Neon deployment, followed by end-to-end conversation testing (text and voice) through Retell.
book_appointmentacceptsdoctor_namebut derives the actual doctor from theslot_id— the name field is not cross-validated against the slot's doctor.- No authentication/authorization on the API endpoints (acceptable for an internal tool-calling backend behind Retell, not exposed as a public API).
- Render free tier cold-start latency (~30-60s) may cause the first call of the day to feel slow.