This tutorial guides you through connecting Vantrexia to eClinicalWorks (eCW) via FHIR R4 and SMART Backend Services. You'll generate RSA keys, register your application in the eCW developer portal, configure JWT authentication, import patients, and verify that observations flow bidirectionally between the two systems.

Advanced Tutorial

This tutorial requires familiarity with OAuth 2.0, JWT tokens, RSA cryptography, and FHIR R4 resources. If you're new to these concepts, review the eClinicalWorks Integration Overview first.

Step 1: Prerequisites

Gather the following before starting:

Requirement Details How to Obtain
eCW Developer Account Access to the eCW developer portal for app registration Register at developer.eclinicalworks.com
FHIR R4 Access eCW must have FHIR R4 APIs enabled for your practice Contact your eCW account representative
OpenSSL For generating RSA key pairs Pre-installed on macOS/Linux; Windows: install via Win32 OpenSSL
Running Vantrexia Instance Backend accessible via HTTPS with a valid SSL certificate See Deployment Guide for production setup
eCW Sandbox Environment

For testing, use the eCW sandbox environment. Production credentials are different. The endpoints referenced in this tutorial use the sandbox URLs — replace them with production URLs when going live.

Step 2: Generate RSA Key Pair

The eCW SMART Backend Services flow uses asymmetric cryptography. You'll sign JWT assertions with your private key, and eCW will verify them using your public key.

  1. Open a terminal and navigate to your keys directory:
    Shell
    mkdir -p backend/keys && cd backend/keys
  2. Generate a 2048-bit RSA private key:
    Shell — Generate Private Key
    openssl genrsa -out private.pem 2048
  3. Extract the public key:
    Shell — Extract Public Key
    openssl rsa -in private.pem -pubout -out public.pem
  4. Verify both files were created:
    Shell
    ls -la *.pem
    # -rw-------  1 user  staff  1675 Feb  6 10:00 private.pem
    # -rw-r--r--  1 user  staff   451 Feb  6 10:00 public.pem
HIPAA: Protect Your Private Key

The private key (private.pem) must never be committed to version control, shared via email, or stored in plaintext on shared drives. In production, store it in a secrets manager (AWS Secrets Manager, HashiCorp Vault) or as an encrypted environment variable. The file permissions should be 600 (owner read/write only).

Step 3: Register Application in eCW Developer Portal

  1. Log in to the eCW Developer Portal.
  2. Navigate to My Applications → Create New Application.
  3. Fill out the registration form:
    FieldValue
    Application NameVantrexia RPM
    Application TypeBackend Service (SMART Backend Services)
    FHIR VersionR4
    Scopes Requestedsystem/Patient.read, system/Observation.write, system/Observation.read
    JWKS URLhttps://your-domain.com/.well-known/jwks.json
    DescriptionRemote Patient Monitoring platform — reads patient demographics, writes vital sign observations
  4. After submission, eCW will review your application (typically 1–3 business days for sandbox, 1–2 weeks for production).
  5. Once approved, you'll receive a Client ID — save this value securely.

Step 4: Configure JWKS Endpoint

eCW needs to verify your JWT signatures. Vantrexia exposes a JWKS (JSON Web Key Set) endpoint that serves your public key in JWK format.

  1. Vantrexia automatically generates the JWKS from your public key. Verify the endpoint is accessible:
    Shell
    curl https://your-domain.com/.well-known/jwks.json
  2. You should see a response like:
    Response — JWKS
    {
      "keys": [
        {
          "kty": "RSA",
          "kid": "vantrexia-ecw-key-1",
          "use": "sig",
          "alg": "RS384",
          "n": "0vx7agoebGcQSuuPiLJXZpt...",
          "e": "AQAB"
        }
      ]
    }
  3. Ensure this URL is publicly accessible — eCW's token server will fetch it to validate your JWT assertions.

Step 5: Set Backend Environment Variables

Configure the eCW integration variables in your backend .env file:

.env — eClinicalWorks Configuration
# eClinicalWorks Integration
ECW_CLIENT_ID=your-client-id-from-ecw-portal
ECW_CLIENT_SECRET=your-client-secret
ECW_ENVIRONMENT=staging
ECW_PRACTICE_CODE=your-practice-code
ECW_APP_TYPE=backend_service
Variable Description
ECW_CLIENT_ID The Client ID assigned when you registered your app in the eCW developer portal
ECW_CLIENT_SECRET The Client Secret for OAuth 2.0 authentication with eCW
ECW_ENVIRONMENT Environment name: staging for sandbox, production for live
ECW_PRACTICE_CODE The eCW practice code assigned to your organization (e.g., FFHEDD)
ECW_APP_TYPE Application type registered with eCW (e.g., backend_service)

After updating the .env file, restart the backend service:

Shell
docker compose restart backend

Step 6: Test JWT Authentication

Vantrexia provides a built-in test endpoint that generates a JWT assertion, exchanges it for an access token from eCW, and reports the result:

POST /api/v1/ecw/test/jwt/
curl -X POST https://app.vantrexia.com/api/v1/ecw/test/jwt/ \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json"

A successful response:

Response — 200 OK
{
  "status": "success",
  "message": "JWT authentication successful",
  "token_endpoint": "https://staging-oauthserver.eclinicalworks.com/oauth/oauth2/token",
  "access_token_preview": "eyJhbGciOiJSUzM4NCIs...truncated",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "system/Patient.read system/Observation.write system/Observation.read",
  "issued_at": "2026-02-06T12:00:00Z"
}
Troubleshooting JWT Failures

Common issues: (1) invalid_client — check that ECW_CLIENT_ID matches the portal; (2) invalid_grant — verify the JWKS endpoint is publicly accessible and the kid matches; (3) key_not_found — ensure ECW_CLIENT_SECRET is correctly set in your environment.

Step 7: Test FHIR Connection

After JWT authentication works, test the end-to-end FHIR connection:

POST /api/v1/ecw/test/connection/
curl -X POST https://app.vantrexia.com/api/v1/ecw/test/connection/ \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json"
Response — 200 OK
{
  "status": "success",
  "fhir_base_url": "https://fhir4.eclinicalworks.com/fhir/r4/FFHEDD",
  "fhir_version": "4.0.1",
  "capabilities": [
    "Patient.read",
    "Observation.read",
    "Observation.write"
  ],
  "test_patient_count": 142,
  "connection_latency_ms": 245
}

Step 8: Import Patients from eCW

With the FHIR connection established, you can browse and import patients from eCW into Vantrexia:

  1. Browse eCW patients — Fetch the patient list from eCW:
    GET /api/v1/ecw/patients/
    curl -X GET "https://app.vantrexia.com/api/v1/ecw/patients/?page=1&page_size=20" \
      -H "Authorization: Bearer $ACCESS_TOKEN"
    This returns a paginated list of patients from eCW with their FHIR resource IDs, names, DOBs, and MRNs.
  2. Select patients for import — Use the dashboard or API to import selected patients:
    POST /api/v1/patients/import_selected_from_ecw/
    curl -X POST https://app.vantrexia.com/api/v1/patients/import_selected_from_ecw/ \
      -H "Authorization: Bearer $ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "ecw_patient_ids": [
          "ecw-patient-fhir-id-001",
          "ecw-patient-fhir-id-002",
          "ecw-patient-fhir-id-003"
        ]
      }'
  3. The import process:
    • Reads patient demographics from eCW FHIR (name, DOB, MRN, phone, address)
    • Creates corresponding patient records in Vantrexia
    • Links the Vantrexia patient to their eCW FHIR ID for bidirectional sync
    • Sets patient active=True
Response — Import Result
{
  "imported": 3,
  "skipped": 0,
  "errors": [],
  "patients": [
    {
      "vantrexia_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "ecw_fhir_id": "ecw-patient-fhir-id-001",
      "name": "John Smith",
      "mrn": "ECW-10042"
    },
    {
      "vantrexia_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "ecw_fhir_id": "ecw-patient-fhir-id-002",
      "name": "Sarah Johnson",
      "mrn": "ECW-10087"
    },
    {
      "vantrexia_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "ecw_fhir_id": "ecw-patient-fhir-id-003",
      "name": "Robert Williams",
      "mrn": "ECW-10103"
    }
  ]
}

Step 9: Verify FHIR Data Flow

The final step is confirming that vital sign observations recorded in Vantrexia are pushed back to eCW and appear in the patient's flowsheet.

  1. Ensure an imported patient has a device assigned and has taken at least one reading (or use the device simulator).
  2. Vantrexia automatically creates FHIR Observation resources and pushes them to eCW when new vitals are recorded. Verify by checking the sync log:
    Shell
    docker compose logs backend | grep "ecw_sync" | tail -5
    You should see entries like:
    Output
    backend | [2026-02-06 12:30:00] INFO ecw_sync: Pushed Observation to eCW for patient ECW-10042 (systolic: 128, diastolic: 82)
    backend | [2026-02-06 12:30:01] INFO ecw_sync: eCW response: 201 Created, FHIR Observation ID: obs-fhir-98765
  3. Log in to the eCW web interface and navigate to the patient's flowsheet. Verify the vital sign reading appears with:
    • Correct systolic/diastolic values
    • Timestamp matching the Vantrexia reading
    • Source tagged as "Vantrexia RPM"
  4. In Vantrexia, check the patient's Sync Status tab to see a history of all FHIR pushes with their HTTP status codes and eCW response IDs.
Integration Complete!

Your Vantrexia instance is now connected to eClinicalWorks. Patient demographics are imported via FHIR, and vital sign observations are pushed back automatically. The complete data flow is: Device → Vantrexia → FHIR Observation → eCW Flowsheet.

Quick Reference

Setting Sandbox Value Notes
Token Endpoint https://staging-oauthserver.eclinicalworks.com/oauth/oauth2/token Replace with production URL when going live
FHIR Base URL https://sandbox-fhir4.eclinicalworks.com/fhir/r4/{practice_code} Replace with production URL when going live
Scopes system/Patient.read system/Observation.write system/Observation.read Request additional scopes as needed
JWT Algorithm RS384 RSA with SHA-384; required by eCW
Token Lifetime 5 minutes (300 seconds) Maximum allowed by eCW for JWT assertions