Introduction

This documentation is published by ZH Healthcare, Inc. (blueEHR) to meet the API documentation requirements of ONC §170.315(g)(10) — Standardized API for Patient and Population Services — as specified in the g(10) Certification Companion Guide (CCG).

blueEHR's FHIR API is powered by the EMR Direct Interoperability Engine. The API implements US Core FHIR Implementation Guide 6.1.0 and USCDI v3 as required by the ONC HTI-1 Final Rule.

For Third-Party Developers: To register your application and obtain OAuth credentials, contact blueEHR at bugsandsupport@bluebrix.health The complete OAuth 2.0 endpoint URLs for a given FHIR endpoint are published in that Data Holder's well-known SMART configuration endpoint: GET https://sandbox-r4.interopengine.com:32540/.well-known/smart-configuration

Per the g(10) CCG, Health IT developers must document which US Core IG polymorphic data type choices ([x] elements) and Reference type choices are supported by their Health IT Module.

blueEHR's FHIR API supports US Core FHIR Implementation Guide 6.1.0 targeting USCDI version 3, as upgraded under the ONC HTI-1 Final Rule.

Supported Data Categories (USCDI v3)

FHIR Resource US Core Profile USCDI v3 Data Class Status
AllergyIntolerance US Core AllergyIntolerance Profile Allergies and Intolerances Required
CarePlan US Core CarePlan Profile Care Plan Required
CareTeam US Core CareTeam Profile Care Team Members Required
Condition (Encounter Dx) US Core Condition Encounter Diagnosis Profile Encounter Diagnoses Required
Condition (Problems) US Core Condition Problems and Health Concerns Profile Problems / Health Concerns Required
Coverage US Core Coverage Profile Health Insurance Information Required (HTI-1)
Device US Core Implantable Device Profile Unique Device Identifiers Required
DiagnosticReport (Lab) US Core DiagnosticReport Profile for Laboratory Results Laboratory Required
DiagnosticReport (Note) US Core DiagnosticReport Profile for Report and Note Exchange Clinical Notes Required
DocumentReference US Core DocumentReference Profile Clinical Notes Required
Encounter US Core Encounter Profile Encounter Information Required (HTI-1)
Goal US Core Goal Profile Goals Required
Immunization US Core Immunization Profile Immunizations Required
MedicationDispense US Core MedicationDispense Profile Medication Dispensed Required (HTI-1)
MedicationRequest US Core MedicationRequest Profile Medications Required
Observation (Lab) US Core Laboratory Result Observation Profile Laboratory Required
Observation (Vital Signs) US Core Vital Signs Profile Vital Signs Required
Observation (Social History) US Core Social History Profile Social Determinants of Health Required
Observation (Survey / SDOH) US Core Simple Observation / Screening Assessment SDOH Required
Patient US Core Patient Profile Patient Demographics Required
Procedure US Core Procedure Profile Procedures Required
QuestionnaireResponse US Core QuestionnaireResponse Profile SDOH Screenings Optional
RelatedPerson US Core RelatedPerson Profile Related Person Required
ServiceRequest US Core ServiceRequest Profile Referral / Notes Required (HTI-1)
Specimen US Core Specimen Profile Laboratory Required (HTI-1)

Polymorphic Data Type Choices Supported [x]

The following table documents the specific FHIR data type choices supported for each [x] element across US Core 6.1.0 profiles.

Element Supported Data Type Choice(s)
AllergyIntolerance.onset[x] onsetDateTime, onsetAge, onsetPeriod, onsetRange, onsetString
Condition.onset[x] onsetDateTime, onsetAge, onsetPeriod, onsetRange, onsetString
Condition.abatement[x] abatementDateTime, abatementAge, abatementPeriod, abatementString
DiagnosticReport.effective[x] effectiveDateTime, effectivePeriod
Encounter.reasonReference[x] reasonReference (Condition, Procedure, Observation)
Goal.start[x] startDate, startCodeableConcept
Immunization.occurrence[x] occurrenceDateTime, occurrenceString
MedicationDispense.medication[x] medicationCodeableConcept, medicationReference
MedicationDispense.statusReason[x] statusReasonCodeableConcept, statusReasonReference
MedicationRequest.medication[x] medicationCodeableConcept, medicationReference
MedicationRequest.reported[x] reportedBoolean, reportedReference
Observation.effective[x] effectiveDateTime, effectivePeriod, effectiveTiming, effectiveInstant
Observation.value[x] valueQuantity, valueCodeableConcept, valueString, valueBoolean, valueInteger, valueRange, valueRatio, valueSampledData, valueTime, valueDateTime, valuePeriod
Observation.component.value[x] valueQuantity, valueCodeableConcept, valueString, valueBoolean, valueInteger, valueRange, valueRatio, valueSampledData, valueTime, valueDateTime, valuePeriod
Patient.deceased[x] deceasedBoolean, deceasedDateTime
Patient.multipleBirth[x] multipleBirthBoolean, multipleBirthInteger
Procedure.performed[x] performedDateTime, performedPeriod, performedString, performedAge, performedRange
Provenance.occurred[x] occurredPeriod, occurredDateTime
ServiceRequest.occurrence[x] occurrenceDateTime, occurrencePeriod, occurrenceTiming
ServiceRequest.quantity[x] quantityQuantity, quantityRatio, quantityRange
ServiceRequest.asNeeded[x] asNeededBoolean, asNeededCodeableConcept
Specimen.collection.collected[x] collectedDateTime, collectedPeriod
Specimen.collection.fastingStatus[x] fastingStatusCodeableConcept, fastingStatusDuration
Coverage.subscribed[x] subscribedString, subscribedPeriod
Timing.repeat.bounds[x] boundsDuration, boundsRange, boundsPeriod

Reference Type Choices Supported

The following table documents the specific Reference target types supported for polymorphic Reference elements across US Core 6.1.0 profiles.

Element Supported Reference Target(s)
AllergyIntolerance.patient Patient
AllergyIntolerance.recorder Patient, Practitioner, PractitionerRole, RelatedPerson
AllergyIntolerance.asserter Patient, Practitioner, PractitionerRole, RelatedPerson
CarePlan.subject Patient
CareTeam.subject Patient
Condition.subject Patient
Condition.encounter Encounter
Condition.asserter Patient, Practitioner, PractitionerRole, RelatedPerson
Coverage.subscriber Patient, RelatedPerson
Coverage.beneficiary Patient
Coverage.payor Patient, RelatedPerson, Organization
DiagnosticReport.subject Patient
DiagnosticReport.performer Practitioner, PractitionerRole, Organization, CareTeam
DiagnosticReport.resultsInterpreter Practitioner, PractitionerRole, Organization, CareTeam
DocumentReference.subject Patient
DocumentReference.author Practitioner, PractitionerRole, Organization, Patient, Device, RelatedPerson
Encounter.subject Patient
Encounter.participant.individual Practitioner, PractitionerRole, RelatedPerson
Goal.subject Patient
Immunization.patient Patient
MedicationDispense.subject Patient
MedicationDispense.performer.actor Practitioner, PractitionerRole, Organization, Patient, Device, RelatedPerson
MedicationRequest.subject Patient
MedicationRequest.requester Patient, Practitioner, PractitionerRole, Organization, RelatedPerson, Device
Observation.subject Patient, Group, Device, Location
Observation.performer Practitioner, PractitionerRole, Organization, CareTeam, Patient, RelatedPerson
Patient.generalPractitioner Organization, Practitioner, PractitionerRole
Procedure.subject Patient
Provenance.agent.who Practitioner, PractitionerRole, RelatedPerson, Patient, Device, Organization
ServiceRequest.subject Patient, Group, Location, Device
ServiceRequest.requester Practitioner, PractitionerRole, Organization, Patient, RelatedPerson, Device
Specimen.subject Patient, Group, Device, Substance, Location

