708 lines
14 KiB
Markdown
708 lines
14 KiB
Markdown
# PX360 API Endpoints
|
|
|
|
## Base URL
|
|
```
|
|
http://localhost:8000/api/
|
|
```
|
|
|
|
## Authentication
|
|
|
|
All API endpoints require JWT authentication (except event creation which can use API keys).
|
|
|
|
### Get JWT Token
|
|
```http
|
|
POST /api/auth/token/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"username": "admin",
|
|
"password": "your_password"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
|
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
|
|
}
|
|
```
|
|
|
|
### Refresh Token
|
|
```http
|
|
POST /api/auth/token/refresh/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
|
|
}
|
|
```
|
|
|
|
### Use Token
|
|
```http
|
|
GET /api/auth/users/me/
|
|
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...
|
|
```
|
|
|
|
---
|
|
|
|
## Accounts & Authentication
|
|
|
|
### Users
|
|
|
|
#### List Users
|
|
```http
|
|
GET /api/auth/users/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `is_active` - Filter by active status
|
|
- `hospital` - Filter by hospital UUID
|
|
- `department` - Filter by department UUID
|
|
- `groups` - Filter by role/group
|
|
- `search` - Search by username, email, name, employee_id
|
|
|
|
#### Get Current User
|
|
```http
|
|
GET /api/auth/users/me/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
#### Create User
|
|
```http
|
|
POST /api/auth/users/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"username": "jdoe",
|
|
"email": "jdoe@hospital.sa",
|
|
"password": "SecurePass123!",
|
|
"password_confirm": "SecurePass123!",
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"phone": "+966501234567",
|
|
"hospital": "HOSPITAL_UUID",
|
|
"department": "DEPARTMENT_UUID"
|
|
}
|
|
```
|
|
|
|
#### Update Profile
|
|
```http
|
|
PUT /api/auth/users/update_profile/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"phone": "+966501234567",
|
|
"language": "ar"
|
|
}
|
|
```
|
|
|
|
#### Change Password
|
|
```http
|
|
POST /api/auth/users/change_password/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"old_password": "OldPass123!",
|
|
"new_password": "NewPass123!",
|
|
"new_password_confirm": "NewPass123!"
|
|
}
|
|
```
|
|
|
|
#### Assign Role
|
|
```http
|
|
POST /api/auth/users/{user_id}/assign_role/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"role_id": "ROLE_UUID"
|
|
}
|
|
```
|
|
|
|
### Roles
|
|
|
|
#### List Roles
|
|
```http
|
|
GET /api/auth/roles/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
---
|
|
|
|
## Organizations
|
|
|
|
### Hospitals
|
|
|
|
#### List Hospitals
|
|
```http
|
|
GET /api/organizations/hospitals/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `status` - Filter by status (active, inactive)
|
|
- `city` - Filter by city
|
|
- `search` - Search by name, code
|
|
|
|
#### Create Hospital
|
|
```http
|
|
POST /api/organizations/hospitals/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"name": "AlHammadi Hospital",
|
|
"name_ar": "مستشفى الحمادي",
|
|
"code": "HOSP001",
|
|
"address": "123 Main St",
|
|
"city": "Riyadh",
|
|
"phone": "+966112345678",
|
|
"email": "info@alhammadi.sa",
|
|
"license_number": "LIC123",
|
|
"capacity": 200,
|
|
"status": "active"
|
|
}
|
|
```
|
|
|
|
### Departments
|
|
|
|
#### List Departments
|
|
```http
|
|
GET /api/organizations/departments/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `hospital` - Filter by hospital UUID
|
|
- `parent` - Filter by parent department UUID
|
|
- `status` - Filter by status
|
|
|
|
#### Create Department
|
|
```http
|
|
POST /api/organizations/departments/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"hospital": "HOSPITAL_UUID",
|
|
"name": "Outpatient Department",
|
|
"name_ar": "قسم العيادات الخارجية",
|
|
"code": "DEPT_OPD",
|
|
"parent": null,
|
|
"manager": "USER_UUID",
|
|
"phone": "+966112345679",
|
|
"location": "Building A, Floor 1",
|
|
"status": "active"
|
|
}
|
|
```
|
|
|
|
### Physicians
|
|
|
|
#### List Physicians
|
|
```http
|
|
GET /api/organizations/physicians/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `hospital` - Filter by hospital UUID
|
|
- `department` - Filter by department UUID
|
|
- `specialization` - Filter by specialization
|
|
- `status` - Filter by status
|
|
|
|
#### Create Physician
|
|
```http
|
|
POST /api/organizations/physicians/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"first_name": "Ahmed",
|
|
"last_name": "Al-Saud",
|
|
"first_name_ar": "أحمد",
|
|
"last_name_ar": "السعود",
|
|
"license_number": "PHY001",
|
|
"specialization": "Internal Medicine",
|
|
"hospital": "HOSPITAL_UUID",
|
|
"department": "DEPARTMENT_UUID",
|
|
"phone": "+966501234567",
|
|
"email": "ahmed.alsaud@hospital.sa",
|
|
"status": "active"
|
|
}
|
|
```
|
|
|
|
### Patients
|
|
|
|
#### List Patients
|
|
```http
|
|
GET /api/organizations/patients/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `primary_hospital` - Filter by hospital UUID
|
|
- `gender` - Filter by gender
|
|
- `city` - Filter by city
|
|
- `status` - Filter by status
|
|
- `search` - Search by MRN, name, phone, email
|
|
|
|
#### Create Patient
|
|
```http
|
|
POST /api/organizations/patients/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"mrn": "MRN123456",
|
|
"national_id": "1234567890",
|
|
"first_name": "Mohammed",
|
|
"last_name": "Ali",
|
|
"first_name_ar": "محمد",
|
|
"last_name_ar": "علي",
|
|
"date_of_birth": "1990-01-15",
|
|
"gender": "male",
|
|
"phone": "+966501234567",
|
|
"email": "mohammed.ali@email.com",
|
|
"address": "123 Street, District",
|
|
"city": "Riyadh",
|
|
"primary_hospital": "HOSPITAL_UUID",
|
|
"status": "active"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Journeys
|
|
|
|
### Journey Templates
|
|
|
|
#### List Journey Templates
|
|
```http
|
|
GET /api/journeys/templates/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `journey_type` - Filter by type (ems, inpatient, opd)
|
|
- `hospital` - Filter by hospital UUID
|
|
- `is_active` - Filter by active status
|
|
- `is_default` - Filter by default status
|
|
|
|
#### Create Journey Template
|
|
```http
|
|
POST /api/journeys/templates/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"name": "Standard OPD Journey",
|
|
"name_ar": "رحلة العيادات الخارجية القياسية",
|
|
"journey_type": "opd",
|
|
"description": "Standard outpatient journey",
|
|
"hospital": "HOSPITAL_UUID",
|
|
"is_active": true,
|
|
"is_default": true
|
|
}
|
|
```
|
|
|
|
#### Get Journey Template with Stages
|
|
```http
|
|
GET /api/journeys/templates/{template_id}/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Response includes all stages:**
|
|
```json
|
|
{
|
|
"id": "...",
|
|
"name": "Standard OPD Journey",
|
|
"journey_type": "opd",
|
|
"hospital_name": "AlHammadi Hospital",
|
|
"stages": [
|
|
{
|
|
"id": "...",
|
|
"name": "MD Consultation",
|
|
"order": 1,
|
|
"trigger_event_code": "OPD_VISIT_COMPLETED",
|
|
"auto_send_survey": true,
|
|
"survey_template_name": "MD Consultation Survey"
|
|
},
|
|
{
|
|
"id": "...",
|
|
"name": "Laboratory",
|
|
"order": 2,
|
|
"trigger_event_code": "LAB_ORDER_COMPLETED",
|
|
"auto_send_survey": true,
|
|
"survey_template_name": "Lab Experience Survey"
|
|
}
|
|
],
|
|
"stage_count": 2
|
|
}
|
|
```
|
|
|
|
### Stage Templates
|
|
|
|
#### List Stage Templates
|
|
```http
|
|
GET /api/journeys/stage-templates/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
#### Create Stage Template
|
|
```http
|
|
POST /api/journeys/stage-templates/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"journey_template": "TEMPLATE_UUID",
|
|
"name": "MD Consultation",
|
|
"name_ar": "استشارة الطبيب",
|
|
"code": "OPD_MD_CONSULT",
|
|
"order": 1,
|
|
"trigger_event_code": "OPD_VISIT_COMPLETED",
|
|
"survey_template": "SURVEY_TEMPLATE_UUID",
|
|
"auto_send_survey": true,
|
|
"survey_delay_hours": 2,
|
|
"requires_physician": true,
|
|
"requires_department": true,
|
|
"is_optional": false,
|
|
"is_active": true
|
|
}
|
|
```
|
|
|
|
### Journey Instances
|
|
|
|
#### List Journey Instances
|
|
```http
|
|
GET /api/journeys/instances/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `journey_template` - Filter by template UUID
|
|
- `journey_template__journey_type` - Filter by journey type
|
|
- `patient` - Filter by patient UUID
|
|
- `hospital` - Filter by hospital UUID
|
|
- `status` - Filter by status
|
|
- `search` - Search by encounter_id, patient MRN/name
|
|
|
|
#### Create Journey Instance
|
|
```http
|
|
POST /api/journeys/instances/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"journey_template": "TEMPLATE_UUID",
|
|
"patient": "PATIENT_UUID",
|
|
"encounter_id": "ENC20251214001",
|
|
"hospital": "HOSPITAL_UUID",
|
|
"department": "DEPARTMENT_UUID",
|
|
"metadata": {
|
|
"admission_type": "scheduled",
|
|
"referring_physician": "Dr. Smith"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Note:** Stage instances are automatically created for all active stages in the template.
|
|
|
|
#### Get Journey Progress
|
|
```http
|
|
GET /api/journeys/instances/{instance_id}/progress/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"journey_id": "...",
|
|
"encounter_id": "ENC20251214001",
|
|
"patient": "Mohammed Ali",
|
|
"journey_type": "opd",
|
|
"status": "active",
|
|
"completion_percentage": 50,
|
|
"is_complete": false,
|
|
"started_at": "2025-12-14T09:00:00Z",
|
|
"completed_at": null,
|
|
"stages": [
|
|
{
|
|
"name": "MD Consultation",
|
|
"order": 1,
|
|
"status": "completed",
|
|
"completed_at": "2025-12-14T10:45:00Z",
|
|
"survey_sent": true
|
|
},
|
|
{
|
|
"name": "Laboratory",
|
|
"order": 2,
|
|
"status": "completed",
|
|
"completed_at": "2025-12-14T14:30:00Z",
|
|
"survey_sent": true
|
|
},
|
|
{
|
|
"name": "Radiology",
|
|
"order": 3,
|
|
"status": "pending",
|
|
"completed_at": null,
|
|
"survey_sent": false
|
|
},
|
|
{
|
|
"name": "Pharmacy",
|
|
"order": 4,
|
|
"status": "pending",
|
|
"completed_at": null,
|
|
"survey_sent": false
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Stage Instances
|
|
|
|
#### List Stage Instances
|
|
```http
|
|
GET /api/journeys/stage-instances/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `journey_instance` - Filter by journey instance UUID
|
|
- `stage_template` - Filter by stage template UUID
|
|
- `status` - Filter by status (pending, in_progress, completed, skipped)
|
|
|
|
---
|
|
|
|
## Integrations
|
|
|
|
### Inbound Events
|
|
|
|
#### Create Event (External Systems)
|
|
```http
|
|
POST /api/integrations/events/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"source_system": "his",
|
|
"event_code": "OPD_VISIT_COMPLETED",
|
|
"encounter_id": "ENC20251214001",
|
|
"patient_identifier": "MRN123456",
|
|
"payload_json": {
|
|
"physician_license": "PHY001",
|
|
"department_code": "DEPT_OPD",
|
|
"visit_date": "2025-12-14",
|
|
"visit_time": "10:30:00",
|
|
"timestamp": "2025-12-14T10:45:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"id": "EVENT_UUID",
|
|
"source_system": "his",
|
|
"event_code": "OPD_VISIT_COMPLETED",
|
|
"encounter_id": "ENC20251214001",
|
|
"status": "pending",
|
|
"received_at": "2025-12-14T10:45:01Z"
|
|
}
|
|
```
|
|
|
|
**Note:** Event is queued for async processing by Celery.
|
|
|
|
#### Bulk Create Events
|
|
```http
|
|
POST /api/integrations/events/bulk_create/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"events": [
|
|
{
|
|
"source_system": "his",
|
|
"event_code": "OPD_VISIT_COMPLETED",
|
|
"encounter_id": "ENC001",
|
|
"patient_identifier": "MRN001",
|
|
"payload_json": {...}
|
|
},
|
|
{
|
|
"source_system": "lab",
|
|
"event_code": "LAB_ORDER_COMPLETED",
|
|
"encounter_id": "ENC001",
|
|
"patient_identifier": "MRN001",
|
|
"payload_json": {...}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"created": 2,
|
|
"failed": 0,
|
|
"errors": []
|
|
}
|
|
```
|
|
|
|
#### List Events (PX Admin Only)
|
|
```http
|
|
GET /api/integrations/events/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
**Query Parameters:**
|
|
- `status` - Filter by status (pending, processing, processed, failed, ignored)
|
|
- `source_system` - Filter by source system
|
|
- `event_code` - Filter by event code
|
|
- `encounter_id` - Filter by encounter ID
|
|
|
|
#### Reprocess Failed Event (PX Admin Only)
|
|
```http
|
|
POST /api/integrations/events/{event_id}/reprocess/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
### Integration Configurations (PX Admin Only)
|
|
|
|
#### List Integration Configs
|
|
```http
|
|
GET /api/integrations/configs/
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
#### Create Integration Config
|
|
```http
|
|
POST /api/integrations/configs/
|
|
Authorization: Bearer {token}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"name": "HIS Integration",
|
|
"source_system": "his",
|
|
"description": "Hospital Information System",
|
|
"api_url": "https://his.hospital.sa/api/",
|
|
"api_key": "secret_key_here",
|
|
"is_active": true,
|
|
"config_json": {
|
|
"timeout": 30,
|
|
"retry_attempts": 3
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Common Response Codes
|
|
|
|
- `200 OK` - Success
|
|
- `201 Created` - Resource created
|
|
- `400 Bad Request` - Validation error
|
|
- `401 Unauthorized` - Authentication required
|
|
- `403 Forbidden` - Permission denied
|
|
- `404 Not Found` - Resource not found
|
|
- `500 Internal Server Error` - Server error
|
|
|
|
## Pagination
|
|
|
|
All list endpoints support pagination:
|
|
|
|
```http
|
|
GET /api/organizations/patients/?page=2&page_size=50
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"count": 150,
|
|
"next": "http://localhost:8000/api/organizations/patients/?page=3",
|
|
"previous": "http://localhost:8000/api/organizations/patients/?page=1",
|
|
"results": [...]
|
|
}
|
|
```
|
|
|
|
## Filtering & Search
|
|
|
|
### Filtering
|
|
```http
|
|
GET /api/journeys/instances/?status=active&hospital=HOSPITAL_UUID
|
|
```
|
|
|
|
### Search
|
|
```http
|
|
GET /api/organizations/patients/?search=mohammed
|
|
```
|
|
|
|
### Ordering
|
|
```http
|
|
GET /api/journeys/instances/?ordering=-started_at
|
|
```
|
|
|
|
## Error Responses
|
|
|
|
### Validation Error
|
|
```json
|
|
{
|
|
"field_name": [
|
|
"This field is required."
|
|
]
|
|
}
|
|
```
|
|
|
|
### Permission Denied
|
|
```json
|
|
{
|
|
"detail": "You do not have permission to perform this action."
|
|
}
|
|
```
|
|
|
|
### Not Found
|
|
```json
|
|
{
|
|
"detail": "Not found."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Interactive Documentation
|
|
|
|
For interactive API documentation with try-it-out functionality:
|
|
|
|
- **Swagger UI:** http://localhost:8000/api/docs/
|
|
- **ReDoc:** http://localhost:8000/api/redoc/
|
|
- **OpenAPI Schema:** http://localhost:8000/api/schema/
|
|
|
|
---
|
|
|
|
## Rate Limiting
|
|
|
|
**TODO:** Implement rate limiting for:
|
|
- Event creation endpoint: 1000 requests/hour per source system
|
|
- Authentication endpoint: 10 requests/minute per IP
|
|
- Other endpoints: 100 requests/minute per user
|
|
|
|
---
|
|
|
|
## Webhooks (Future)
|
|
|
|
**TODO:** Implement webhooks for:
|
|
- Journey completion
|
|
- Survey completion
|
|
- Action creation
|
|
- SLA breach
|
|
|
|
---
|
|
|
|
**Last Updated:** December 14, 2025
|