http://localhost:5000/api
All protected routes require:
Authorization: Bearer <JWT_TOKEN>
POST /auth/login
{
"email": "admin@example.com",
"password": "password123"
}{
"success": true,
"data": {
"token": "jwt_token_here",
"user": {
"id": "user_id",
"role": "admin",
"email": "admin@example.com"
}
}
}GET /users/doctors
Roles: admin
{
"success": true,
"data": {
"doctors": [],
"total": 15, //didn't add pagination yet.
"page": 1,
"pages": 2
}
}POST /users/doctors
Roles: admin
{
"name": "Dr. Smith",
"email": "smith@hospital.com",
"department": "cardiology"
}GET /patients
Roles: admin, receptionist
POST /patients
Roles: admin, receptionist
{
"name": "John Doe",
"age": 30,
"gender": "male",
"phone": "9999999999"
}POST /appointments
Roles: admin, receptionist
{
"doctor": "doctor_id",
"patient": "patient_id",
"date": "2026-02-20T10:00:00Z"
}{
"success": false,
"message": "Doctor already has an appointment at this time"
}PATCH /appointments/:id/status
Roles: admin, doctor
{
"status": "completed"
}POST /billing
Roles: admin
{
"patient": "patient_id",
"amount": 1500
}PATCH /billing/:id/status
Roles: admin, billing
{
"status": "paid",
"paymentMethod": "cash"
}GET /admin/dashboard/summary
Roles: admin
{
"success": true,
"data": {
"totalDoctors": 5,
"totalPatients": 40,
"totalAppointments": 100,
"totalRevenue": 45000,
"pendingRevenue": 5000,
"todayAppointments": 8
}
}GET /reports/revenue
Roles: admin, billing
?startDate=2026-01-01
&endDate=2026-01-31
GET /reports/appointments
Roles: admin
GET /reports/my-summary
Roles: doctor
| Route | Admin | Doctor | Reception | Billing |
|---|---|---|---|---|
| /users/doctors | ✔ | ❌ | ❌ | ❌ |
| /patients | ✔ | ❌ | ✔ | ❌ |
| /appointments | ✔ | ✔ (own) | ✔ | ❌ |
| /billing | ✔ | ❌ | ❌ | ✔ |
| /reports | ✔ | Limited | ❌ | Financial Only |
| /admin/dashboard | ✔ | ❌ | ❌ | ❌ |
Success:
{
"success": true,
"data": {},
"message": "Optional message"
}Error:
{
"success": false,
"message": "Error description"
}- Always send JWT in Authorization header
- Role-based UI must match backend RBAC
- Do not trust frontend-only role checks
- Use pagination parameters for large datasets