HTI-1 Required FHIR Extensions (US Core 6.1.0)

The following FHIR extensions are newly required or updated under the ONC HTI-1 Final Rule and are supported on the Patient resource:

Extension URL Resource Description HTI-1 Status
us-core-sex Patient Sex for clinical use (replaces birthsex as primary) New — Required
us-core-genderIdentity Patient Patient's gender identity New — Required
us-core-tribal-affiliation Patient Tribal affiliation and enrolled/non-enrolled status New — Required
us-core-race Patient Race (expanded value set in 6.1.0) Updated
us-core-ethnicity Patient Ethnicity Retained
us-core-birthsex Patient Birth sex (legacy; retained for backward compatibility) Retained (legacy)
us-core-interpreter-required Patient Whether patient requires an interpreter New

Version Comparison: Previous vs. Current

Component Previous Version Current Version Change Driver
US Core FHIR IG STU 3.1.1 6.1.0 ONC HTI-1 Final Rule
USCDI v1 v3 ONC HTI-1 Final Rule
SMART App Launch 1.0.0 2.0 STU2 ONC HTI-1 Final Rule
New Required Resources N/A Coverage, MedicationDispense, ServiceRequest, Specimen, Encounter (required), Media, Endpoint US Core 6.1.0 / HTI-1
Finer-Grained Scopes Not supported Supported (SMART v2) SMART App Launch 2.0 STU2

blueEHR's FHIR API implements the SMART App Launch Framework 2.0 (STU2) scope model. Three scope context prefixes are supported, corresponding to the three access tiers required by ONC §170.315(g)(10):

Prefix Context Grant Type Required
patient/ Patient-authorized access (single patient context) authorization_code
user/ Clinician / user-authorized access authorization_code
system/ Backend system access — no active user session client_credentials

Both authorization_code and client_credentials grant types are enabled per g(10) certification requirements (see RFC 6749).

Patient and User Scopes — Supported Resource Types

