All admin endpoints require authentication via Bearer token. Most endpoints require the admin role unless otherwise specified.
Authentication
All admin endpoints require a valid JWT token in the Authorization header:
Authorization: Bearer YOUR_JWT_TOKEN
List Users
curl -X GET https://api.omniehr.com/admin/users \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Retrieve a list of all system users.
Authorization
Required Role: admin
Response
Array of user objectsUser’s unique identifier (MongoDB ObjectId)
User’s email address (lowercase)
User role: admin, practitioner, or auditor
Whether the user account is active
ISO 8601 timestamp of last login
ISO 8601 timestamp of account creation
ISO 8601 timestamp of last update
Example Response
{
"data": [
{
"id": "65a1b2c3d4e5f6a7b8c9d0e1",
"email": "[email protected]",
"fullName": "Dr. Sarah Smith",
"organization": "City General Hospital",
"role": "practitioner",
"active": true,
"lastLoginAt": "2026-03-04T10:30:00.000Z",
"createdAt": "2026-01-15T08:00:00.000Z",
"updatedAt": "2026-03-04T10:30:00.000Z"
},
{
"id": "65a1b2c3d4e5f6a7b8c9d0e2",
"email": "[email protected]",
"fullName": "System Administrator",
"organization": "OmniEHR",
"role": "admin",
"active": true,
"lastLoginAt": "2026-03-04T09:15:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-03-04T09:15:00.000Z"
}
],
"total": 2
}
Create User
curl -X POST https://api.omniehr.com/admin/users \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"fullName": "Dr. Michael Johnson",
"organization": "Downtown Clinic",
"password": "SecureP@ssw0rd123!",
"role": "practitioner"
}'
Provision a new user account in the system.
Authorization
Required Role: admin
Request Body
User’s email address. Must be a valid email format and will be converted to lowercase. Must be unique.
User’s full name. Must be 2-120 characters.
User’s organization name. Maximum 120 characters. Defaults to empty string.
User’s password. Must meet complexity requirements:
- Minimum 12 characters, maximum 128 characters
- At least one uppercase letter (A-Z)
- At least one lowercase letter (a-z)
- At least one digit (0-9)
- At least one special character
User’s role in the system. Must be one of: admin, practitioner, auditor. Defaults to practitioner.
Response
The created user objectAccount active status (always true for new users)
ISO 8601 timestamp of account creation
ISO 8601 timestamp of last update
Example Response
{
"user": {
"id": "65a1b2c3d4e5f6a7b8c9d0e3",
"email": "[email protected]",
"fullName": "Dr. Michael Johnson",
"organization": "Downtown Clinic",
"role": "practitioner",
"active": true,
"createdAt": "2026-03-04T11:00:00.000Z",
"updatedAt": "2026-03-04T11:00:00.000Z"
}
}
Error Responses
Email address is already in use{
"error": "Email is already in use"
}
Validation error for invalid input{
"error": "Validation failed",
"details": [
{
"field": "password",
"message": "Password must include at least one uppercase letter"
}
]
}
List Practitioners
curl -X GET https://api.omniehr.com/admin/practitioners \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Retrieve a list of active practitioners.
Authorization
Required Role: admin or practitioner
When accessed by a practitioner, only returns their own information. When accessed by an admin, returns all active practitioners.
Response
Array of practitioner user objects (same structure as user objects), sorted alphabetically by full name
Total number of practitioners returned
Example Response (Admin)
{
"data": [
{
"id": "65a1b2c3d4e5f6a7b8c9d0e1",
"email": "[email protected]",
"fullName": "Dr. Alice Anderson",
"organization": "City General Hospital",
"role": "practitioner",
"active": true,
"lastLoginAt": "2026-03-04T08:45:00.000Z",
"createdAt": "2026-01-10T00:00:00.000Z",
"updatedAt": "2026-03-04T08:45:00.000Z"
},
{
"id": "65a1b2c3d4e5f6a7b8c9d0e3",
"email": "[email protected]",
"fullName": "Dr. Michael Johnson",
"organization": "Downtown Clinic",
"role": "practitioner",
"active": true,
"createdAt": "2026-03-04T11:00:00.000Z",
"updatedAt": "2026-03-04T11:00:00.000Z"
}
],
"total": 2
}
Get Audit Logs
curl -X GET "https://api.omniehr.com/admin/audit-logs?page=1&limit=25&outcome=success" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Retrieve paginated audit logs with optional filtering.
Authorization
Required Role: admin or auditor
Query Parameters
Page number for pagination. Must be >= 1.
Number of records per page. Must be between 1 and 100.
Filter by outcome: success or failure
Filter by FHIR resource type (e.g., Patient, Observation, Appointment)
Filter by actor’s email address (case-insensitive)
Response
Number of records per page
Total number of records matching the filter
Array of audit log entriesUnique identifier for the audit log entry
User ID of the actor who performed the action
Email address of the actor
Role of the actor: admin, practitioner, or auditor
Description of the action performed (e.g., “create”, “read”, “update”, “delete”)
FHIR resource type affected (e.g., “Patient”, “Observation”)
ID of the affected resource
HTTP method used (GET, POST, PUT, DELETE)
API endpoint path accessed
HTTP status code of the response
Result of the action: success or failure
User agent string of the client
ISO 8601 timestamp when the log was created
ISO 8601 timestamp of last update
Example Response
{
"page": 1,
"limit": 25,
"total": 142,
"data": [
{
"_id": "65a1b2c3d4e5f6a7b8c9d0f1",
"actorUserId": "65a1b2c3d4e5f6a7b8c9d0e1",
"actorEmail": "[email protected]",
"actorRole": "practitioner",
"action": "create",
"resourceType": "Patient",
"resourceId": "65a1b2c3d4e5f6a7b8c9d0f2",
"method": "POST",
"path": "/fhir/Patient",
"statusCode": 201,
"outcome": "success",
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"createdAt": "2026-03-04T10:35:22.000Z",
"updatedAt": "2026-03-04T10:35:22.000Z"
},
{
"_id": "65a1b2c3d4e5f6a7b8c9d0f3",
"actorUserId": "65a1b2c3d4e5f6a7b8c9d0e2",
"actorEmail": "[email protected]",
"actorRole": "admin",
"action": "create",
"resourceType": "User",
"resourceId": "65a1b2c3d4e5f6a7b8c9d0e3",
"method": "POST",
"path": "/admin/users",
"statusCode": 201,
"outcome": "success",
"ipAddress": "10.0.0.50",
"userAgent": "curl/7.68.0",
"createdAt": "2026-03-04T10:30:15.000Z",
"updatedAt": "2026-03-04T10:30:15.000Z"
},
{
"_id": "65a1b2c3d4e5f6a7b8c9d0f4",
"actorEmail": "[email protected]",
"action": "login_attempt",
"method": "POST",
"path": "/auth/login",
"statusCode": 401,
"outcome": "failure",
"ipAddress": "203.0.113.45",
"userAgent": "PostmanRuntime/7.29.0",
"createdAt": "2026-03-04T10:28:50.000Z",
"updatedAt": "2026-03-04T10:28:50.000Z"
}
]
}
Example Filtered Request
# Get all failed operations
curl -X GET "https://api.omniehr.com/admin/audit-logs?outcome=failure&page=1&limit=50" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Get all Patient resource operations by a specific user
curl -X GET "https://api.omniehr.com/admin/audit-logs?resourceType=Patient&[email protected]" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
User Roles
Role Descriptions
Administrator - Full system access including user provisioning, all FHIR resources, and audit logs
Healthcare Practitioner - Can manage patient records, clinical resources (Observations, Conditions, Medications, Encounters, Appointments, Tasks), and view their own practitioner profile
Auditor - Read-only access to audit logs for compliance and security monitoring. Cannot modify any resources.
Role Permission Matrix
| Endpoint | Admin | Practitioner | Auditor |
|---|
| GET /admin/users | ✓ | ✗ | ✗ |
| POST /admin/users | ✓ | ✗ | ✗ |
| GET /admin/practitioners | ✓ | ✓ (self only) | ✗ |
| GET /admin/audit-logs | ✓ | ✗ | ✓ |
| All FHIR endpoints | ✓ | ✓ | ✗ |
Error Responses
All admin endpoints may return the following error responses:
401 Unauthorized
Returned when authentication fails or no token is provided.
{
"error": "Authentication required"
}
403 Forbidden
Returned when the authenticated user lacks the required role.
{
"error": "Insufficient permissions"
}
400 Bad Request
Returned when request validation fails.
{
"error": "Validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
500 Internal Server Error
Returned when an unexpected server error occurs.
{
"error": "Internal server error"
}