Skip to main content
Version: v0.1.0

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​

CodeMeaningDescription
200OKRequest successful
201CreatedResource created successfully
400Bad RequestInvalid request parameters
401UnauthorizedMissing or invalid authentication
403ForbiddenInsufficient permissions
404Not FoundResource not found
409ConflictResource conflict (duplicate)
422Unprocessable EntityValidation error
500Internal Server ErrorServer 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.created
  • patient.updated
  • appointment.created
  • appointment.updated
  • appointment.cancelled
  • encounter.created
  • invoice.created
  • payment.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​

CodeDescription
AUTH_001Invalid credentials
AUTH_002Token expired
AUTH_003Insufficient permissions
VAL_001Validation error
VAL_002Missing required field
RES_001Resource not found
RES_002Resource already exists
SYS_001Internal server error
SYS_002Database 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​

  1. Always use HTTPS in production
  2. Store tokens securely - Use httpOnly cookies or secure storage
  3. Implement token refresh - Refresh before expiration
  4. Handle errors gracefully - Check response status and error codes
  5. Respect rate limits - Implement exponential backoff
  6. Validate input - Validate data before sending
  7. Use pagination - Don't fetch all records at once
  8. Cache responses - Cache when appropriate

Next Steps​