The following scopes are supported for both patient/ and user/ context prefixes. SMART v2 permission suffixes: .rs = read + search; .r = read only; .s = search only. Wildcard patient/*.rs and user/*.rs are also supported.

patient/ Scope user/ Scope FHIR Resource US Core / USCDI v3
patient/AllergyIntolerance.rs user/AllergyIntolerance.rs AllergyIntolerance Required
patient/CarePlan.rs user/CarePlan.rs CarePlan Required
patient/CareTeam.rs user/CareTeam.rs CareTeam Required
patient/Condition.rs user/Condition.rs Condition Required
patient/Coverage.rs user/Coverage.rs Coverage Required (HTI-1)
patient/Device.rs user/Device.rs Device Required
patient/DiagnosticReport.rs user/DiagnosticReport.rs DiagnosticReport Required
patient/DocumentReference.rs user/DocumentReference.rs DocumentReference Required
patient/Encounter.rs user/Encounter.rs Encounter Required (HTI-1)
patient/Goal.rs user/Goal.rs Goal Required
patient/Immunization.rs user/Immunization.rs Immunization Required
patient/MedicationDispense.rs user/MedicationDispense.rs MedicationDispense Required (HTI-1)
patient/MedicationRequest.rs user/MedicationRequest.rs MedicationRequest Required
patient/Observation.rs user/Observation.rs Observation Required
patient/Patient.rs user/Patient.rs Patient Required
patient/Procedure.rs user/Procedure.rs Procedure Required
patient/QuestionnaireResponse.rs user/QuestionnaireResponse.rs QuestionnaireResponse Optional
patient/ServiceRequest.rs user/ServiceRequest.rs ServiceRequest Required (HTI-1)
patient/Specimen.rs user/Specimen.rs Specimen Required (HTI-1)
patient/Media.rs user/Media.rs Media Required (HTI-1)
patient/Provenance.rs user/Provenance.rs Provenance Required

System Scopes (Backend / Bulk Data)

System scopes are used with the client_credentials grant type for backend services and bulk data export (§170.315(g)(10)(e)):

Scope Description
system/*.rs Full read access to all authorized resources (bulk export)
system/Patient.rs Patient-level bulk read
system/Group.rs Group-level bulk read (population export)
system/[ResourceType].rs Per-resource type system-level read/search
Note: System scopes require the client_credentials grant type and a registered backend client. Contact blueEHR to enable backend/system access for your application.

OpenID Connect and Launch Scopes

Scope Description
openid Enables OpenID Connect ID token return (RFC 8414)
fhirUser Returns the authenticated user's FHIR resource URL in the ID token
launch EHR-embedded (EHR Launch) context token
launch/patient Standalone launch — requests patient selection at authorization
offline_access Requests a long-lived refresh token for persistent access (see Section 4)

Finer-Grained Scopes (HTI-1 Requirement)

SMART App Launch 2.0 STU2 introduces category-level access filters, required under the ONC HTI-1 Final Rule. These are enforced server-side automatically — the API applies a category filter to all matching queries when a finer-grained scope is granted.

Finer-Grained Scope Filters Access To
patient/Condition.rs?category=problem-list-item Problem list conditions only
patient/Condition.rs?category=encounter-diagnosis Encounter diagnoses only
patient/Condition.rs?category=health-concern Health concern conditions only
patient/DiagnosticReport.rs?category=LAB Laboratory diagnostic reports only
patient/DiagnosticReport.rs?category=http://loinc.org|LP29684-5 Radiology reports only
patient/Observation.rs?category=laboratory Lab result observations only
patient/Observation.rs?category=vital-signs Vital sign observations only
patient/Observation.rs?category=social-history Social history observations only
patient/Observation.rs?category=survey Survey / SDOH screening observations only
patient/MedicationRequest.rs?category=inpatient Inpatient medication requests only
patient/MedicationRequest.rs?category=community Outpatient / community medication requests only
SMART Discovery: All supported scopes and capabilities are published at the SMART configuration endpoint:
GET https://sandbox-r4.interopengine.com:32540/.well-known/smart-configuration
This endpoint returns scopes_supported, grant_types_supported, response_types_supported, and capabilities per SMART App Launch 2.0 STU2.

blueEHR's FHIR API enforces encrypted transport for all connections carrying ePHI in accordance with the HIPAA Security Rule (45 CFR §164.312(e)(2)(ii)) and ONC §170.315(g)(10).

Enforcement Method

Layer Policy
Minimum TLS Version TLS 1.2 minimum. Connections attempting to negotiate TLS 1.0, TLS 1.1, SSL 3.0, or any earlier version are rejected at the transport layer before any data is exchanged.
Plaintext HTTP All HTTP (port 80) connections to FHIR API endpoints are refused. No redirects are issued — the connection is terminated immediately without processing any request payload.
Backend Connection The phiQuery connection from blueEHR's EHR system to the EMR Direct Interoperability Engine is also a TLS 1.2-only persistent socket. No PHI traverses any unencrypted channel at any layer.
Mutual TLS (mTLS) Supported as an optional trust policy for backend client applications and dynamic client registration. Clients may be required to present a valid, trusted digital certificate for high-assurance connection establishment.
Certificate Validation Server certificates are issued by a trusted certificate authority. Client applications must validate the full server certificate chain on every connection. Self-signed certificates are not accepted by the API server.
Note: Only TLS 1.2 (or higher) connections are accepted. All plaintext connections will be refused.

Accepted Cipher Suites

The API server accepts TLS 1.2 cipher suites from the following approved categories per NIST SP 800-52 Rev. 2:

  • ECDHE key exchange with forward secrecy (PFS)
  • AES-128-GCM or AES-256-GCM authenticated encryption (AEAD)
  • SHA-256 or SHA-384 for message authentication

The following cipher suites and protocols are explicitly not accepted: RC4, DES, 3DES, MD5-based cipher suites, NULL cipher suites, and export-grade ciphers.

FHIR Capability Statement Declaration

The CapabilityStatement.rest.security element declares transport-security support per the SMART on FHIR security extensions, confirming that TLS is required for all API access:

{
  "resourceType": "CapabilityStatement",
  "rest": [{
    "security": {
      "cors": true,
      "service": [{
        "coding": [{
          "system": "http://terminology.hl7.org/CodeSystem/restful-security-service",
          "code": "SMART-on-FHIR"
        }]
      }],
      "extension": [{
        "url": "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris",
        "extension": [
          { "url": "authorize", "valueUri": "https://sandbox-r4.interopengine.com:32540/authz" },
          { "url": "token",     "valueUri": "https://sandbox-r4.interopengine.com:32540/token" },
          { "url": "register",  "valueUri": "https://sandbox-r4.interopengine.com:32540/register" },
          { "url": "manage",    "valueUri": "https://sandbox-r4.interopengine.com:32540/manage" },
          { "url": "revoke",    "valueUri": "https://sandbox-r4.interopengine.com:32540/revoke" }
        ]
      }]
    }
  }]
}

ONC §170.315(g)(10)(v)(A)(3) and SMART App Launch 2.0 STU2 require that the API support secure issuance of an initial refresh token to native applications. blueEHR's FHIR API implements this through the OAuth 2.0 Authorization Code Flow with PKCE (RFC 7636).

Why PKCE? Native applications (mobile apps, desktop apps, single-page apps) cannot securely store a client secret. PKCE eliminates the need for a client secret by cryptographically binding the authorization code to a one-time verifier that only the originating app instance can produce.

Authorization Code + PKCE Flow

1
Generate a Code Verifier and Challenge

The native app generates a cryptographically random code_verifier (43–128 characters) and computes:

code_challenge = BASE64URL(SHA-256(ASCII(code_verifier)))
code_challenge_method = S256
Note: Only the S256 method is accepted. The plain method is not supported.
2
Authorization Request

The app redirects the user to the authorization endpoint. Include offline_access in the scope to request a refresh token:

GET https://sandbox-r4.interopengine.com:32540/authz
  ?response_type=code
  &client_id=[registered_client_id]
  &redirect_uri=[app_redirect_uri]
  &scope=launch/patient openid fhirUser offline_access patient/*.rs
  &state=[csrf_random_token]
  &code_challenge=[code_challenge]
  &code_challenge_method=S256
  &aud=[FHIR base URL]
3
User Authentication and Consent

The user authenticates via blueEHR patient portal or provider portal credentials. The authorization server presents a consent screen listing the requested scopes. Upon approval, an authorization code is issued to the registered redirect_uri.

4
Token Exchange (with code_verifier)

The app exchanges the authorization code for tokens, proving possession by including the original code_verifier:

POST https://sandbox-r4.interopengine.com:32540/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=[authorization_code]
&redirect_uri=[app_redirect_uri]
&client_id=[registered_client_id]
&code_verifier=[original_code_verifier]
5
Token Response (includes Refresh Token)

The server validates the code_verifier against the stored code_challenge. If valid, it returns:

{
  "access_token":  "[jwt_access_token]",
  "token_type":    "Bearer",
  "expires_in":    3600,
  "refresh_token": "[opaque_refresh_token]",
  "scope":         "launch/patient openid fhirUser offline_access patient/*.rs",
  "id_token":      "[jwt_id_token]",
  "patient":       "[patient_fhir_id]"
}

The refresh_token is returned because offline_access was requested and approved.

6
Using the Refresh Token

When the access token expires (after 1 hour), obtain a new access token without requiring the user to re-authenticate:

POST https://sandbox-r4.interopengine.com:32540/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=[refresh_token]
&client_id=[registered_client_id]

Security Properties

Property Implementation
No client secret required Native apps use PKCE S256 — no pre-shared secret needed
Authorization code binding Code is cryptographically bound to the PKCE verifier — interception does not grant access without the verifier
Redirect URI validation The redirect_uri must exactly match a URI pre-registered for the client_id
State parameter (CSRF) Apps must include and validate the state parameter on the callback
Refresh token rotation A new refresh token is issued on each token refresh; the previous token is immediately invalidated
Scope restriction Refresh tokens are bound to the originally approved scopes; scope cannot be elevated at refresh
Access token lifetime Access tokens expire after 1 hour (3600 seconds)

Dynamic Client Registration (RFC 7591)

Native applications that support SMART Dynamic Client Registration may register with the authorization server at runtime without a pre-assigned client secret, using a trusted digital certificate or a signed software statement. This is the recommended approach for native apps distributed to multiple end-users, as each installation may register independently, receiving a unique client_id.

To enable Dynamic Client Registration for your application, contact bugsandsupport@bluebrix.health.

Relevant Standards

blueEHR's FHIR API supports the full USCDI v3 data set profiled in US Core 6.1.0. The following resources and capabilities are additionally available beyond the USCDI v3 mandatory baseline.

Additional Patient-Facing Resources

These resources are accessible via patient-context scopes and support individual patient queries, but are not part of the USCDI v3 required data class set:

FHIR Resource Profile Used Description
QuestionnaireResponse US Core QuestionnaireResponse Profile (optional in 6.1.0) Patient-reported outcomes, SDOH screening instrument responses
Media Base FHIR R4 (no US Core profile — HTI-1 required) Clinical images and media referenced from DiagnosticReport or other clinical resources
RelatedPerson US Core RelatedPerson Profile Individuals related to the patient — emergency contacts, guardians, caregivers

Additional Non-Patient-Specific Resources

Available to authorized user-context and system-context clients to support broader interoperability:

FHIR Resource Profile Used Description
Practitioner US Core Practitioner Profile Provider directory information
PractitionerRole US Core PractitionerRole Profile Provider role, specialty, and organizational affiliation
Organization US Core Organization Profile Healthcare organization directory data
Location US Core Location Profile Facility and location information
Endpoint Base FHIR R4 (HTI-1 required — referenced by US Core) Technical connectivity information for organizations and practitioners
Provenance US Core Provenance Profile Data lineage and source attribution for all clinical records
Group Base FHIR R4 Patient population groupings — used for bulk data export ($export)
Binary Base FHIR R4 Raw document and attachment data (e.g., CCD / C-CDA documents via $docref)
Person Base FHIR R4 Cross-system patient matching and identity linking

Additional Operations

Operation Endpoint Description
$docref POST https://sandbox-r4.interopengine.com:32540/DocumentReference/$docref Returns the patient's CCD (C-CDA on FHIR) document. Per US Core OperationDefinition http://hl7.org/fhir/us/core/OperationDefinition/docref.
$export (System) GET https://sandbox-r4.interopengine.com:32540/$export Bulk FHIR export of all authorized patient data, per FHIR Bulk Data Access IG STU 1.0.1.
$export (Group) GET https://sandbox-r4.interopengine.com:32540/Group/[id]/$export Bulk export of data for a defined patient population group.
$export (Patient) GET https://sandbox-r4.interopengine.com:32540/Patient/$export Bulk export of all patient-level data.

HTI-1 Extensions Beyond USCDI v1 Baseline

The following FHIR extensions are supported as required by US Core 6.1.0 and the ONC HTI-1 Final Rule. These represent an expansion beyond the prior USCDI v1 baseline that was previously implemented:

Extension Resource Description HTI-1 Status
us-core-sex Patient Biological sex for clinical use New — Required
us-core-genderIdentity Patient Patient's gender identity New — Required
us-core-tribal-affiliation Patient Tribal affiliation and enrolled/non-enrolled status New — Required
us-core-race Patient Race (expanded value set in 6.1.0) Updated
us-core-ethnicity Patient Ethnicity Retained
us-core-birthsex Patient Birth sex (legacy; retained for backward compatibility) Retained
Note on Data Availability: Availability of specific data categories depends on data present in the patient's record and the permissions granted to the requesting application. Where data is not available for a requested resource type, the API returns an empty bundle rather than an error response.

1. Permitted Use

Access to and use of the blueEHR FHIR API is permitted solely for the purposes of enabling lawful interoperability with patient health data as described in the published API documentation. Use of the API for any purpose not explicitly described in, or reasonably implied by, the official API documentation is prohibited.

2. No Reverse Engineering

Users of this API may not reverse engineer, disassemble, decompile, or attempt to derive the source code, underlying algorithms, or any non-public technical components of the API, its supporting infrastructure, or any associated software.

3. Compliance with Applicable Law

Users are solely responsible for ensuring that their applications and data-handling practices comply with all applicable federal and state laws and regulations, including but not limited to:

  • HIPAA Privacy Rule (45 CFR Part 164, Subpart E)
  • HIPAA Security Rule (45 CFR Part 164, Subpart C)
  • HITECH Act
  • ONC Information Blocking Rules (45 CFR Part 171)
  • Applicable state privacy laws
BAA Notice: These Terms and Conditions do not constitute a Business Associate Agreement (BAA). Organizations that are Covered Entities or Business Associates under HIPAA must execute a separate BAA with their applicable counterpart before transmitting PHI through this API.

4. Prohibited Uses

The following are expressly prohibited:

  • Accessing, querying, storing, or transmitting PHI for any purpose not authorized under HIPAA and not consented to by the patient or their authorized representative
  • Using the API to aggregate, sell, or market patient data without explicit patient consent and applicable legal authorization
  • Attempting to access data beyond the scope of authorized patient records or authorized user roles
  • Using the API in a manner that could impair, damage, or overload the API infrastructure or interfere with other authorized users
  • Circumventing access controls, authentication mechanisms, or rate limits

5. Authentication and Access Credentials

API credentials (OAuth client IDs, client secrets, and certificates) are issued to specific registered applications. Credentials may not be shared between applications or transferred to third parties. Users must notify blueEHR immediately upon any actual or suspected unauthorized access to or compromise of their credentials.

6. Rate Limiting

API access is subject to rate limits based on practice size and allocated resources. Requests that consistently exceed allocated bandwidth may be throttled or temporarily blocked to protect service availability for all users. A HTTP 429 Too Many Requests response with a Retry-After header will be returned when rate limits are exceeded.

7. No Warranty

The blueEHR FHIR API and the underlying EMR Direct Interoperability Engine are provided "AS IS" without warranty of any kind, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, or non-infringement. blueEHR and EMR Direct do not warrant that the API will be uninterrupted, error-free, or free of harmful components.

8. Limitation of Liability

To the maximum extent permitted by applicable law, blueEHR's and EMR Direct's aggregate liability to any party arising out of or related to use of this API shall not exceed the amounts paid by that party for API access during the twelve (12) months preceding the claim. In no event shall blueEHR or EMR Direct be liable for indirect, incidental, special, exemplary, or consequential damages.

9. Non-Discrimination

blueEHR will not restrict access to the API, impose different terms, or otherwise discriminate against any lawful third-party application, technology, or developer in a manner inconsistent with 45 CFR §170.404(a)(1) (API Transparency Conditions — non-discrimination).

10. Modifications

blueEHR reserves the right to modify these Terms and Conditions at any time. Material changes will be communicated to registered developers with a minimum of 60 days notice, except where changes are required immediately to maintain security, comply with law, or address an emergency. Continued use of the API after the effective date of changes constitutes acceptance of the updated terms.

11. Governing Law

These Terms and Conditions are governed by and construed in accordance with the laws of the State of California, without regard to conflicts of law principles. Any disputes arising under these terms shall be resolved in the courts of competent jurisdiction located in California.

12. Contact

Company ZH Healthcare, Inc. (blueEHR)
Address 4800 Hampden Lane, Suite 200, Bethesda, MD 20814
Support Phone +1-703-340-8065
Sales Phone +1-855-936-3367
Support Email bugsandsupport@bluebrix.health
Sales Email marketing@bluebrix.health
Privacy Policy blueehr.com/legal-documents/
Underlying Platform Terms: These Terms and Conditions incorporate by reference the EMR Direct Interoperability Engine Open API Terms of Use, available at www.interopengine.com/open-api-terms. In the event of conflict between these terms and the EMR Direct terms, the EMR Direct agreement governs with respect to EMR Direct's services.

Developer Reference

This section documents the technical API specification required for third-party application developers, including API syntax, function names, parameter data types, return structures, error handling, mandatory software requirements, and application registration details.

API Syntax

Base URL Structure

All FHIR API requests are made against a base FHIR R4 endpoint provided by blueEHR. Obtain your organization's specific base URL from the SMART configuration endpoint or by contacting blueEHR support.

https://sandbox-r4.interopengine.com:32540 = https://sandbox-r4.interopengine.com:32540

The base URL is used as the prefix for all resource and operation endpoints documented in this reference. The SMART discovery endpoint is always at:

GET https://sandbox-r4.interopengine.com:32540/.well-known/smart-configuration
GET https://sandbox-r4.interopengine.com:32540/metadata

HTTP Methods

Method Used For Content-Type
GET FHIR search, read, and capability queries N/A (no request body)
POST FHIR operations ($docref, $export), token endpoint, dynamic client registration application/fhir+json or application/x-www-form-urlencoded

Mandatory Request Headers

Header Required? Value Description
Authorization Required Bearer [access_token] OAuth 2.0 Bearer token obtained from the token endpoint. Must be included on every FHIR API request.
Accept Required application/fhir+json Declares the client accepts FHIR JSON responses. Requests without a valid Accept header may return HTTP 406.
Content-Type Required (POST only) application/fhir+json Required when sending a FHIR resource body (e.g., $docref operation).
FHIR-Version Optional 4.0 Explicitly requests FHIR R4. Defaults to R4 when omitted.
Prefer Optional respond-async Required for bulk export ($export) to initiate asynchronous processing per FHIR Bulk Data Access IG STU 1.0.1.

Standard Response Headers

Header Type Description
Content-Type string application/fhir+json; charset=UTF-8 on all FHIR responses
ETag string Version identifier for the returned resource (format: W/"[version_id]")
Last-Modified HTTP-date Timestamp of the last modification to the returned resource
Location URI Returned on successful resource creation; contains the resource's canonical URL
X-Content-Type-Options string nosniff — prevents MIME-type sniffing
Content-Security-Policy string CSP header enforced on all API responses
Retry-After integer Seconds to wait before retrying. Present on HTTP 429 (rate limit) responses only.

General Request Syntax — Individual Resource Read

GET https://sandbox-r4.interopengine.com:32540/[ResourceType]/[logical-id]
Authorization: Bearer [access_token]
Accept: application/fhir+json

General Request Syntax — Resource Search

GET https://sandbox-r4.interopengine.com:32540/[ResourceType]?[search_parameter]=[value]&[parameter2]=[value2]
Authorization: Bearer [access_token]
Accept: application/fhir+json

Multiple parameters are combined with & (AND logic). Multiple values for the same parameter use comma separation (OR logic within that parameter). Example:

GET https://sandbox-r4.interopengine.com:32540/Observation?patient=12345&category=laboratory&date=ge2025-01-01&_count=50
Authorization: Bearer [access_token]
Accept: application/fhir+json

General Request Syntax — FHIR Operation (POST)

POST https://sandbox-r4.interopengine.com:32540/[ResourceType]/$[operation-name]
Authorization: Bearer [access_token]
Accept: application/fhir+json
Content-Type: application/fhir+json

{
  "resourceType": "Parameters",
  "parameter": [
    { "name": "[param-name]", "valueString": "[value]" }
  ]
}

Function Names and Operations

The following table enumerates every supported FHIR function (operation) by name, HTTP method, and endpoint pattern.

Capability and Discovery

Function Name Method Endpoint Description
capabilities GET https://sandbox-r4.interopengine.com:32540/metadata Returns the server's CapabilityStatement (FHIR R4). Declares all supported resources, search parameters, and operations.
smart-configuration GET https://sandbox-r4.interopengine.com:32540/.well-known/smart-configuration Returns the SMART App Launch configuration JSON, including OAuth endpoint URLs, supported scopes, and PKCE capabilities.

Individual Resource Read

Function Name Method Endpoint Returns
read GET https://sandbox-r4.interopengine.com:32540/[ResourceType]/[id] Single FHIR resource by logical ID
vread GET https://sandbox-r4.interopengine.com:32540/[ResourceType]/[id]/_history/[vid] Specific version of a resource

Resource Search Operations (by Resource)

Function Name Method Endpoint Scope Required
search-AllergyIntolerance GET https://sandbox-r4.interopengine.com:32540/AllergyIntolerance patient/AllergyIntolerance.rs
search-CarePlan GET https://sandbox-r4.interopengine.com:32540/CarePlan patient/CarePlan.rs
search-CareTeam GET https://sandbox-r4.interopengine.com:32540/CareTeam patient/CareTeam.rs
search-Condition GET https://sandbox-r4.interopengine.com:32540/Condition patient/Condition.rs
search-Coverage GET https://sandbox-r4.interopengine.com:32540/Coverage patient/Coverage.rs
search-Device GET https://sandbox-r4.interopengine.com:32540/Device patient/Device.rs
search-DiagnosticReport GET https://sandbox-r4.interopengine.com:32540/DiagnosticReport patient/DiagnosticReport.rs
search-DocumentReference GET https://sandbox-r4.interopengine.com:32540/DocumentReference patient/DocumentReference.rs
search-Encounter GET https://sandbox-r4.interopengine.com:32540/Encounter patient/Encounter.rs
search-Goal GET https://sandbox-r4.interopengine.com:32540/Goal patient/Goal.rs
search-Immunization GET https://sandbox-r4.interopengine.com:32540/Immunization patient/Immunization.rs
search-MedicationDispense GET https://sandbox-r4.interopengine.com:32540/MedicationDispense patient/MedicationDispense.rs
search-MedicationRequest GET https://sandbox-r4.interopengine.com:32540/MedicationRequest patient/MedicationRequest.rs
search-Observation GET https://sandbox-r4.interopengine.com:32540/Observation patient/Observation.rs
search-Patient GET https://sandbox-r4.interopengine.com:32540/Patient patient/Patient.rs
search-Procedure GET https://sandbox-r4.interopengine.com:32540/Procedure patient/Procedure.rs
search-QuestionnaireResponse GET https://sandbox-r4.interopengine.com:32540/QuestionnaireResponse patient/QuestionnaireResponse.rs
search-ServiceRequest GET https://sandbox-r4.interopengine.com:32540/ServiceRequest patient/ServiceRequest.rs
search-Specimen GET https://sandbox-r4.interopengine.com:32540/Specimen patient/Specimen.rs
search-Media GET https://sandbox-r4.interopengine.com:32540/Media patient/Media.rs
search-Provenance GET https://sandbox-r4.interopengine.com:32540/Provenance user/Provenance.rs

Named FHIR Operations

Function Name Method Endpoint Description
$docref POST https://sandbox-r4.interopengine.com:32540/DocumentReference/$docref Generates and returns the patient's C-CDA document as a FHIR DocumentReference. Defined by US Core OperationDefinition.
$export (System) GET https://sandbox-r4.interopengine.com:32540/$export Initiates asynchronous bulk export of all authorized data. Requires Prefer: respond-async header and system/*.rs scope.
$export (Group) GET https://sandbox-r4.interopengine.com:32540/Group/[id]/$export Initiates bulk export for a defined patient population group.
$export (Patient) GET https://sandbox-r4.interopengine.com:32540/Patient/$export Initiates bulk export of all patient-level data.
$export-status GET [polling_location_from_export_response] Polls the status of an in-progress bulk export job. Returns 202 (in progress) or 200 (complete with file manifest).
$export-cancel DELETE [polling_location_from_export_response] Cancels an in-progress bulk export job.

OAuth / Authorization Functions

Function Name Method Endpoint Description
authorize GET https://sandbox-r4.interopengine.com:32540/authz OAuth 2.0 authorization endpoint. Initiates user authentication and consent. Redirects to client redirect_uri with code or error.
token POST https://sandbox-r4.interopengine.com:32540/token OAuth 2.0 token endpoint. Exchanges authorization code for access/refresh tokens, or refreshes an existing access token.
register POST https://sandbox-r4.interopengine.com:32540/register Dynamic client registration endpoint (RFC 7591). Registers a new client application and returns client credentials.
revoke POST https://sandbox-r4.interopengine.com:32540/revoke Token revocation endpoint (RFC 7009). Revokes an access token or refresh token.
introspect POST https://sandbox-r4.interopengine.com:32540/introspect Token introspection endpoint (RFC 7662). Returns token metadata including active status, scope, and expiry.
manage GET https://sandbox-r4.interopengine.com:32540/manage Patient-facing authorization management portal. Allows patients to review and revoke granted application permissions.

Search Parameters, Data Types, and Required/Optional Status

FHIR search parameter types: token = coded value or identifier (system|code); reference = resource reference (ResourceType/id); date = ISO 8601 date with optional prefix (eq, lt, gt, le, ge, ne, sa, eb, ap); string = text string (partial match by default); uri = exact URI match; quantity = numeric value with optional unit.

Common Parameters (All Resources)

Parameter Type Required? Description
_id token Optional Filter by the resource's logical ID. Example: _id=abc123
_count integer Optional Maximum number of results per page. Default: 20. Maximum: 100. Example: _count=50
_sort string Optional Sort results by a named parameter. Prefix with - for descending. Example: _sort=-date
_include string Optional Include referenced resources in the Bundle. Example: _include=MedicationRequest:medication
_revinclude string Optional Include resources that reference the matched resource. Example: _revinclude=Provenance:target
_elements string Optional Comma-delimited list of element names to return (partial response). Example: _elements=id,status,subject

AllergyIntolerance Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose allergy records to retrieve. Example: patient=Patient/12345
clinical-status token Optional Filter by clinical status. Values: active, inactive, resolved
date date Optional Date the allergy was recorded. Example: date=ge2024-01-01
code token Optional Allergy substance code. Example: code=http://www.nlm.nih.gov/research/umls/rxnorm|1049502

CarePlan Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose care plans to retrieve.
category token Required Must be assess-plan. Example: category=assess-plan
date date Optional Date range filter on the care plan period. Example: date=ge2024-01-01&date=le2025-12-31
status token Optional Values: draft, active, on-hold, revoked, completed, entered-in-error, unknown

Condition Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose conditions to retrieve.
category token Optional Values: problem-list-item, encounter-diagnosis, health-concern
clinical-status token Optional Values: active, recurrence, relapse, inactive, remission, resolved
code token Optional Condition code (ICD-10, SNOMED CT). Example: code=http://snomed.info/sct|73211009
onset-date date Optional Filter by onset date. Example: onset-date=ge2023-01-01
encounter reference Optional Filter conditions linked to a specific encounter. Example: encounter=Encounter/67890

DiagnosticReport Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose diagnostic reports to retrieve.
category token Optional Report category. Values: LAB, http://loinc.org|LP29684-5 (radiology), http://loinc.org|LP7839-6 (pathology)
code token Optional LOINC code for the report type. Example: code=http://loinc.org|58410-2
date date Optional Date the report was effective. Example: date=ge2024-06-01
status token Optional Values: registered, partial, preliminary, final, amended, corrected, appended, cancelled, entered-in-error

DocumentReference Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose documents to retrieve.
category token Optional Document category. Example: category=http://hl7.org/fhir/us/core/CodeSystem/us-core-documentreference-category|clinical-note
type token Optional Document type (LOINC). Example: type=http://loinc.org|34133-9 (summarization of episode note / CCD)
date date Optional Document creation date. Example: date=ge2024-01-01
period date Optional Time period the document covers.
status token Optional Values: current, superseded, entered-in-error

Encounter Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose encounters to retrieve.
date date Optional Encounter period date range. Example: date=ge2024-01-01&date=le2025-01-01
class token Optional Encounter class. Example: class=AMB (ambulatory), IMP (inpatient), EMER (emergency)
type token Optional Encounter type code (SNOMED CT / CPT).
status token Optional Values: planned, arrived, triaged, in-progress, onleave, finished, cancelled, entered-in-error, unknown
identifier token Optional Business identifier for the encounter. Example: identifier=http://hospital.example.org|ENC-2024-001

MedicationRequest Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose medication requests to retrieve.
intent token Required Must be specified. Values: proposal, plan, order, original-order, reflex-order, filler-order, instance-order, option
status token Optional Values: active, on-hold, cancelled, completed, entered-in-error, stopped, draft, unknown
authoredon date Optional Date prescription was authored. Example: authoredon=ge2024-01-01
encounter reference Optional Filter by the prescribing encounter.

Observation Search Parameters

Parameter Type Required? Description / Example
patient reference Required Patient whose observations to retrieve.
category token Required Observation category. Values: laboratory, vital-signs, social-history, survey, imaging, procedure, activity
code token Optional LOINC or SNOMED code for the specific observation type. Example: code=http://loinc.org|8302-2 (body height)
date date Optional Observation effective date/time. Example: date=ge2024-01-01
status token Optional Values: registered, preliminary, final, amended, corrected, cancelled, entered-in-error, unknown
value-quantity quantity Optional Filter by numeric value. Example: value-quantity=gt100|http://unitsofmeasure.org|mg/dL

Patient Search Parameters

Parameter Type Required? Description / Example
_id token Conditional FHIR logical ID of the patient. Required when not using patient-context scopes. Example: _id=patient-12345
identifier token Optional Business identifier (MRN, etc.). Example: identifier=http://hospital.example.org/mrn|MRN-001
family string Optional Patient's family (last) name. Example: family=Smith
given string Optional Patient's given (first) name. Example: given=John
birthdate date Optional Date of birth. Example: birthdate=1980-01-15
gender token Optional Administrative gender. Values: male, female, other, unknown
name string Optional Any part of the patient's name (given, family, prefix, suffix).

$docref Operation Parameters

Parameter Type Required? Description Return Type
patient reference (id) Required The FHIR logical ID of the patient for whom the CCD is requested.
start dateTime Optional Start of the period for the C-CDA document content. ISO 8601 format.
end dateTime Optional End of the period for the C-CDA document content.
type token (CodeableConcept) Optional Document type LOINC code. Defaults to 34133-9 (CCD).
on-demand boolean Optional If true, generates a new on-demand document. If false or omitted, returns existing document. Bundle (searchset) containing DocumentReference

$export Operation Parameters

Parameter Type Required? Description
_outputFormat string Optional Output format. Default and only supported value: application/fhir+ndjson
_since instant Optional Only include resources last updated after this timestamp. ISO 8601 format. Example: _since=2024-01-01T00:00:00Z
_type string Optional Comma-delimited list of resource types to export. If omitted, all authorized resource types are exported. Example: _type=Patient,Observation,MedicationRequest
_elements string Optional Comma-delimited list of elements to include in each resource (partial export). Example: _elements=id,status,subject
patient reference Conditional Required for Group-level export only. Specifies the patient(s) to include.

Return Variables and Response Structures

FHIR Search Response — Bundle (searchset)

All search operations return a Bundle resource with type: "searchset". The top-level structure is:

Field Type Always Present? Description
resourceType string Yes Always "Bundle"
id string (id) Yes Server-assigned unique identifier for this Bundle
meta.lastUpdated instant Yes ISO 8601 timestamp of when the Bundle was generated
type string (code) Yes Always "searchset" for search responses
total integer Yes Total number of matching records (may exceed page size if paginated)
link array of objects Yes Pagination links. Each object has relation (string: "self", "next", "previous") and url (string: full URL for that page)
entry array of objects Conditional Array of result entries. Empty array if no results found. Each entry contains fullUrl (string) and resource (object: the FHIR resource).
entry[n].fullUrl URI Yes (per entry) Canonical URL of the individual resource
entry[n].resource object (FHIR Resource) Yes (per entry) The FHIR resource object (e.g., Patient, Observation)
entry[n].search.mode string (code) Yes (per entry) "match" for primary results; "include" for _include results

Example Bundle (searchset) response structure:

{
  "resourceType": "Bundle",
  "id": "bundle-search-001",
  "meta": { "lastUpdated": "2026-04-06T10:00:00Z" },
  "type": "searchset",
  "total": 47,
  "link": [
    { "relation": "self",     "url": "https://sandbox-r4.interopengine.com:32540/Observation?patient=12345&category=laboratory&_count=20" },
    { "relation": "next",     "url": "https://sandbox-r4.interopengine.com:32540/Observation?patient=12345&category=laboratory&_count=20&_page=2" }
  ],
  "entry": [
    {
      "fullUrl": "https://sandbox-r4.interopengine.com:32540/Observation/obs-001",
      "resource": {
        "resourceType": "Observation",
        "id": "obs-001",
        ...
      },
      "search": { "mode": "match" }
    }
  ]
}

Individual Resource Read Response

A direct read (GET https://sandbox-r4.interopengine.com:32540/[ResourceType]/[id]) returns the FHIR resource object directly — not wrapped in a Bundle:

Field Type Description
resourceType string The FHIR resource type name (e.g., "Patient", "Observation")
id string (id) Logical ID of the resource (server-assigned)
meta.versionId string Version identifier for the resource
meta.lastUpdated instant Timestamp of last modification
meta.profile array of URIs US Core profile URLs the resource claims conformance with
Resource-specific fields various All mandatory (Must Support) elements per the applicable US Core 6.1.0 profile

Token Endpoint Response

A successful POST to the token endpoint returns HTTP 200 with the following JSON body:

Field Type Always Present? Description
access_token string (JWT) Yes Bearer token to use in the Authorization header for FHIR API requests
token_type string Yes Always "Bearer"
expires_in integer Yes Access token lifetime in seconds. Value: 3600 (1 hour)
scope string Yes Space-delimited list of scopes actually granted (may be a subset of requested scopes)
refresh_token string Conditional Present only when offline_access scope was requested and approved
id_token string (JWT) Conditional Present only when openid scope was requested. Contains identity claims.
patient string Conditional FHIR logical ID of the in-context patient. Present for patient-context launches.
encounter string Conditional FHIR logical ID of the in-context encounter. Present for EHR launches with encounter context.
fhirContext array Conditional Additional FHIR launch context resources (SMART 2.0 STU2 extension).

Bulk Export — Initial Response (202 Accepted)

Field Type Description
HTTP status integer 202 Accepted — export job initiated
Content-Location header URI Polling URL to check export status. Poll this URL to determine when the export is complete.

Bulk Export — Completed Response (200 OK)

When polled and the export is complete, the status endpoint returns:

Field Type Description
transactionTime instant Timestamp when the export was started (ISO 8601)
request URI The original $export request URL
requiresAccessToken boolean If true, the download URLs also require a Bearer token
output array of objects Array of export file descriptors. Each has type (string: resource type), url (string: NDJSON download URL), and count (integer: number of records)
error array of objects Any non-fatal errors encountered during export. Each has type ("OperationOutcome") and url (NDJSON file of OperationOutcome resources)

SMART Configuration Response

The /.well-known/smart-configuration endpoint returns a JSON object with the following fields:

Field Type Description
issuer URI Authorization server issuer identifier
jwks_uri URI JSON Web Key Set endpoint (public keys for token verification)
authorization_endpoint URI OAuth 2.0 authorization endpoint URL
token_endpoint URI OAuth 2.0 token endpoint URL
registration_endpoint URI Dynamic client registration endpoint URL (RFC 7591)
scopes_supported array of strings All scope values supported by this server
response_types_supported array of strings Supported OAuth response types. Value: ["code"]
grant_types_supported array of strings Supported grant types. Values: ["authorization_code", "client_credentials"]
code_challenge_methods_supported array of strings PKCE methods supported. Value: ["S256"]
capabilities array of strings SMART capabilities. Includes: launch-ehr, launch-standalone, client-public, client-confidential-symmetric, sso-openid-connect, context-banner, context-style, context-ehr-patient, context-ehr-encounter, permission-patient, permission-user, permission-offline, authorize-post

Exceptions and Exception Handling

All errors are returned as FHIR OperationOutcome resources with an appropriate HTTP status code. Applications must handle all of the following HTTP status codes.

HTTP Error Status Codes

HTTP Code Status Cause Recommended Action
400 Bad Request Malformed request syntax, invalid parameter value, missing required parameter, or unsupported search parameter. Parse the OperationOutcome issue[].details.text for the specific error. Correct the parameter and retry.
401 Unauthorized Missing or invalid Authorization header. Token is absent, expired, or malformed. Obtain a new access token from the token endpoint (using refresh token if available, or re-authorize).
403 Forbidden Access token is valid but does not have the required scope for the requested resource or operation. Request the appropriate scope during authorization. Do not retry without scope correction.
404 Not Found The requested resource does not exist, the resource ID is invalid, or the endpoint URL is incorrect. Verify the resource ID and base URL. Check the CapabilityStatement to confirm the resource type is supported.
405 Method Not Allowed HTTP method (e.g., PUT, DELETE) not supported for this endpoint. Use the correct HTTP method as documented in the Function Names section.
406 Not Acceptable The Accept header does not include application/fhir+json. Set Accept: application/fhir+json on all requests.
410 Gone The resource previously existed but has been deleted. Do not retry for the same resource ID. Remove it from local cache.
422 Unprocessable Entity The request body is syntactically valid but semantically invalid (e.g., invalid FHIR resource structure, failed validation against a profile). Review the OperationOutcome for validation error details. Correct the resource content and retry.
429 Too Many Requests Rate limit exceeded. The client has exceeded the request threshold for the allocated time window. Read the Retry-After response header (integer, seconds). Wait for the indicated duration before retrying. Implement exponential backoff.
500 Internal Server Error Unexpected server error. Log the error with the request details. Retry with exponential backoff (max 3 retries). If the issue persists, contact bugsandsupport@bluebrix.health with the id value from the OperationOutcome.
501 Not Implemented The requested operation or parameter is not implemented by this server. Check the CapabilityStatement to verify support. Do not retry.
503 Service Unavailable Server is temporarily unavailable (maintenance or overload). Retry after the duration indicated in the Retry-After header, if present. Implement exponential backoff.

OperationOutcome Structure

All error responses return a FHIR OperationOutcome resource. Applications must never display the raw OperationOutcome to end users — log the details server-side and present a user-friendly message.

Field Type Description
resourceType string Always "OperationOutcome"
id string Unique identifier for this error instance. Include in support requests.
issue array One or more issue objects describing the error(s)
issue[].severity string (code) Severity of this issue. Values: fatal, error, warning, information
issue[].code string (code) FHIR issue type code. Common values: invalid, security, login, not-found, too-costly, business-rule, exception, throttled
issue[].details.text string Human-readable description of the specific error. Do not expose directly to end users.
issue[].diagnostics string Additional diagnostic information (technical detail). For server-side logging only.
issue[].expression array of strings FHIRPath expression(s) identifying the element(s) that caused the issue (for validation errors)

Example OperationOutcome (401 Unauthorized):

HTTP/1.1 401 Unauthorized
Content-Type: application/fhir+json

{
  "resourceType": "OperationOutcome",
  "id": "err-20260406-001",
  "issue": [
    {
      "severity": "error",
      "code": "security",
      "details": {
        "text": "Access token is missing or has expired. Obtain a new access token and retry."
      }
    }
  ]
}

Example OperationOutcome (429 Rate Limit):

HTTP/1.1 429 Too Many Requests
Content-Type: application/fhir+json
Retry-After: 60

{
  "resourceType": "OperationOutcome",
  "id": "err-20260406-002",
  "issue": [
    {
      "severity": "error",
      "code": "throttled",
      "details": {
        "text": "Request rate limit exceeded. Please wait before retrying."
      }
    }
  ]
}

OAuth Error Responses

The authorization and token endpoints return OAuth 2.0 standard error responses (RFC 6749 §5.2) as JSON when an error occurs:

Field Type Description
error string Error code. Values: invalid_request, invalid_client, invalid_grant, unauthorized_client, unsupported_grant_type, invalid_scope, access_denied
error_description string Human-readable description of the error. For logging purposes only.
error_uri URI Optional URI pointing to additional error information.
Security Note: Never expose raw OperationOutcome details, stack traces, or OAuth error_description values to end users. Log all errors server-side with the OperationOutcome id field for traceability.

Mandatory Software Components

The following software components are required in any application that integrates with blueEHR's FHIR API. All components must be current, actively maintained, and free of known critical vulnerabilities (CVE severity: High or Critical).

Required Components — All Applications

Component Requirement Purpose
TLS 1.2-capable HTTP Client Must support TLS 1.2 or higher. Must perform server certificate chain validation. Must not allow fallback to TLS 1.0/1.1 or plaintext HTTP. All FHIR API requests and OAuth requests must be made over TLS 1.2+. HTTP connections are refused.
OAuth 2.0 Library with PKCE Support Must support Authorization Code Flow with PKCE using the S256 challenge method (RFC 7636). Must support the state parameter for CSRF protection. Must handle token storage and refresh token rotation. Required for all patient-context and user-context (authorization_code) API access.
JSON Parser Must support parsing of JSON per RFC 8259. Must handle deeply nested objects and large payloads (bulk export NDJSON files may be many megabytes). All FHIR resources and responses are encoded as JSON (application/fhir+json).
JWT Library Must support RS256 and ES256 signature verification. Must validate iss, aud, exp, iat, and nbf claims. Must retrieve and cache the JWKS from the server's jwks_uri. Required for verifying ID tokens (OpenID Connect) returned by the token endpoint.
Secure Storage / Keychain Must use platform-native secure credential storage (e.g., iOS Keychain, Android Keystore, Windows Data Protection API, OS-level secrets manager). Tokens must never be stored in plaintext files, browser localStorage, or sessionStorage. Secure storage of access tokens and refresh tokens.

Required Components — Backend / System Applications

Component Requirement Purpose
OAuth 2.0 Client Credentials Library Must support the client_credentials grant type (RFC 6749 §4.4). Must support client_secret_basic or private_key_jwt token endpoint authentication. Required for backend/system-level (no user session) FHIR access and bulk data export.
NDJSON Parser Must support streaming parse of Newline-Delimited JSON (NDJSON / application/fhir+ndjson) for processing bulk export output files. Must handle partial-line buffering for large files. Bulk export ($export) output files are delivered as NDJSON.
Async HTTP Client Must support long-polling for bulk export status. Must handle HTTP 202 (in-progress) responses correctly and retry polling at appropriate intervals (minimum 30 seconds between polls). Bulk export is an asynchronous operation that may take minutes to complete.
X.509 Certificate / Private Key Management Required only when using Dynamic Client Registration with client certificate authentication or mTLS. Certificate must be issued by a trusted CA. Private key must be stored in a hardware security module (HSM) or secure vault (e.g., AWS KMS, Azure Key Vault, HashiCorp Vault). Mutual TLS and certificate-based client registration.
Library Examples (not endorsed): Common open-source libraries that satisfy these requirements include: AppAuth (iOS/Android, PKCE-native), oidc-client-ts (JavaScript SPA), Spring Security OAuth2 (Java), Requests-OAuthlib (Python), and HAPI FHIR Client (Java). Regardless of library choice, developers are responsible for verifying that all mandatory features are supported and that the library is free of known critical vulnerabilities.

Mandatory Software Configurations

Applications must be configured as specified below before they can successfully authenticate and interact with blueEHR's FHIR API.

TLS Configuration

Configuration Item Required Value Notes
Minimum TLS version TLS 1.2 TLS 1.0, TLS 1.1, and SSL are not accepted. Configure your HTTP client to refuse downgrade.
Certificate verification Enabled (verify peer) Server certificate chain must be validated on every connection. Disabling certificate verification is not permitted.
Allowed cipher suites ECDHE + AES-GCM + SHA-256/384 only Configure your TLS client to disable RC4, DES, 3DES, MD5-based, and NULL cipher suites.
HTTPS-only All requests over HTTPS Do not construct or follow HTTP (non-TLS) redirect URLs for FHIR or OAuth endpoints.

OAuth / PKCE Configuration

Configuration Item Required Value Notes
PKCE code challenge method S256 The plain method is not accepted. Must always generate a new random code_verifier per authorization request.
code_verifier length 43–128 characters Generated using a cryptographically random source (e.g., SecureRandom, crypto.getRandomValues). Must use characters from: [A-Z a-z 0-9 - . _ ~] (unreserved URI characters per RFC 3986).
State parameter Required — cryptographically random Minimum 128 bits of entropy. Must be validated on callback — reject any callback where state does not match.
Redirect URI Must be pre-registered with blueEHR Must exactly match one of the registered redirect_uris for your client. For native apps, use a custom URI scheme (e.g., com.example.myapp:/callback) or a localhost loopback URL per RFC 8252.
aud parameter FHIR base URL of the target server Must be included in the authorization request. Protects against token mix-up attacks.
Token storage Platform secure storage only Never store tokens in cookies without HttpOnly + Secure + SameSite=Strict, localStorage, sessionStorage, or plaintext files.

HTTP Request Configuration

Configuration Item Required Value Notes
Accept header application/fhir+json Must be set on all FHIR API requests. Omitting this header may result in HTTP 406.
Content-Type header (POST) application/fhir+json or application/x-www-form-urlencoded Use application/fhir+json for FHIR operation requests; use application/x-www-form-urlencoded for OAuth token requests.
Request timeout Minimum 30 seconds Some FHIR searches may involve large result sets. Bulk export status polling uses a minimum 30-second interval.
Retry policy Exponential backoff with jitter On HTTP 429 or 503, wait for the Retry-After duration (or default 60 seconds) before retrying. Maximum 3 retries before surfacing the error.

Bulk Export Configuration

Configuration Item Required Value Notes
Prefer header respond-async Must be included on all $export requests. Without it, the server will return HTTP 400.
Polling interval Minimum 30 seconds between polls Polling too frequently may trigger rate limiting. Use exponential backoff if 202 responses persist beyond expected duration.
NDJSON output format application/fhir+ndjson Configure your NDJSON parser to process one JSON object per line. Files may be multiple gigabytes for large populations.

Application Registration Requirements

All applications must be registered with blueEHR's authorization server before making any API requests. Registration can be performed via static (manual) registration or via the Dynamic Client Registration endpoint (RFC 7591). In both cases, the following attributes are required or conditionally required.

Required Registration Attributes — All Applications

Attribute Type Required? Description and Requirements
client_name string Required Human-readable name of the client application. Displayed to the patient/user on the consent screen. Must accurately represent the application. Maximum 128 characters.
redirect_uris array of URIs Required One or more pre-registered redirect URIs. The redirect_uri in authorization requests must exactly match one of these values. For native apps: use custom URI scheme (e.g., com.example.app:/callback) or loopback URL per RFC 8252. HTTPS required for web apps. HTTP on loopback only (127.0.0.1 or [::1]) is permitted for desktop apps.
grant_types array of strings Required Grant types the client will use. Must include "authorization_code" for patient/user access. Must include "client_credentials" for system/bulk access. Must include "refresh_token" if offline_access will be requested. Example: ["authorization_code", "refresh_token"]
response_types array of strings Required Must include "code" (Authorization Code flow). Value: ["code"]
scope string Required Space-delimited list of all scopes the application may request. Registration must enumerate the maximum scope the application will ever request. Individual authorization requests may request a subset. Example: "launch/patient openid fhirUser offline_access patient/*.rs"
token_endpoint_auth_method string Required How the client authenticates to the token endpoint. Values: "none" — public client using PKCE (native/SPA apps, no client secret); "client_secret_basic" — confidential client with client secret via HTTP Basic Auth; "private_key_jwt" — confidential client using signed JWT assertion.
contacts array of email strings Required Contact email address(es) for the developer or organization responsible for the application. Used to notify of policy changes or security issues.

Conditional Registration Attributes

Attribute Type Condition Description
client_uri URI Required if client_name is not self-explanatory URL of the application's homepage. Must be HTTPS. Displayed on the consent screen to help users identify the application.
logo_uri URI Optional URL of the application's logo image. Must be HTTPS. Displayed on the consent screen.
policy_uri URI Recommended URL of the application's privacy policy. Must be HTTPS. Should describe how the application handles patient data.
tos_uri URI Recommended URL of the application's Terms of Service. Must be HTTPS.
jwks_uri URI Required if token_endpoint_auth_method is private_key_jwt URL of the client's JSON Web Key Set (public keys). Must be HTTPS. Used to verify signed JWT client assertions at the token endpoint.
jwks object (JWKS) Alternative to jwks_uri for private_key_jwt Inline JSON Web Key Set. Use jwks_uri (preferred) for dynamic key rotation without re-registration.
software_id string Required for UDAP Dynamic Registration Unique identifier for the software product (not the specific installation). Must be a UUID. Used to track multiple instances of the same application.
software_version string Recommended Version string of the client software. Example: "2.4.1"

Registration Response

On successful registration, the server returns HTTP 201 Created with the following JSON body:

Field Type Description
client_id string The assigned OAuth client identifier. Use this value as client_id in all authorization and token requests.
client_secret string Present only for confidential clients (client_secret_basic auth method). Store securely. Never expose in client-side code or version control.
client_id_issued_at integer (Unix timestamp) Time the client ID was issued.
client_secret_expires_at integer (Unix timestamp) Time the client secret expires. Value 0 means the secret does not expire. Re-register before expiry.
registration_access_token string Token used to read or update this client registration via the registration management endpoint.
registration_client_uri URI URL of this client's registration record. Use with the registration_access_token to update registration details.
All submitted attributes various All submitted registration attributes are echoed back in the response for confirmation.

Static Registration Process

For organizations that prefer manual (non-dynamic) registration, contact blueEHR with the following information:

  • Application name and description
  • Developer / organization contact email
  • All redirect URIs the application will use
  • Grant types required (authorization_code, client_credentials, refresh_token)
  • Full list of scopes the application will request
  • Token endpoint authentication method (none, client_secret_basic, or private_key_jwt)
  • Application type: web, native, or service (backend)
  • Privacy policy URL and Terms of Service URL
HIPAA Reminder: Applications registered to access patient data via this API are acting as Business Associates under HIPAA. A signed Business Associate Agreement (BAA) with the covered entity (healthcare organization) is required before any access to protected health information (PHI). The API registration alone does not constitute a BAA.