Overview

The eClinicalWorks integration enables Vantrexia to read patient demographics from eCW and write RPM observation data back to patient charts in real time. This eliminates manual data entry for clinical staff and ensures that all remote monitoring readings are part of the patient's longitudinal health record.

Certification: Vantrexia's eCW integration uses the official FHIR R4 API provided by eClinicalWorks. All data exchange conforms to the HL7 FHIR R4 (4.0.1) specification with LOINC-coded observations and SNOMED CT clinical terminology.

Key capabilities:

  • Patient Import — Search and import patient demographics from eCW into Vantrexia's patient registry
  • Observation Push — Automatically sync RPM readings (blood pressure, SpO2, weight, glucose) to eCW as FHIR Observation resources
  • Authentication — Dual authentication support: JWT Backend Services for automated sync and OAuth2 Standalone for interactive access
  • Audit Trail — Every data exchange is logged with timestamps, resource IDs, and delivery confirmation for HIPAA compliance

Authentication Methods

Vantrexia supports two authentication methods for connecting to eClinicalWorks' FHIR API. The appropriate method depends on whether the access is machine-initiated (automated sync) or user-initiated (interactive workflows).

JWT Backend Services (Primary)

The JWT Backend Services flow uses the OAuth 2.0 client_credentials grant type with a signed JWT client assertion. This is the primary authentication method for all automated, machine-to-machine data exchange between Vantrexia and eCW.

Parameter Value
Grant Type client_credentials
Client Assertion Type urn:ietf:params:oauth:client-assertion-type:jwt-bearer
Signing Algorithm RS384 (RSA with SHA-384)
Key Registration JWKS endpoint (/.well-known/jwks.json)
Token Lifetime 5 minutes (300 seconds)
Access Token Expiry 60 minutes (3600 seconds)

The JWT assertion includes the following claims:

JWT Payload Claims
{
  "iss": "your-ecw-client-id",
  "sub": "your-ecw-client-id",
  "aud": "https://oauthserver.eclinicalworks.com/oauth/oauth2/token",
  "exp": 1738900500,
  "iat": 1738900200,
  "jti": "unique-request-id-uuid4"
}

OAuth2 Standalone (Interactive)

The OAuth2 Standalone flow uses the authorization_code grant with PKCE (Proof Key for Code Exchange) for user-interactive scenarios where a provider needs to authorize Vantrexia to access their eCW account. This flow is used during initial setup and for operations that require user consent.

Parameter Value
Grant Type authorization_code
PKCE Challenge Method S256
Redirect URI https://api.vantrexia.com/api/v1/ecw/auth/callback/
Response Type code
Access Token Expiry 60 minutes (3600 seconds)
Refresh Token Supported (7-day lifetime)

Configuration

The following endpoints and configuration parameters are required to establish a connection with eClinicalWorks:

Configuration Staging Production
Token Endpoint https://staging-oauthserver.eclinicalworks.com/oauth/oauth2/token https://oauthserver.eclinicalworks.com/oauth/oauth2/token
FHIR Base URL https://sandbox-fhir4.eclinicalworks.com/fhir/r4/{practice_code} https://fhir4.eclinicalworks.com/fhir/r4/{practice_code}
Authorization URL https://staging-oauthserver.eclinicalworks.com/oauth/oauth2/authorize https://oauthserver.eclinicalworks.com/oauth/oauth2/authorize
JWKS Endpoint https://api.vantrexia.com/.well-known/jwks.json

Required Scopes

The following FHIR scopes must be granted to Vantrexia's client application in the eCW developer portal:

Required FHIR Scopes
system/Patient.read        # Read patient demographics
system/Observation.write   # Write RPM observation data
system/*.write             # Write clinical resources (Observations, DiagnosticReports)
user/Patient.read          # Read patients in user context (OAuth2 standalone)
user/Observation.write     # Write observations in user context (OAuth2 standalone)

Setup Steps

Follow these steps to configure the eClinicalWorks integration from scratch. Estimated setup time: 30–45 minutes.

1

Generate RSA Key Pair

Generate an RSA key pair for JWT signing. The private key stays on the Vantrexia server; the public key is registered with eCW via the JWKS endpoint.

Generate RSA-384 Key Pair
# Generate 2048-bit RSA private key
openssl genrsa -out ecw_private_key.pem 2048

# Extract public key
openssl rsa -in ecw_private_key.pem -pubout -out ecw_public_key.pem

# Generate a key ID (kid) for JWKS
export KEY_ID=$(openssl rand -hex 16)
echo "Key ID: $KEY_ID"

# Verify the key pair
openssl rsa -in ecw_private_key.pem -check -noout
Security: Store the private key securely. Never commit it to source control. In production, the private key is stored in AWS Secrets Manager and injected at runtime.
2

Register in eCW Developer Portal

Log in to the eClinicalWorks Developer Portal and create a new application registration:

  1. Navigate to Applications → Register New Application
  2. Set the application type to Backend Service
  3. Enter the redirect URI: https://api.vantrexia.com/api/v1/ecw/auth/callback/
  4. Select the required FHIR scopes listed above
  5. Submit the registration and note the assigned Client ID
3

Whitelist JWKS Endpoint

In the eCW developer portal, register your JWKS endpoint URL so eCW can verify your JWT signatures:

JWKS Endpoint URL
https://api.vantrexia.com/.well-known/jwks.json

Vantrexia automatically serves the JWKS document containing your public key. Verify it is accessible:

Verify JWKS Endpoint
curl -s https://api.vantrexia.com/.well-known/jwks.json | python -m json.tool

The response should contain a keys array with your RSA public key in JWK format, including the kid matching your generated Key ID.

4

Configure Environment Variables

Add the following variables to your .env file (local development) or AWS Secrets Manager (production):

.env configuration
# eClinicalWorks Integration
ECW_CLIENT_ID=your-assigned-client-id
ECW_CLIENT_SECRET=your-client-secret
ECW_ENVIRONMENT=staging
ECW_PRACTICE_CODE=your-practice-code
ECW_APP_TYPE=backend_service

# For production, change ECW_ENVIRONMENT:
# ECW_ENVIRONMENT=production
5

Test Connection

Verify the integration is working by testing JWT authentication and FHIR connectivity via the Vantrexia API:

Test JWT Authentication
# Test JWT token acquisition
curl -X POST https://api.vantrexia.com/api/v1/ecw/test/jwt/ \
  -H "Authorization: Bearer YOUR_VANTREXIA_TOKEN" \
  -H "Content-Type: application/json"

# Expected response:
# {
#   "status": "success",
#   "token_type": "bearer",
#   "expires_in": 3600,
#   "scope": "system/Patient.read system/Observation.write"
# }

# Test FHIR connection
curl -X POST https://api.vantrexia.com/api/v1/ecw/test/connection/ \
  -H "Authorization: Bearer YOUR_VANTREXIA_TOKEN" \
  -H "Content-Type: application/json"

# Expected response:
# {
#   "status": "success",
#   "fhir_server": "eClinicalWorks FHIR R4",
#   "capabilities": ["Patient", "Observation", "DiagnosticReport"]
# }

API Endpoints

Vantrexia exposes the following endpoints for managing the eClinicalWorks integration. All endpoints require authentication with a valid Vantrexia access token.

POST /api/v1/ecw/auth/start/

Initiates the OAuth2 standalone authorization flow. Returns an authorization URL that the user should be redirected to for granting eCW access. A PKCE code challenge is generated and stored server-side.

Response

200 OK
{
  "authorization_url": "https://staging-oauthserver.ecwcloud.com/oauth/oauth2/authorize?response_type=code&client_id=...&redirect_uri=...&scope=...&code_challenge=...&code_challenge_method=S256&state=...",
  "state": "random-state-token"
}
GET /api/v1/ecw/auth/callback/

Handles the OAuth2 callback after the user authorizes Vantrexia in eCW. Exchanges the authorization code for access and refresh tokens using the PKCE code verifier. Tokens are encrypted and stored in the database.

Query Parameters

ParameterTypeDescription
codestringAuthorization code from eCW
statestringState parameter for CSRF validation
GET /api/v1/ecw/auth/status/

Returns the current eClinicalWorks authentication status for the requesting user's organization. Indicates whether JWT and/or OAuth2 credentials are configured and valid.

Response

200 OK
{
  "jwt_configured": true,
  "jwt_last_success": "2026-02-09T10:30:00Z",
  "oauth2_configured": true,
  "oauth2_token_expires": "2026-02-09T11:30:00Z",
  "fhir_base_url": "https://sandbox-api.eclinicalworks.com/fhir/r4",
  "scopes": ["system/Patient.read", "system/Observation.write"]
}
POST /api/v1/ecw/test/jwt/

Tests JWT authentication by generating a client assertion, requesting an access token from eCW's OAuth server, and validating the response. Returns the token metadata on success or a detailed error message on failure.

Response (Success)

200 OK
{
  "status": "success",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "system/Patient.read system/Observation.write system/*.write"
}
POST /api/v1/ecw/test/connection/

Performs a full end-to-end connection test: acquires a JWT token, queries the eCW FHIR metadata endpoint (/metadata), and verifies that the required resource types are available.

Response (Success)

200 OK
{
  "status": "success",
  "fhir_server": "eClinicalWorks FHIR R4",
  "fhir_version": "4.0.1",
  "capabilities": ["Patient", "Observation", "DiagnosticReport", "Encounter"],
  "response_time_ms": 342
}
GET /api/v1/ecw/patients/

Searches for patients in eClinicalWorks by name, date of birth, or MRN. Results are returned as FHIR Patient resources and formatted for display in the Vantrexia import UI.

Query Parameters

ParameterTypeRequiredDescription
namestringNoPatient name (partial match supported)
birthdatestringNoDate of birth (YYYY-MM-DD format)
identifierstringNoMRN or other patient identifier
_countintegerNoMax results to return (default: 20)

Response

200 OK
{
  "count": 2,
  "patients": [
    {
      "ecw_id": "Patient/12345",
      "first_name": "Jane",
      "last_name": "Doe",
      "date_of_birth": "1985-03-15",
      "gender": "female",
      "mrn": "MRN-001234",
      "phone": "555-0101",
      "already_imported": false
    },
    {
      "ecw_id": "Patient/67890",
      "first_name": "John",
      "last_name": "Smith",
      "date_of_birth": "1972-11-28",
      "gender": "male",
      "mrn": "MRN-005678",
      "phone": "555-0202",
      "already_imported": true
    }
  ]
}
POST /api/v1/patients/import_selected_from_ecw/

Imports one or more selected patients from eClinicalWorks into Vantrexia's patient registry. Creates local patient records with linked eCW identifiers for future observation syncing.

Request Body

Request
{
  "patient_ids": ["Patient/12345", "Patient/67890"],
  "assign_to_provider": "dr-smith-uuid",
  "program": "RPM"
}

Response

201 Created
{
  "imported": 2,
  "skipped": 0,
  "patients": [
    {
      "vantrexia_id": "a1b2c3d4-uuid",
      "ecw_id": "Patient/12345",
      "name": "Jane Doe",
      "status": "imported"
    },
    {
      "vantrexia_id": "e5f6g7h8-uuid",
      "ecw_id": "Patient/67890",
      "name": "John Smith",
      "status": "imported"
    }
  ]
}

Data Flow

When an RPM observation is recorded in Vantrexia (either from MioConnect device data or manual entry), the following pipeline pushes it to eClinicalWorks:

1

Observation Created

A new Observation record is stored in Vantrexia's database with vital sign data (e.g., systolic: 138, diastolic: 88, pulse: 72).

2

FHIR R4 Transform

The observation is transformed into a FHIR R4 Observation resource with LOINC codes, proper units (UCUM), and a reference to the patient's eCW FHIR ID.

FHIR Observation Resource
{
  "resourceType": "Observation",
  "status": "final",
  "category": [{
    "coding": [{
      "system": "http://terminology.hl7.org/CodeSystem/observation-category",
      "code": "vital-signs",
      "display": "Vital Signs"
    }]
  }],
  "code": {
    "coding": [{
      "system": "http://loinc.org",
      "code": "85354-9",
      "display": "Blood pressure panel"
    }]
  },
  "subject": {
    "reference": "Patient/12345"
  },
  "effectiveDateTime": "2026-02-09T10:30:00Z",
  "component": [
    {
      "code": {"coding": [{"system": "http://loinc.org", "code": "8480-6", "display": "Systolic BP"}]},
      "valueQuantity": {"value": 138, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}
    },
    {
      "code": {"coding": [{"system": "http://loinc.org", "code": "8462-4", "display": "Diastolic BP"}]},
      "valueQuantity": {"value": 88, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}
    }
  ]
}
3

JWT Token Acquired

A JWT client assertion is generated with a 5-minute expiry, signed with the RS384 private key, and exchanged for an access token at eCW's token endpoint. Tokens are cached until 5 minutes before expiry.

4

POST to eCW FHIR Endpoint

The FHIR Observation resource is POSTed to {ECW_FHIR_BASE_URL}/Observation with the access token in the Authorization header. Retries are attempted up to 3 times with exponential backoff on transient failures (5xx, timeout).

5

Delivery Confirmation

On successful creation (HTTP 201), the response includes the eCW-assigned resource ID. This ID is stored in Vantrexia's database alongside the observation for audit trailing and deduplication. Failed deliveries are queued for retry via Celery.

Troubleshooting

Common issues encountered during eClinicalWorks integration setup and operation:

Issue Symptoms Resolution
JWT Token Expired HTTP 401 response with invalid_grant error when requesting access token Ensure the JWT assertion exp claim is set to no more than 5 minutes from iat. Check that the server clock is synchronized via NTP. Vantrexia auto-caches tokens; clear the cache with python manage.py clear_ecw_token_cache.
JWKS Not Accessible eCW returns invalid_client error; unable to verify JWT signature Verify https://api.vantrexia.com/.well-known/jwks.json is publicly accessible (no auth required). Check that the kid in the JWT header matches the key ID in the JWKS document. Ensure Nginx is not blocking the endpoint with rate limiting.
FHIR Validation Errors HTTP 422 response with OperationOutcome containing validation errors Common causes: missing required LOINC codes, incorrect UCUM unit codes, invalid patient reference. Check the OperationOutcome issue array for specific field-level errors. Run python manage.py validate_fhir_resources to validate locally before syncing.
Scope Mismatch HTTP 403 when accessing FHIR resources despite valid token Verify that the requested scopes in the JWT assertion match the scopes granted in the eCW developer portal. The system/Observation.write scope is required for pushing observations. Check with GET /api/v1/ecw/auth/status/ for currently active scopes.
Patient Not Found FHIR POST returns HTTP 404 for the patient reference in the Observation Ensure the patient exists in eCW and the Patient/ID reference is correct. Re-import the patient from eCW to refresh the linked ID. Patient IDs may change if the patient record is merged in eCW.
Rate Limiting HTTP 429 Too Many Requests from eCW FHIR API eCW applies rate limits per client. Vantrexia's Celery workers use a token bucket rate limiter (default: 10 requests/second). If you hit rate limits, reduce the ECW_RATE_LIMIT setting in your environment variables. Batch observation pushes during off-peak hours.
SSL/TLS Handshake Failure Connection errors when contacting eCW endpoints Ensure the server has an up-to-date CA certificate bundle. eCW requires TLS 1.2+. Check with openssl s_client -connect staging-oauthserver.ecwcloud.com:443 -tls1_2. Update the certifi Python package if needed.
Debug Logging: Enable detailed eCW integration logging by setting ECW_LOG_LEVEL=DEBUG in your environment. This logs all JWT assertions (with secrets redacted), HTTP requests/responses, and FHIR resource payloads. Logs are written to /app/logs/ecw_integration.log and automatically rotated at 10 MB.
Support: If you encounter issues not covered here, check the eCW developer portal status page for known outages. For Vantrexia-specific integration issues, contact the engineering team with the output of GET /api/v1/ecw/auth/status/ and the relevant log entries from ecw_integration.log.