748 lines
19 KiB
Markdown
748 lines
19 KiB
Markdown
# PX360 External API Documentation
|
|
|
|
Base URL: `/api/v1/external/`
|
|
|
|
## Authentication
|
|
|
|
All requests require an `X-API-Key` header.
|
|
|
|
```
|
|
X-API-Key: <your-api-key>
|
|
```
|
|
|
|
API keys are managed through the Django admin panel. Each key can be scoped to:
|
|
|
|
- A specific hospital (restricts data access to that hospital)
|
|
- Specific entities (`complaints`, `inquiries`, `observations`, `appreciations`, `suggestions`, `doctor_ratings`)
|
|
- Empty `allowed_entities` = access to all entities
|
|
|
|
### Creating an API Key
|
|
|
|
Via Django admin or programmatically:
|
|
|
|
```python
|
|
from apps.integrations.models import ExternalAPIKey
|
|
|
|
api_key, raw_key = ExternalAPIKey.create_key(
|
|
name="Partner Integration",
|
|
hospital=hospital_object, # Optional: scope to a hospital
|
|
allowed_entities=["complaints", "inquiries"], # Optional: empty = all
|
|
rate_limit=60, # Requests per minute
|
|
description="Integration with partner system",
|
|
)
|
|
# raw_key is shown ONCE - store it securely
|
|
```
|
|
|
|
### Error Responses
|
|
|
|
| HTTP Status | Meaning |
|
|
|---|---|
|
|
| `401` | Missing or invalid API key |
|
|
| `403` | API key does not have access to the requested entity, or hospital scope mismatch |
|
|
| `404` | Requested resource not found |
|
|
| `400` | Validation error (missing/invalid fields) |
|
|
|
|
---
|
|
|
|
## Lookup Endpoints
|
|
|
|
These endpoints provide dropdown/reference data for building forms.
|
|
|
|
### List Hospitals
|
|
|
|
```
|
|
GET /api/v1/external/hospitals/
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"count": 3,
|
|
"results": [
|
|
{ "id": "uuid", "name": "Al Nuzha", "code": "HH-N" },
|
|
{ "id": "uuid", "name": "Al Olya", "code": "HH-A" },
|
|
{ "id": "uuid", "name": "Al Suwaidi", "code": "HH-S" }
|
|
]
|
|
}
|
|
```
|
|
|
|
### List Location Types
|
|
|
|
```
|
|
GET /api/v1/external/location-types/
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"count": 4,
|
|
"results": [
|
|
{ "value": "OP", "label": "Outpatient", "label_ar": "خارجي" },
|
|
{ "value": "IP", "label": "Inpatient", "label_ar": "تنويم" },
|
|
{ "value": "ER", "label": "Emergency", "label_ar": "طوارئ" },
|
|
{ "value": "GENERAL", "label": "General", "label_ar": "عام" }
|
|
]
|
|
}
|
|
```
|
|
|
|
### List Areas
|
|
|
|
```
|
|
GET /api/v1/external/areas/?hospital=<hospital_name>
|
|
```
|
|
|
|
| Parameter | Required | Description |
|
|
|---|---|---|
|
|
| `hospital` | Yes | Hospital name (case-insensitive) |
|
|
| `location_type` | No | Filter by location type (`OP`, `IP`, `ER`, `GENERAL`) |
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"count": 27,
|
|
"results": [
|
|
{ "id": "uuid", "name": "Emergency", "name_ar": "", "code": "emergency" }
|
|
]
|
|
}
|
|
```
|
|
|
|
### List Departments
|
|
|
|
```
|
|
GET /api/v1/external/departments/?hospital=<hospital_name>
|
|
```
|
|
|
|
| Parameter | Required | Description |
|
|
|---|---|---|
|
|
| `hospital` | Yes | Hospital name (case-insensitive) |
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"count": 37,
|
|
"results": [
|
|
{ "id": "uuid", "name": "Critical Care Department", "name_en": "Critical Care Department", "name_ar": "", "code": "hh_n_critical_care_department" }
|
|
]
|
|
}
|
|
```
|
|
|
|
### List Sections
|
|
|
|
```
|
|
GET /api/v1/external/sections/?hospital=<hospital_name>&department=<department_name>
|
|
```
|
|
|
|
| Parameter | Required | Description |
|
|
|---|---|---|
|
|
| `hospital` | Yes | Hospital name (case-insensitive) |
|
|
| `department` | Yes | Department name (case-insensitive) |
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"count": 3,
|
|
"results": [
|
|
{ "id": "uuid", "name": "ICU", "name_ar": "", "code": "hh_n_critical_care_department__icu" }
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Complaints
|
|
|
|
### Create a Complaint
|
|
|
|
```
|
|
POST /api/v1/external/complaints/
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
| Field | Required | Type | Description |
|
|
|---|---|---|---|
|
|
| `hospital` | Yes | string | Hospital name (case-insensitive) |
|
|
| `title` | Yes | string | Complaint title (max 500 chars) |
|
|
| `description` | Yes | string | Detailed complaint description |
|
|
| `contact_name` | Yes | string | Reporter's name (max 200 chars) |
|
|
| `contact_phone` | Yes | string | Reporter's phone (max 20 chars) |
|
|
| `contact_email` | No | string | Reporter's email |
|
|
| `relation_to_patient` | No | string | One of: `patient`, `relative`, `friend`, `other` |
|
|
| `patient_name` | No | string | Patient name |
|
|
| `national_id` | No | string | National ID number |
|
|
| `incident_date` | No | date | Date of incident (`YYYY-MM-DD`) |
|
|
| `expected_result` | No | string | Expected resolution |
|
|
| `location_type` | No | string | One of: `OP`, `IP`, `ER`, `GENERAL` |
|
|
| `area` | No | string | Area name (resolved by hospital) |
|
|
| `department` | No | string | Department name (resolved by hospital) |
|
|
| `section` | No | string | Section name (requires department) |
|
|
|
|
**Example:**
|
|
|
|
```json
|
|
{
|
|
"hospital": "Al Nuzha",
|
|
"title": "Long wait time in ER",
|
|
"description": "I waited 3 hours in the emergency room without being seen.",
|
|
"contact_name": "John Doe",
|
|
"contact_phone": "+966501234567",
|
|
"contact_email": "john@example.com",
|
|
"location_type": "ER",
|
|
"area": "Emergency",
|
|
"department": "Critical Care Department",
|
|
"section": "ICU"
|
|
}
|
|
```
|
|
|
|
**Response (201):**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"reference_number": "CMP-20260609-167152",
|
|
"status": "open"
|
|
}
|
|
```
|
|
|
|
### List Complaints
|
|
|
|
```
|
|
GET /api/v1/external/complaints/list/
|
|
```
|
|
|
|
| Parameter | Required | Description |
|
|
|---|---|---|
|
|
| `page` | No | Page number (default: 1) |
|
|
| `page_size` | No | Items per page (default: 20, max: 100) |
|
|
| `created_from` | No | Filter by created date from (`YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS`) |
|
|
| `created_to` | No | Filter by created date to (date-only values auto-extend to end of day) |
|
|
| `updated_from` | No | Filter by updated date from |
|
|
| `updated_to` | No | Filter by updated date to |
|
|
| `status` | No | Filter by status value |
|
|
|
|
### Retrieve a Complaint
|
|
|
|
```
|
|
GET /api/v1/external/complaints/<reference_number>/
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"reference_number": "CMP-20260609-167152",
|
|
"title": "Long wait time in ER",
|
|
"description": "I waited 3 hours...",
|
|
"status": "open",
|
|
"severity": "medium",
|
|
"priority": "medium",
|
|
"contact_name": "John Doe",
|
|
"contact_phone": "+966501234567",
|
|
"contact_email": "john@example.com",
|
|
"relation_to_patient": "",
|
|
"patient_name": "",
|
|
"incident_date": null,
|
|
"expected_result": "",
|
|
"resolution": "",
|
|
"satisfaction": "",
|
|
"hospital_name": "Al Nuzha",
|
|
"created_at": "2026-06-09T13:38:03.808618+03:00",
|
|
"updated_at": "2026-06-09T13:38:03.808683+03:00"
|
|
}
|
|
```
|
|
|
|
#### Resolution & Satisfaction Fields
|
|
|
|
| Field | Description |
|
|
|---|---|
|
|
| `resolution` | Free-text description of the resolution taken (empty if unresolved) |
|
|
| `satisfaction` | Patient satisfaction: `satisfied`, `neutral`, `dissatisfied`, `no_response`, or empty |
|
|
|
|
### Set Patient Satisfaction
|
|
|
|
Sets the patient satisfaction level for a complaint. **A resolution must be recorded first** — returns `400` if the complaint has no resolution.
|
|
|
|
```
|
|
PATCH /api/v1/external/complaints/<reference_number>/satisfaction/
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
| Field | Required | Type | Description |
|
|
|---|---|---|---|
|
|
| `satisfaction` | Yes | string | One of: `satisfied`, `neutral`, `dissatisfied`, `no_response` |
|
|
|
|
**Example:**
|
|
|
|
```json
|
|
{
|
|
"satisfaction": "satisfied"
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"reference_number": "CMP-20260609-167152",
|
|
"satisfaction": "satisfied"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Inquiries
|
|
|
|
### Create an Inquiry
|
|
|
|
```
|
|
POST /api/v1/external/inquiries/
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
| Field | Required | Type | Description |
|
|
|---|---|---|---|
|
|
| `hospital` | Yes | string | Hospital name |
|
|
| `subject` | Yes | string | Inquiry subject (max 500 chars) |
|
|
| `message` | Yes | string | Inquiry message |
|
|
| `contact_name` | Yes | string | Contact name |
|
|
| `contact_phone` | Yes | string | Contact phone |
|
|
| `contact_email` | No | string | Contact email |
|
|
| `category` | No | string | One of: `appointment`, `billing`, `medical_records`, `general`, `other` |
|
|
| `location_type` | No | string | One of: `OP`, `IP`, `ER`, `GENERAL` |
|
|
| `area` | No | string | Area name |
|
|
| `department` | No | string | Department name |
|
|
| `section` | No | string | Section name (requires department) |
|
|
|
|
**Response (201):**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"reference_number": "INQ-20260609-124293",
|
|
"status": "open"
|
|
}
|
|
```
|
|
|
|
### List / Retrieve Inquiries
|
|
|
|
```
|
|
GET /api/v1/external/inquiries/list/
|
|
GET /api/v1/external/inquiries/<reference_number>/
|
|
```
|
|
|
|
Same pagination and date/status filters as complaints.
|
|
|
|
**Retrieve Response:**
|
|
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"reference_number": "INQ-20260609-124293",
|
|
"subject": "Appointment rescheduling",
|
|
"message": "I need to reschedule my cardiology appointment.",
|
|
"category": "appointment",
|
|
"status": "open",
|
|
"contact_name": "Jane Smith",
|
|
"contact_phone": "+966509876543",
|
|
"contact_email": "jane@example.com",
|
|
"hospital_name": "Al Nuzha",
|
|
"created_at": "2026-06-09T13:36:22.730962+03:00",
|
|
"updated_at": "2026-06-09T13:36:22.731020+03:00"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Observations
|
|
|
|
### Create an Observation
|
|
|
|
```
|
|
POST /api/v1/external/observations/
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
| Field | Required | Type | Description |
|
|
|---|---|---|---|
|
|
| `hospital` | Yes | string | Hospital name |
|
|
| `description` | Yes | string | Observation description |
|
|
| `title` | No | string | Title (max 300 chars) |
|
|
| `severity` | No | string | One of: `low`, `medium`, `high`, `critical` (default: `medium`) |
|
|
| `category` | No | UUID | Observation category UUID |
|
|
| `location_text` | No | string | Free-text location description |
|
|
| `incident_datetime` | No | datetime | When the incident occurred |
|
|
| `contact_name` | No | string | Reporter name (anonymous supported) |
|
|
| `contact_phone` | No | string | Reporter phone |
|
|
| `contact_email` | No | string | Reporter email |
|
|
| `reporter_staff_id` | No | string | Staff ID of reporter |
|
|
| `patient_file_number` | No | string | Patient file number |
|
|
|
|
**Response (201):**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"reference_number": "OBS-O8TCIC",
|
|
"status": "new"
|
|
}
|
|
```
|
|
|
|
### List / Retrieve Observations
|
|
|
|
```
|
|
GET /api/v1/external/observations/list/
|
|
GET /api/v1/external/observations/<tracking_code>/
|
|
```
|
|
|
|
**Retrieve Response:**
|
|
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"reference_number": "OBS-O8TCIC",
|
|
"title": "",
|
|
"description": "Wet floor near the main entrance, no warning sign posted.",
|
|
"severity": "medium",
|
|
"status": "new",
|
|
"location_text": "Main entrance lobby",
|
|
"incident_datetime": "2026-06-09T13:36:23.542046+03:00",
|
|
"contact_name": "Anonymous Reporter",
|
|
"contact_phone": "",
|
|
"contact_email": "",
|
|
"reporter_staff_id": "",
|
|
"patient_file_number": "",
|
|
"hospital_name": "Al Nuzha",
|
|
"category_name": null,
|
|
"created_at": "2026-06-09T13:36:23.540024+03:00",
|
|
"updated_at": "2026-06-09T13:36:23.540079+03:00"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Appreciations
|
|
|
|
### Create an Appreciation
|
|
|
|
```
|
|
POST /api/v1/external/appreciations/
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
| Field | Required | Type | Description |
|
|
|---|---|---|---|
|
|
| `hospital` | Yes | string | Hospital name |
|
|
| `message` | Yes | string | Appreciation message |
|
|
| `contact_name` | Yes | string | Submitter name |
|
|
| `contact_phone` | Yes | string | Submitter phone |
|
|
|
|
**Response (201):**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"reference_number": "APR-202607-0001",
|
|
"status": "draft"
|
|
}
|
|
```
|
|
|
|
### List / Retrieve Appreciations
|
|
|
|
```
|
|
GET /api/v1/external/appreciations/list/
|
|
GET /api/v1/external/appreciations/<reference_number>/
|
|
```
|
|
|
|
**Retrieve Response:**
|
|
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"reference_number": "APR-202607-0001",
|
|
"message_en": "Dr. Ahmed was incredibly kind and thorough.",
|
|
"status": "draft",
|
|
"hospital_name": "Al Nuzha",
|
|
"is_anonymous": false,
|
|
"created_at": "2026-06-09T13:36:23.788028+03:00",
|
|
"updated_at": "2026-06-09T13:36:23.788077+03:00"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Suggestions
|
|
|
|
### Create a Suggestion
|
|
|
|
```
|
|
POST /api/v1/external/suggestions/
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
| Field | Required | Type | Description |
|
|
|---|---|---|---|
|
|
| `hospital` | Yes | string | Hospital name |
|
|
| `message` | Yes | string | Suggestion message |
|
|
| `contact_name` | Yes | string | Submitter name |
|
|
| `contact_phone` | Yes | string | Submitter phone |
|
|
| `title` | No | string | Title (auto-generated from message if omitted) |
|
|
| `category` | No | string | One of: `clinical_care`, `staff_service`, `facility`, `communication`, `appointment`, `billing`, `food_service`, `cleanliness`, `technology`, `general`, `other` |
|
|
| `rating` | No | integer | Rating 1-5 |
|
|
|
|
**Response (201):**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"reference_number": "SGT-202607-0001",
|
|
"status": "submitted"
|
|
}
|
|
```
|
|
|
|
### List / Retrieve Suggestions
|
|
|
|
```
|
|
GET /api/v1/external/suggestions/list/
|
|
GET /api/v1/external/suggestions/<reference_number>/
|
|
```
|
|
|
|
**Retrieve Response:**
|
|
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"reference_number": "SGT-202607-0001",
|
|
"title": "Digital queue system",
|
|
"message": "Please implement a digital queue management system.",
|
|
"category": "technology",
|
|
"rating": null,
|
|
"status": "submitted",
|
|
"feedback_type": "suggestion",
|
|
"sentiment": "neutral",
|
|
"contact_name": "Suggestor",
|
|
"contact_phone": "+966504445566",
|
|
"hospital_name": "Al Nuzha",
|
|
"created_at": "2026-06-09T13:36:24.051998+03:00",
|
|
"updated_at": "2026-06-09T13:36:24.052047+03:00"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Doctor Ratings
|
|
|
|
### Submit a Doctor Rating
|
|
|
|
Submit a patient rating for a doctor. The `doctor_id` should identify the doctor (existing staff matched by employee ID, license number, or name; otherwise a new Staff record is auto-created — see below).
|
|
|
|
```
|
|
POST /api/v1/external/doctor-ratings/
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
| Field | Required | Type | Description |
|
|
|---|---|---|---|
|
|
| `hospital` | Yes | string | Hospital name (case-insensitive) |
|
|
| `doctor_id` | Yes | string | Doctor's employee ID |
|
|
| `rating` | Yes | integer | Rating from 1 to 5 |
|
|
| `doctor_name` | Conditional | string | Doctor name. Required when `doctor_id` does not match an existing staff record (see auto-creation below). Otherwise stored for reference. |
|
|
| `feedback` | No | string | Patient feedback text |
|
|
| `rating_date` | No | date | Date of rating (`YYYY-MM-DD`, defaults to current date) |
|
|
| `patient_uhid` | No | string | Patient unique health ID |
|
|
| `patient_name` | No | string | Patient name |
|
|
| `patient_type` | No | string | One of: `IP`, `OP`, `ER`, `DC` |
|
|
| `department_name` | No | string | Department name |
|
|
| `admit_date` | No | date | Admission date (`YYYY-MM-DD`) |
|
|
| `discharge_date` | No | date | Discharge date (`YYYY-MM-DD`) |
|
|
|
|
**Staff lookup & auto-creation:** When a rating is submitted, the server looks up the doctor by (in order) `employee_id`, `license_number`, then `doctor_name` (exact / contains / first+last name split). If no existing staff is matched, a new Staff record is **auto-created** with `staff_type=physician`, `job_title="Physician"`, `employee_id=doctor_id`, and the provided name. In that case `doctor_name` is required; omitting it returns `400`. The auto-creation is logged as an `external_staff_auto_created` audit event.
|
|
|
|
**Example:**
|
|
|
|
```json
|
|
{
|
|
"hospital": "Al Nuzha",
|
|
"doctor_id": "10738",
|
|
"doctor_name": "Dr. Omaymah Yaqoub",
|
|
"rating": 4,
|
|
"feedback": "Great doctor, very caring and attentive.",
|
|
"rating_date": "2026-06-10",
|
|
"patient_uhid": "UHID12345",
|
|
"patient_name": "Ahmed Ali",
|
|
"patient_type": "OP",
|
|
"department_name": "Internal Medicine"
|
|
}
|
|
```
|
|
|
|
**Response (201):**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"rating_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
|
"rating": 4
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| HTTP Status | Condition |
|
|
|---|---|
|
|
| `400` | `doctor_id` matches no existing staff AND `doctor_name` is missing (cannot auto-create) |
|
|
| `400` | `rating` outside 1-5 range |
|
|
| `400` | `hospital` not found |
|
|
| `403` | Hospital does not match API key scope |
|
|
|
|
**Error Example (cannot auto-create without a name):**
|
|
|
|
```json
|
|
{
|
|
"doctor_name": [
|
|
"Staff not found for this doctor_id; provide doctor_name to auto-create the staff record."
|
|
]
|
|
}
|
|
```
|
|
|
|
### List Doctor Ratings
|
|
|
|
Returns a paginated list of doctor ratings, scoped to the API key's hospital.
|
|
|
|
```
|
|
GET /api/v1/external/doctor-ratings/list/
|
|
```
|
|
|
|
**Query Parameters (all optional):**
|
|
|
|
| Parameter | Description |
|
|
|---|---|
|
|
| `doctor_id` | Filter by HIS employee ID (exact match) |
|
|
| `rating` | Filter by rating value 1-5 (exact match) |
|
|
| `rating_from` | Rating-date lower bound (`YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS`) |
|
|
| `rating_to` | Rating-date upper bound (`YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS`) |
|
|
| `created_from` / `created_to` | Created-at date range |
|
|
| `updated_from` / `updated_to` | Updated-at date range |
|
|
| `page` | Page number (default `1`) |
|
|
| `page_size` | Page size (default `20`, max `100`) |
|
|
|
|
**Response (200):**
|
|
|
|
```json
|
|
{
|
|
"count": 42,
|
|
"page": 1,
|
|
"page_size": 20,
|
|
"results": [
|
|
{
|
|
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
|
"staff_id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
|
|
"hospital_name": "Al Nuzha",
|
|
"source": "his_api",
|
|
"source_reference": "",
|
|
"doctor_id": "10738",
|
|
"doctor_name": "OMAYMAH YAQOUB ELAMEIAN",
|
|
"doctor_name_raw": "10738 - OMAYMAH YAQOUB ELAMEIAN",
|
|
"doctor_name_display": "OMAYMAH YAQOUB ELAMEIAN",
|
|
"department_name": "Internal Medicine",
|
|
"patient_uhid": "UHID12345",
|
|
"patient_name": "Ahmed Ali",
|
|
"patient_type": "OP",
|
|
"admit_date": null,
|
|
"discharge_date": null,
|
|
"rating": 4,
|
|
"feedback": "Great doctor, very caring and attentive.",
|
|
"rating_date": "2026-06-10T00:00:00+03:00",
|
|
"is_aggregated": false,
|
|
"aggregated_at": null,
|
|
"created_at": "2026-06-10T14:22:11+03:00",
|
|
"updated_at": "2026-06-10T14:22:11+03:00"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Retrieve a Doctor Rating
|
|
|
|
Retrieve a single rating by its UUID (returned in the `rating_id` field on creation).
|
|
|
|
```
|
|
GET /api/v1/external/doctor-ratings/<rating_id>/
|
|
```
|
|
|
|
**Response (200):** Same object shape as a single item from the list endpoint.
|
|
|
|
**Error Responses:**
|
|
|
|
| HTTP Status | Condition |
|
|
|---|---|
|
|
| `404` | Rating does not exist, or is outside the API key's hospital scope |
|
|
| `403` | API key does not have access to `doctor_ratings` |
|
|
|
|
---
|
|
|
|
## Common Patterns
|
|
|
|
### Location Hierarchy
|
|
|
|
Locations follow a cascading hierarchy. Use lookup endpoints to populate dependent dropdowns:
|
|
|
|
```
|
|
1. GET /hospitals/ → pick hospital
|
|
2. GET /location-types/ → pick location type
|
|
3. GET /areas/?hospital=X → pick area (filtered by hospital)
|
|
4. GET /departments/?hospital=X → pick department
|
|
5. GET /sections/?hospital=X&department=Y → pick section
|
|
```
|
|
|
|
### Date Filtering
|
|
|
|
All list endpoints support date range filtering:
|
|
|
|
```
|
|
GET /complaints/list/?created_from=2026-01-01&created_to=2026-06-30
|
|
GET /complaints/list/?updated_from=2026-06-01T08:00:00&updated_to=2026-06-09T17:00:00
|
|
```
|
|
|
|
- Date-only values (`YYYY-MM-DD`): `created_from` starts at 00:00, `created_to` extends to 23:59:59
|
|
- Full datetime values (`YYYY-MM-DDTHH:MM:SS`) are also accepted
|
|
|
|
### Pagination
|
|
|
|
All list endpoints return paginated results:
|
|
|
|
```json
|
|
{
|
|
"count": 150,
|
|
"page": 1,
|
|
"page_size": 20,
|
|
"results": [...]
|
|
}
|
|
```
|
|
|
|
| Parameter | Default | Max |
|
|
|---|---|---|
|
|
| `page` | 1 | - |
|
|
| `page_size` | 20 | 100 |
|
|
|
|
### Reference Number Formats
|
|
|
|
| Entity | Prefix | Format |
|
|
|---|---|---|
|
|
| Complaint | `CMP-` | `CMP-YYYYMMDD-XXXXXX` |
|
|
| Inquiry | `INQ-` | `INQ-YYYYMMDD-XXXXXX` |
|
|
| Observation | `OBS-` | `OBS-XXXXXX` (auto-generated by model) |
|
|
| Appreciation | `APR-` | `APR-YYYYMM-NNNN` |
|
|
| Suggestion | `SGT-` | `SGT-YYYYMM-NNNN` |
|