eClinicalWorks
eClinicalWorks
eClinicalWorks
Complete OAuth 2.0 and FHIR R4 integration adapter for eClinicalWorks EHR systems. Supports patient-facing, system-to-system, and embedded EHR launch workflows with mandatory PKCE, FHIR CRUD operations, batch/transaction bundles, and bulk data export.
Overview
ConnectHealth's eClinicalWorks (eCW) integration gives your application secure access to patient data and clinical workflows through eCW's FHIR API. ConnectHealth acts as a robust middleware layer — handling eCW's strict Mandatory PKCE (S256) implementation, JWT assertions for B2B authentication, SMART endpoint discovery, token refreshing, and complex batch/transaction bundles.
You (your organization) must independently create and own eClinicalWorks applications. ConnectHealth is middleware — it does NOT create apps, manage eCW/Healow Developer accounts, or handle organizational validations on your behalf, so you must have an approved application with an active Client ID before configuring workflows in ConnectHealth.
On This Page
Supported Authentication Flows
Click a card to jump to its configuration section.
Standalone OAuth
OAuth 2.0 authorization code flow with mandatory PKCE where users authorize access. Best for patient portals, health tracking apps, and tools requiring consent.
Backend to Backend (B2B)
Client credentials flow with JWT assertion (RS384). Requires hosting a JWKS public key. Best for automated data sync and population health analytics.
Embed Launch
SMART on FHIR launch flow with mandatory PKCE for tools embedded within eCW's clinical interface. Reaps patient and encounter context automatically.
Key Features
- FHIR resource CRUD operations
- Sophisticated Bulk data export
- Extensive batch and transaction bundle capabilities
- Mandatory PKCE (S256) executed entirely invisibly by ConnectHealth
- RS384 JWT Signatures and automated ConnectHealth JWKS endpoint generation
- Extremely long-lived refresh tokens (90-day validity mapping)
Before You Begin
The eClinicalWorks developer ecosystem is highly fragmented based on your target audience. You will be using one of two separate developer portals:
1. Healow Developer Portal
For Patient-Centric Apps. Used primarily to create Standalone (public) patient portals or fitness/tracking applications.
2. eCW OpenDev Portal
For Provider & System Apps. Used exclusively to create B2B (System) and Embed Launch SMART on FHIR tools directly interacting with the clinic staff.
Prerequisites Checklist
- Appropriate Developer Account — Registered under your organization
- Client ID — Issued by either Healow or OpenDev
- Callback Redirect URI — Perfectly matched in the portal
- For B2B: JWKS URI registered — The ConnectHealth-issued public key path given to eCW
Create Your eCW Application
Follow these steps to generate your exact credentials. Pay strict attention to selecting the correct developer portal.
Choose Your Developer Portal & Sign Up
Log in or create a developer instance based on your application type:
- Patient-facing Apps (Standalone): Navigate to the Healow Developer Portal.
- Provider Apps (Embed) & B2B (System): Navigate to the eCW OpenDev Portal.
Register the Application & URLs
Create a new application in your chosen dashboard.
- Select if the app is Public (no secret required) or Confidential (server-side, uses JWT). Note: eCW requires Confidential apps for B2B workflow.
- For Standalone and Embed Launch: Register the ConnectHealth OAuth Callback precisely:
https://your-connecthealth-domain/api/workflow/auth/{integrationId}/callback(No trailing slashes allowed) - Copy your generated Client ID natively stored by eCW.
Add Required Scopes
Carefully define the scopes. If using Provider Embed Launch, remember the launch scope must be paired directly with explicit FHIR reads (e.g. launch patient/*.read); otherwise, the OAuth ticket will grant no actual data access.
Register the JWKS Public Key (B2B Only)
If utilizing Backend (B2B) System integration:
- Create the eCW Connection partially in the ConnectHealth dashboard.
- ConnectHealth will instantly autogenerate a secure RSA key pair and a custom JWKS URI.
- Paste this ConnectHealth JWKS URI directly into your eCW OpenDev application settings securely defining your assertion identity.
Finalize inside ConnectHealth
Finish setting up your Connection in ConnectHealth by dropping in the registered Client ID, verifying the Scopes, and designating whether the App Type is public or confidential.
Test in the eCW Sandbox
Target the eCW Sandbox using Practice Code JAFJCD. Verify that ConnectHealth successfully generates the PKCE challenge strings and cleanly finishes the auth loop.
Production Activation
eClinicalWorks restricts Open API endpoints based on clinical agreements. Use of the API for write-backs or high-volume background sweeps requires the hospital or practice to formally validate the vendor application through their account manager.
Sandbox Environment Setup
The eClinicalWorks sandbox environment heavily depends on which Developer Portal you are utilizing.
The Practice Code JAFJCD and the synthetic patient logins below are exclusively for Healow (Patient-Facing) sandbox testing — there are no public shared credentials for the eCW OpenDev platform. If you are developing a Provider or B2B application via eCW OpenDev, eClinicalWorks will privately assign you a specific staging Practice Code and test provider credentials during your application registration process.
eCW Sandbox Endpoints (Healow Patient Portal)
| Purpose | URL |
|---|---|
| FHIR Base (R4) | https://fhir4.eclinicalworks.com/fhir/r4/JAFJCD |
| OAuth Authorization | https://oauthserver.eclinicalworks.com/oauth/oauth2/authorize |
| OAuth Token | https://oauthserver.eclinicalworks.com/oauth/oauth2/token |
| SMART Configuration | https://fhir4.eclinicalworks.com/fhir/r4/JAFJCD/.well-known/smart-configuration |
Synthetic Test Patient Login
If utilizing a Patient-Facing (Healow) application in Standalone workflow, use these test credentials in the OAuth login pop-up.
| Username | Password | Description |
|---|---|---|
AdultFemaleFHIR |
e@CWFHIR1 |
Adult female test patient |
AdultMaleFHIR |
e@CWFHIR1 |
Adult male test patient |
ChildFemaleFHIR |
e@CWFHIR1 |
Child female test patient |
Sandbox vs Production Comparison
| Aspect | Sandbox | Production |
|---|---|---|
| Practice Code | JAFJCD |
Customer-specific string |
| Data Access | Synthetic clinical records | Real HIPAA-covered PHI |
| Approval Layer | Immediate after developer registration | Requires eCW organizational authorization |
| Rate Limits | Heavy throttling | Scaled per instance limits |
Configuration Reference
Warning: Ensure you differentiate between Public APIs and Confidential implementations properly based on the developer portal guidelines.
Standalone OAuth
| Field | Autofill | Required | Description |
|---|---|---|---|
Client ID |
No | Yes | Your unique application identifier. |
App Type |
No | Yes | 'public' (no secret) or 'confidential' (requires JWT assertion). |
FHIR Base URL |
No | Yes | The base URL of the specific practice's FHIR server. |
Redirect URL |
Yes | Yes | Your ConnectHealth callback URL. |
Scopes |
No | Yes | String of explicit OAuth scopes mapping to your approved portal specs. |
Private Key |
Yes | No | Only required for confidential App Types. Autogenerated RS384. |
Setup Steps
- Register your application in the eCW Developer Portal and capture the Client ID.
- Choose your app type: 'public' (browser-only, no secret) or 'confidential' (server-side, uses JWT).
- For confidential apps: ConnectHealth will automatically generate an RSA key pair and host the public key at a JWKS endpoint.
- Register your redirect URI perfectly — it must match EXACTLY (case-sensitive, no trailing slashes).
- Configure the Standalone workflow in ConnectHealth with the fields above.
- Test the authorization flow — PKCE parameters are generated and validated automatically under the hood by ConnectHealth.
Backend to Backend (B2B)
eCW B2B mandates JWT assertions. ConnectHealth automatically hosts your JWKS public endpoint, making this complex handshake virtually invisible to your team.
| Field | Autofill | Required | Description |
|---|---|---|---|
Client ID |
No | Yes | Identifier generated in eCW OpenDev. |
App Type |
No | Yes | Must be strictly set to confidential. |
Private Key |
Yes | Yes | PEM RS384 signature key generated by ConnectHealth. |
Key ID |
Yes | Yes | KID mapping to the provided JWKS. |
FHIR Base URL |
No | Yes | The practice-specific FHIR base endpoint. |
Token URL |
Yes | Yes | eCW OAuth token endpoint url. |
Setup Steps
- Register your application as a confidential backend system app in the eCW OpenDev Portal.
- ConnectHealth will automatically generate an RSA key pair (RS384) and host the public key at a ConnectHealth JWKS endpoint.
- Copy the JWKS URL from ConnectHealth and register it in your eCW OpenDev application settings.
- After app registration is approved by eCW, configure the Backend workflow in ConnectHealth with your Client ID, FHIR base URL, and correct system scopes.
- Test by requesting a backend token via ConnectHealth — a new JWT assertion is dynamically cryptographically signed for each request automatically.
SMART on FHIR - Embed Launch
SMART on FHIR launch flow utilizing mandatory PKCE for tools embedded directly within eClinicalWorks. Reads active patient and encounter context automatically directly from the clinician's session.
| Field | Autofill | Required | Description |
|---|---|---|---|
Client ID |
No | Yes | Your unique application identifier issued by the eCW OpenDev Portal. |
App Type |
No | Yes | Application type: public or confidential. |
FHIR Base URL |
No | Yes | The base URL of the specific eCW FHIR server instance. |
Client Secret |
No | No | Required only if the app type is registered as confidential. Not broadly needed for public smart apps. |
Scopes |
No | No (Optional) |
Space-separated list of additional OAuth scopes your app requires beyond exactly
launch.
Example:
launch openid fhirUser patient/*.read offline_access
The
launch scope is always included automatically. If left empty, your app will receive EHR context but will have NO access to read FHIR resources or patient data.Always populate this field with ALL scopes your application legally needs.
|
The launch Scope Caveat
eCW strictly evaluates the exact scopes requested during the authorization flow. If you only pass the launch scope natively, the application receives generic EHR context but is 100% blind to read real clinical FHIR resources.
Ensure you manually append additional explicit scope rights inside ConnectHealth configuration settings: launch openid fhirUser patient/*.read.
Setup Steps
- Register your application in the eCW OpenDev Portal as a SMART on FHIR EHR Launch application.
- Register the ConnectHealth launch URL where eCW will push the
issandlaunchtracking parameters. - Configure the Embed Launch workflow in ConnectHealth with your Client ID.
- Your frontend app only needs to handle the short-lived
tokenIdreturned by ConnectHealth and call the ConnectHealth token exchange endpoint. - Test by launching your app from within the eCW wrapper — the massively complex PKCE handshake parameters are handled natively by ConnectHealth.
How Launch URL Works
The launch URL is a critical component of the SMART on FHIR EHR Embed workflow. Here is the operational sequence:
Step-by-Step Launch Flow
- EHR Initiates Launch: When a clinician clicks your app from within eCW, eCW sends a GET request to your launch URL containing:
iss- The FHIR server base URLlaunch- An opaque token containing the active patient/encounter context
- ConnectHealth Intercepts Launch: Your configured ConnectHealth launch URL receives these parameters. ConnectHealth dynamically discovers eCW's SMART endpoints and structures the authorization request containing the Mandatory PKCE variables.
- Authorization URL Generated: ConnectHealth responds with a secure authorization URL containing the PKCE code challenge (S256), State CSRF parameter, and scopes.
- User Authorization: The provider's browser seamlessly follows the redirect to authorize against eCW.
- Code Exchange: eCW redirects back to ConnectHealth bounding the authorization code. ConnectHealth automatically exchanges this code paired with the secret PKCE verifier for the final FHIR payload.
💡 Key Takeaway: You only need to register the OAuth Callback URL with the eCW Developer Portal. ConnectHealth silently executes the entire complex PKCE generation, Token exchanging, and session management protocol — you just interact with our standard `/token/exchange` REST endpoint.
General Scopes
| Scope | Description |
|---|---|
user/*.read | Universal read mapping to clinician permissions |
patient/*.read | Universal read focused purely on linked patient persona |
system/*.read | Background (B2B) universal read |
launch | Receive active EHR context payloads via Embed |
openid fhirUser | Connect metadata representing user authentication |
offline_access | Obtain eCW 90-day extended Refresh Tokens |
Use Cases
Choose the workflow type that best matches your application's needs.
Patient-Facing Applications
Scenario: A third-party Healow platform app needs to access patient health data via consent. Features strictly enforced PKCE verification.
Recommended Workflow: Standalone OAuth
Best For: Patient portals, health pipelines, PHR trackers
Recommended Scopes: patient/*.read openid fhirUser offline_access
System-to-System Orchestration
Scenario: A server runs automated FHIR extracts independently without clinician logins. Handled securely via RS384 signed JWT Assertions.
Recommended Workflow: Backend to Backend (B2B)
Best For: Nightly data ingestion loops, data pipeline aggregation, enterprise reporting
Recommended Scopes: system/*.read
EHR-Embedded Providers
Scenario: Web component embedded directly into eCW screens granting rapid provider workflow acceleration with active patient context provided instantly.
Recommended Workflow: Embed Launch (SMART on FHIR)
Best For: CDS Hooks components, charting assistants
Recommended Scopes: launch openid fhirUser patient/*.read
Data Analytics Export
Scenario: Moving extremely large cross-sectional FHIR chunks representing entire practice demographic batches via eCW's bulk APIs.
Recommended Workflow: Backend to Backend (B2B)
Best For: Machine Learning datasets, long-term analytics warehousing
Recommended Scopes: system/*.read system/Group.read
Get Your ConnectHealth API Key
Several ConnectHealth endpoints — Token Exchange, Backend Token, and Token Refresh — require a ConnectHealth API key passed as the x-api-key header. Without this header, these endpoints return 401 Unauthorized. Follow these steps to create your API key.
Log in to the ConnectHealth Dashboard
Log into your ConnectHealth instance (the URL where your deployment is hosted).
Navigate to Settings → API Keys
From the left nav, click Settings, then open the API Keys tab.
If you have never generated a key, the list will be empty.
Create a New API Key
Click Create API Key, enter a descriptive name (e.g. ecw-production-client), and submit.
Under the hood this calls POST /api/keys/ with body { "name": "<your-key-name>" }.
Copy the Key Value
ConnectHealth shows the full API key once — copy it and store it securely (AWS Secrets Manager, HashiCorp Vault, or your equivalent private store).
Use the Key in the x-api-key Header
All endpoints that parse Token IDs or issue active refresh actions require this layer of protection.
API Endpoints
Token Exchange, Token Refresh, and Backend Token endpoints require the ConnectHealth API Key passed in the x-api-key header.
All API paths are prefixed with your ConnectHealth domain. Replace {integrationId} with the UUID of your eCW connection.
Token Exchange
Resolve the eCW short-lived tokenId mapped through PKCE and retrieve the authorized access payload.
curl
curl -X GET "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/exchange/{tokenId}" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"
JavaScript (fetch)
const res = await fetch(
`https://<your-ch-domain>/api/workflow/auth/${integrationId}/token/exchange/${tokenId}`,
{ headers: { "x-api-key": process.env.CH_API_KEY, "Accept": "application/json" } }
);
const { access_token, patient, scope, expires_in } = await res.json();
Backend Token (B2B)
Orchestrate a server-side JWT assertion automatically signed by RS384 via ConnectHealth.
curl
curl -X GET "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"
JavaScript (fetch)
const res = await fetch(
`https://<your-ch-domain>/api/workflow/auth/${integrationId}/token`,
{ headers: { "x-api-key": process.env.CH_API_KEY, "Accept": "application/json" } }
);
Token Refresh
Refresh an access token before expiry. Only works if the original token was issued with offline_access. eCW refresh tokens are valid for 90 days.
curl
curl -X POST "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/refresh" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"refresh_token": "YOUR_REFRESH_TOKEN"}'
JavaScript (fetch)
const res = await fetch(
`https://<your-ch-domain>/api/workflow/auth/${integrationId}/token/refresh`,
{
method: "POST",
headers: {
"x-api-key": process.env.CH_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ refresh_token: "YOUR_REFRESH_TOKEN" }),
}
);
const { access_token, refresh_token, expires_in } = await res.json();
Response
{
"body": {
"access_token": "eyJhbGc...",
"refresh_token": "dGhpcyBp...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "patient/*.read",
"patient": "patient-id-if-applicable"
},
"message": "Token refreshed successfully",
"timestamp": 1718000000000
}
OAuth Start (browser-initiated)
Initiates the Patient and Provider PKCE challenges directly and establishes the state security tokens automatically triggering immediate eCW portal relocation.
curl (inspect redirect only)
curl -I "https://<your-ch-domain>/api/workflow/auth/{integrationId}/start"