Skip to main content
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

data
array
required
Array of user objects
id
string
required
User’s unique identifier (MongoDB ObjectId)
email
string
required
User’s email address (lowercase)
fullName
string
required
User’s full name
organization
string
User’s organization name
role
string
required
User role: admin, practitioner, or auditor
active
boolean
required
Whether the user account is active
lastLoginAt
string
ISO 8601 timestamp of last login
createdAt
string
required
ISO 8601 timestamp of account creation
updatedAt
string
required
ISO 8601 timestamp of last update
total
number
required
Total number of users

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

email
string
required
User’s email address. Must be a valid email format and will be converted to lowercase. Must be unique.
fullName
string
required
User’s full name. Must be 2-120 characters.
organization
string
User’s organization name. Maximum 120 characters. Defaults to empty string.
password
string
required
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
role
string
User’s role in the system. Must be one of: admin, practitioner, auditor. Defaults to practitioner.

Response

user
object
required
The created user object
id
string
required
User’s unique identifier
email
string
required
User’s email address
fullName
string
required
User’s full name
organization
string
User’s organization name
role
string
required
User’s assigned role
active
boolean
required
Account active status (always true for new users)
createdAt
string
required
ISO 8601 timestamp of account creation
updatedAt
string
required
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

409 Conflict
Email address is already in use
{
  "error": "Email is already in use"
}
400 Bad Request
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

data
array
required
Array of practitioner user objects (same structure as user objects), sorted alphabetically by full name
total
number
required
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
default:"1"
Page number for pagination. Must be >= 1.
limit
number
default:"25"
Number of records per page. Must be between 1 and 100.
outcome
string
Filter by outcome: success or failure
resourceType
string
Filter by FHIR resource type (e.g., Patient, Observation, Appointment)
actorEmail
string
Filter by actor’s email address (case-insensitive)

Response

page
number
required
Current page number
limit
number
required
Number of records per page
total
number
required
Total number of records matching the filter
data
array
required
Array of audit log entries
_id
string
required
Unique identifier for the audit log entry
actorUserId
string
User ID of the actor who performed the action
actorEmail
string
Email address of the actor
actorRole
string
Role of the actor: admin, practitioner, or auditor
action
string
required
Description of the action performed (e.g., “create”, “read”, “update”, “delete”)
resourceType
string
FHIR resource type affected (e.g., “Patient”, “Observation”)
resourceId
string
ID of the affected resource
method
string
required
HTTP method used (GET, POST, PUT, DELETE)
path
string
required
API endpoint path accessed
statusCode
number
required
HTTP status code of the response
outcome
string
required
Result of the action: success or failure
ipAddress
string
IP address of the client
userAgent
string
User agent string of the client
createdAt
string
required
ISO 8601 timestamp when the log was created
updatedAt
string
required
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

admin
Administrator - Full system access including user provisioning, all FHIR resources, and audit logs
practitioner
Healthcare Practitioner - Can manage patient records, clinical resources (Observations, Conditions, Medications, Encounters, Appointments, Tasks), and view their own practitioner profile
auditor
Auditor - Read-only access to audit logs for compliance and security monitoring. Cannot modify any resources.

Role Permission Matrix

EndpointAdminPractitionerAuditor
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"
}

Build docs developers (and LLMs) love