REST API Reference
Complete reference for the Ciyex EHR REST API.
Overview
The Ciyex EHR REST API provides programmatic access to all platform features. The API follows RESTful principles and uses JSON for request and response bodies.
Base URL
Development: http://localhost:8080
Staging: https://api-stage.example.com
Production: https://api.example.com
Authentication
All API requests require authentication using JWT tokens.
Get Access Token
POST /api/auth/login
Content-Type: application/json
{
"username": "user@example.com",
"password": "password123"
}
Response:
{
"success": true,
"message": "Login successful",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600,
"user": {
"id": 123,
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"role": "PROVIDER"
}
}
}
Using the Token
Include the token in the Authorization header:
GET /api/patients
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Refresh Token
POST /api/auth/refresh
Content-Type: application/json
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response Format
All API responses follow this structure:
Success Response
{
"success": true,
"message": "Operation completed successfully",
"data": {
// Response data
}
}
Error Response
{
"success": false,
"message": "Error description",
"error": {
"code": "ERROR_CODE",
"details": "Detailed error message"
}
}
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource not found |
| 409 | Conflict | Resource conflict (duplicate) |
| 422 | Unprocessable Entity | Validation error |
| 500 | Internal Server Error | Server error |
Pagination
List endpoints support pagination:
GET /api/patients?page=0&size=20&sort=lastName,asc
Parameters:
page- Page number (0-indexed)size- Items per page (default: 20, max: 100)sort- Sort field and direction (e.g.,lastName,asc)
Response:
{
"success": true,
"data": {
"content": [...],
"pageable": {
"pageNumber": 0,
"pageSize": 20
},
"totalElements": 150,
"totalPages": 8,
"last": false,
"first": true
}
}
Filtering
Use query parameters for filtering:
GET /api/patients?firstName=John&status=ACTIVE
API Endpoints
Authentication
Login
POST /api/auth/login
Keycloak Login
POST /api/auth/keycloak-login
Logout
POST /api/auth/logout
Refresh Token
POST /api/auth/refresh
Patients
List Patients
GET /api/patients
Get Patient
GET /api/patients/{id}
Create Patient
POST /api/patients
Update Patient
PUT /api/patients/{id}
Delete Patient
DELETE /api/patients/{id}
Search Patients
GET /api/patients/search?q={query}
Appointments
List Appointments
GET /api/appointments
Get Appointment
GET /api/appointments/{id}
Create Appointment
POST /api/appointments
Update Appointment
PUT /api/appointments/{id}
Cancel Appointment
POST /api/appointments/{id}/cancel
Get Available Slots
GET /api/appointments/available-slots?providerId={id}&date={date}
Providers
List Providers
GET /api/providers
Get Provider
GET /api/providers/{id}
Get Provider Schedule
GET /api/providers/{id}/schedule?startDate={date}&endDate={date}
Encounters
List Encounters
GET /api/encounters
Get Encounter
GET /api/encounters/{id}
Create Encounter
POST /api/encounters
Update Encounter
PUT /api/encounters/{id}
Clinical Data
Add Vitals
POST /api/patients/{patientId}/vitals
Add Lab Results
POST /api/patients/{patientId}/lab-results
Add Condition
POST /api/patients/{patientId}/conditions
Add Allergy
POST /api/patients/{patientId}/allergies
Add Medication
POST /api/patients/{patientId}/medications
Documents
Upload Document
POST /api/patients/{patientId}/documents
Content-Type: multipart/form-data
List Documents
GET /api/patients/{patientId}/documents
Download Document
GET /api/documents/{documentId}/download
Delete Document
DELETE /api/documents/{documentId}
Telehealth
Create Room
POST /api/telehealth/rooms
Join Room
POST /api/telehealth/jitsi/join
Billing
Create Invoice
POST /api/billing/invoices
List Invoices
GET /api/billing/invoices
Process Payment
POST /api/billing/payments
Messages
Send Message
POST /api/messages
List Messages
GET /api/messages
Mark as Read
PUT /api/messages/{id}/read
Rate Limiting
API requests are rate-limited to prevent abuse:
- Authenticated requests: 1000 requests per hour
- Unauthenticated requests: 100 requests per hour
Rate limit headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1634567890
Webhooks
Subscribe to events via webhooks:
Available Events
patient.createdpatient.updatedappointment.createdappointment.updatedappointment.cancelledencounter.createdinvoice.createdpayment.received
Register Webhook
POST /api/webhooks
Content-Type: application/json
{
"url": "https://your-app.com/webhook",
"events": ["appointment.created", "appointment.cancelled"],
"secret": "your-webhook-secret"
}
Webhook Payload
{
"event": "appointment.created",
"timestamp": "2024-10-15T10:30:00Z",
"data": {
"id": 123,
"patientId": 456,
"providerId": 789,
"appointmentDate": "2024-10-20",
"appointmentTime": "10:00:00"
}
}
Error Codes
| Code | Description |
|---|---|
AUTH_001 | Invalid credentials |
AUTH_002 | Token expired |
AUTH_003 | Insufficient permissions |
VAL_001 | Validation error |
VAL_002 | Missing required field |
RES_001 | Resource not found |
RES_002 | Resource already exists |
SYS_001 | Internal server error |
SYS_002 | Database error |
Code Examples
JavaScript/TypeScript
// Login
const login = async (username: string, password: string) => {
const response = await fetch('http://localhost:8080/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
const data = await response.json();
localStorage.setItem('token', data.data.token);
return data;
};
// Get patients
const getPatients = async () => {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:8080/api/patients', {
headers: { 'Authorization': `Bearer ${token}` }
});
return await response.json();
};
// Create patient
const createPatient = async (patientData) => {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:8080/api/patients', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(patientData)
});
return await response.json();
};
Python
import requests
# Login
def login(username, password):
response = requests.post(
'http://localhost:8080/api/auth/login',
json={'username': username, 'password': password}
)
data = response.json()
return data['data']['token']
# Get patients
def get_patients(token):
response = requests.get(
'http://localhost:8080/api/patients',
headers={'Authorization': f'Bearer {token}'}
)
return response.json()
# Create patient
def create_patient(token, patient_data):
response = requests.post(
'http://localhost:8080/api/patients',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json=patient_data
)
return response.json()
cURL
# Login
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"user@example.com","password":"password123"}'
# Get patients
curl -X GET http://localhost:8080/api/patients \
-H "Authorization: Bearer YOUR_TOKEN"
# Create patient
curl -X POST http://localhost:8080/api/patients \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"identification": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1985-06-15",
"gender": "Male"
},
"contact": {
"email": "john.doe@example.com",
"phoneNumber": "555-123-4567"
}
}'
Testing
Postman Collection
Download the Postman collection:
https://github.com/ciyex-org/ciyex/blob/main/postman/Ciyex-API.postman_collection.json
Swagger/OpenAPI
Access interactive API documentation:
http://localhost:8080/swagger-ui.html
Best Practices
- Always use HTTPS in production
- Store tokens securely - Use httpOnly cookies or secure storage
- Implement token refresh - Refresh before expiration
- Handle errors gracefully - Check response status and error codes
- Respect rate limits - Implement exponential backoff
- Validate input - Validate data before sending
- Use pagination - Don't fetch all records at once
- Cache responses - Cache when appropriate
Next Steps
- Authentication API - Detailed auth endpoints
- FHIR API - FHIR R4 endpoints
- Webhooks - Event subscriptions
- Security - API security