A production-ready Smart Appointment REST API for healthcare clinics β built with FastAPI, PostgreSQL, and AI.
| Resource | Link |
|---|---|
| π Live API | https://medibook-api-9xi4.onrender.com |
| π Interactive Docs (Swagger) | https://medibook-api-9xi4.onrender.com/docs |
| β€οΈ Health Check | https://medibook-api-9xi4.onrender.com/health |
MediBook is a backend API that powers a smart healthcare appointment booking system. It allows clinics to manage doctors and availability slots, while patients can book appointments, receive email confirmations, and interact with an AI assistant.
Built as a portfolio project to demonstrate real-world backend engineering skills β async Python, relational database design, JWT authentication, third-party integrations, AI features, and cloud deployment.
- Clinic and patient registration with bcrypt password hashing
- JWT token-based authentication with role separation (clinic vs patient)
- Google OAuth 2.0 login for patients
- Clinics register and manage their own doctors
- Full multi-tenancy β each clinic only sees their own data
- Doctor profiles with specialization, bio, and contact info
- Clinics create available time slots for doctors
- Overlap detection β no double-booking of slots
- Conflict detection β patients can't book two appointments at the same time
- Atomic slot locking β slot marked unavailable in the same DB transaction as booking
- Patients can cancel appointments (slot automatically freed)
- Clinics can update appointment status and add clinical notes
- Confirmation email on booking (human-readable date/time format)
- Cancellation email when appointment is cancelled
- 24-hour reminder emails via Celery background tasks
- Powered by Resend
- Smart Slot Suggester β recommends the best available slot based on patient's medical reason and urgency level
- MediBot β context-aware patient chatbot that knows the patient's appointment history and answers questions about the platform
- Celery + Redis task queue for automated appointment reminders
- Runs every hour, scans for appointments within the next 24 hours
| Layer | Technology | Why |
|---|---|---|
| Framework | FastAPI | Async, fast, auto-docs, modern Python |
| Database | PostgreSQL | Relational data integrity, industry standard |
| ORM | SQLAlchemy 2.0 (async) | Production-grade, type-safe queries |
| Migrations | Alembic | Version-controlled schema changes |
| Authentication | JWT + Google OAuth | Industry standard auth patterns |
| Email | Resend | Simple API, reliable delivery |
| AI | OpenAI GPT-4o-mini | Cost-efficient, powerful reasoning |
| Task Queue | Celery + Redis | Scalable background job processing |
| Deployment | Render | Cloud hosting with PostgreSQL |
| Validation | Pydantic v2 | Request/response validation |
medibook-api/
βββ app/
β βββ main.py # FastAPI app entry point
β βββ core/
β β βββ config.py # Environment settings (Pydantic)
β β βββ security.py # JWT + bcrypt
β β βββ dependencies.py # Auth dependencies
β βββ db/
β β βββ base.py # SQLAlchemy declarative base
β β βββ session.py # Async DB session
β βββ models/ # SQLAlchemy models
β β βββ clinic.py
β β βββ doctor.py
β β βββ patient.py
β β βββ slot.py
β β βββ appointment.py
β βββ schemas/ # Pydantic schemas
β βββ api/v1/endpoints/ # Route handlers
β β βββ auth.py
β β βββ doctors.py
β β βββ slots.py
β β βββ appointments.py
β β βββ ai.py
β βββ services/
β β βββ email_service.py # Resend integration
β β βββ ai_service.py # OpenAI integration
β βββ tasks/
β βββ reminder_tasks.py # Celery background tasks
βββ alembic/ # Database migrations
βββ render.yaml # Render deployment config
βββ requirements.txt
βββ .env.example
- Python 3.11+
- PostgreSQL
- Redis (for Celery)
- Conda or virtualenv
# 1. Clone the repository
git clone https://github.com/CynthiaKaluson/medibook-api.git
cd medibook-api
# 2. Create and activate environment
conda create -n medibook python=3.13
conda activate medibook
# 3. Install dependencies
pip install -r requirements.txt
# 4. Set up environment variables
cp .env.example .env
# Edit .env with your values
# 5. Run database migrations
alembic upgrade head
# 6. Start the server
uvicorn app.main:app --reloadVisit http://localhost:8000/docs for the interactive API documentation.
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/medibook_db
SECRET_KEY=your-secret-key
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
OPENAI_API_KEY=sk-...
RESEND_API_KEY=re_...
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
REDIS_URL=redis://localhost:6379/0
APP_ENV=development| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/v1/auth/clinic/register |
Register a clinic | None |
| POST | /api/v1/auth/clinic/login |
Clinic login β JWT | None |
| POST | /api/v1/auth/patient/register |
Register a patient | None |
| POST | /api/v1/auth/patient/login |
Patient login β JWT | None |
| GET | /api/v1/auth/patient/google |
Google OAuth URL | None |
| GET | /api/v1/auth/patient/google/callback |
Google OAuth callback | None |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/v1/doctors/ |
Create doctor | Clinic JWT |
| GET | /api/v1/doctors/ |
List clinic's doctors | Clinic JWT |
| GET | /api/v1/doctors/{id} |
Get doctor by ID | Clinic JWT |
| DELETE | /api/v1/doctors/{id} |
Delete doctor | Clinic JWT |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/v1/slots/ |
Create time slot | Clinic JWT |
| GET | /api/v1/slots/doctor/{id} |
List available slots | None |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/v1/appointments/ |
Book appointment | Patient JWT |
| GET | /api/v1/appointments/my |
My appointments | Patient JWT |
| PATCH | /api/v1/appointments/{id}/cancel |
Cancel appointment | Patient JWT |
| PATCH | /api/v1/appointments/{id}/status |
Update status/notes | Clinic JWT |
| GET | /api/v1/appointments/clinic/all |
All clinic appointments | Clinic JWT |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/v1/ai/suggest-slot |
AI slot recommendation | Patient JWT |
| POST | /api/v1/ai/chat |
Chat with MediBot | Patient JWT |
curl -X POST https://medibook-api-9xi4.onrender.com/api/v1/appointments/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slot_id": "uuid-here",
"doctor_id": "uuid-here",
"reason": "Annual checkup"
}'curl -X POST https://medibook-api-9xi4.onrender.com/api/v1/ai/suggest-slot \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"doctor_id": "uuid-here",
"reason": "Severe chest pain and difficulty breathing"
}'Response:
{
"suggestion": {
"recommended_slot_id": "uuid-here",
"reason": "Morning slot recommended for severe symptoms requiring prompt evaluation",
"urgency": "high"
},
"doctor": "Dr. Chidi Okeke",
"specialization": "Cardiologist"
}curl -X POST https://medibook-api-9xi4.onrender.com/api/v1/ai/chat \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "What appointments do I have coming up?",
"history": []
}'Response:
{
"response": "You have one upcoming appointment β a routine checkup scheduled for March 20, 2026 at 09:00 AM with Dr. Chidi Okeke (Cardiologist). Would you like to make any changes?",
"patient": "Ada Obi"
}Async everywhere β FastAPI + SQLAlchemy 2.0 async + asyncpg means the API handles concurrent requests without blocking, which is critical for healthcare systems with simultaneous users.
UUID primary keys β All IDs are UUIDs instead of integers, preventing enumeration attacks where an attacker guesses resource IDs.
Transactional slot locking β When a patient books an appointment, the slot is marked unavailable in the same database commit as the appointment creation. This prevents race conditions where two patients book the same slot simultaneously.
Multi-tenancy by design β Every doctor and appointment query is scoped to the authenticated clinic's ID, ensuring clinics never see each other's data.
Non-blocking email β Email failures are caught and logged but never crash the booking flow. Patients get their appointment even if the email service is temporarily down.
**Cynthia Kalu**
Junior Backend Developer
β’ [GitHub](https://github.com/CynthiaKaluson)
β’ [LinkedIn](https://www.linkedin.com/in/cynthia-kalu-okorie/)
This project is licensed under the MIT License.