Skills Development Validating FHIR Against US Core Profiles

Validating FHIR Against US Core Profiles

v20260803
validating-us-core
This skill validates FHIR R4 resources and Bundles against mandatory US Core profiles (USCDI). It goes beyond mere syntactic checks to ensure that data prepared for submission to major Electronic Health Records (EHRs) like Epic or Cerner meets the required US-specific conformance standards. It detects common data gaps, checks 'must-support' elements, and converts the comprehensive validation report into a standard FHIR OperationOutcome for seamless pipeline integration.
Get Skill
285 downloads
Overview

Validating US Core

Producing syntactically valid R4 (which exporting-to-fhir and assembling-fhir-bundles do) is not the same as conforming to US Core — the HL7 US realm profiles that EHRs (Epic, Cerner/Oracle Health) require for ingestion and that USCDI mandates for certified exchange. This skill validates OpenMed-produced FHIR against US Core before you submit it.

When to use

Use it as the gate right before submission, after you have assembled a Bundle. Reach for it when the user says "US Core", "USCDI", "must-support", "will Epic accept this", or "validate my FHIR". It is the conformance counterpart to the mechanical builders — OpenMed builds the JSON; the HL7 validator judges it.

Quick start: run the official validator

The reference implementation is the HL7 validator_cli.jar (the same engine behind https://validator.fhir.org). Validate against the US Core package by IG:

# One-time: get the validator
curl -L -o validator_cli.jar \
  https://github.com/hapifhir/org.hl7.fhir.core/releases/latest/download/validator_cli.jar

# Validate a resource/Bundle against the current US Core IG
java -jar validator_cli.jar condition.json \
  -version 4.0.1 \
  -ig hl7.fhir.us.core \
  -tx https://tx.fhir.org            # terminology server for code validation

-ig hl7.fhir.us.core pulls the current published US Core package; pin a version (e.g. -ig hl7.fhir.us.core#6.1.0) for reproducible CI. The validator exits non-zero on errors and prints issues with FHIRPath locations.

For ad-hoc checks without a JVM, paste the JSON into the public validator UI at https://validator.fhir.org (do not paste real PHI — validate synthetic or de-identified resources only).

Declare the profile you claim

US Core only validates against a profile if the resource claims it via meta.profile. Add the canonical URL for the profile you target:

{
  "resourceType": "Condition",
  "meta": {
    "profile": [
      "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition-problems-health-concerns"
    ]
  }
}

Then java -jar validator_cli.jar condition.json -ig hl7.fhir.us.core checks it against that profile's constraints, including must-support elements.

Common conformance gaps (from OpenMed output)

OpenMed NER gives you the clinical mention; US Core wants structured context. The recurring gaps when going from raw spans to US Core:

Gap US Core expects Fix in the exporter
Missing code.coding A coded value (SNOMED/ICD-10 for Condition; LOINC for Observation; RxNorm for medication) Ground the span; codeable_concept([...]) with a real coding, not just text
Missing category encounter-diagnosis/problem-list-item (Condition), laboratory/vital-signs (Observation) Set category in the resource shell
Missing clinicalStatus / status Required status fields Set them per the exporting-to-fhir cheat-sheet
Missing subject A resolvable Patient reference Reference an in-Bundle Patient; let to_bundle rewrite it
Unbound valueQuantity.code UCUM unit code Use system: http://unitsofmeasure.org + UCUM code
Vital signs not on the vitals profile us-core-vital-signs shape (LOINC code, vital-signs category) Use the vitals LOINC + category

"Must-support" means the producer must populate the element when the data exists. The validator flags must-support omissions as warnings; certified systems may reject them.

Workflow

  1. Export + assemble the Bundle (exporting-to-fhir, assembling-fhir-bundles).
  2. Add meta.profile for the US Core profile each resource targets.
  3. Run validator_cli.jar with -ig hl7.fhir.us.core and a -tx server.
  4. Read the issues: error = will be rejected; warning = must-support / best practice. Fix errors in the exporter, not by hand-editing JSON.
  5. Re-validate until clean; wire the validator into CI on synthetic fixtures.
  6. Submit (assembling-fhir-bundles for the transaction POST).

Turn validator output into an OperationOutcome

If you run validation programmatically, adapt the result into a FHIR OperationOutcome with OpenMed's helper so the rest of your pipeline speaks one shape:

from openmed.clinical.exporters.fhir import from_validation_result

# `result` exposes issues, or errors/warnings/information buckets
outcome = from_validation_result(result)   # -> R4 OperationOutcome dict

from_validation_result understands either an issues collection or errors/warnings/information buckets (strings or issue objects) and emits a clean R4 OperationOutcome (all-ok when empty). It only reads structural metadata — keep diagnostics PHI-free.

Hand-off to / from OpenMed

  • Validate OpenMed-produced FHIR: the input is the Bundle from assembling-fhir-bundles; the output is conformance issues you fix back in exporting-to-fhir.
  • OperationOutcome bridge: from_validation_result / to_operation_outcome / OperationOutcomeIssue (all in openmed.clinical.exporters.fhir) convert validator findings to R4.
  • No PHI in validation: validate synthetic or de-identified resources. If a narrative might carry PHI, run openmed.interop.fhir_operations.de_identify_bundle first.

Edge cases & gotchas

  • No meta.profile, no profile check. The validator validates base R4 only unless the resource claims the profile (or you force it with -profile <url>).
  • Terminology binding needs a -tx server. Without -tx, code-system / value-set bindings are not fully checked; many US Core required bindings will be missed. Point -tx at https://tx.fhir.org or your own Ontoserver.
  • Pin the IG version in CI (hl7.fhir.us.core#<version>). US Core revisions change must-support and bindings; an unpinned run drifts.
  • Reference resolution in Bundles. Validate the whole Bundle so urn:uuid references resolve; validating a lone resource flags references it cannot see.
  • USCDI ≠ US Core. USCDI is the data-element regulation; US Core is the FHIR profile set that implements it. Conform to the US Core profile for the matching USCDI class.
  • Warnings can still block ingestion. Some EHRs reject must-support omissions even though the validator calls them warnings. Treat must-support as required for production.

Standards & references

Info
Category Development
Name validating-us-core
Version v20260803
Size 7.43KB
Updated At 2026-08-04
Language