FHIR Health Data
The @openinsure/fhir package provides FHIR R4 resource builders and serializers for programs that process health data — primarily stop-loss, group captive health, and HIPAA-regulated lines.
Supported Resources
Section titled “Supported Resources”| Resource | Description |
|---|---|
| Patient | Member demographics — name, DOB, MBI/member ID |
| Coverage | Insurance plan, group, and subscriber information |
| Claim | Healthcare claim submitted to the plan |
| ExplanationOfBenefit (EOB) | Adjudicated claim with payments, adjustments, denials |
| Bundle | Transaction bundle wrapping multiple resources |
Building a Claim Bundle
Section titled “Building a Claim Bundle”The most common operation is constructing a Bundle containing a Patient, Coverage, and Claim for stop-loss submission to the reinsurer.
The chargeAmount and totalCharge fields in buildClaimBundle() accept dollar amounts as number values for backward compatibility. Internally the package converts them to integer-cent Money objects via money() for precise arithmetic.
import { buildClaimBundle } from '@openinsure/fhir';
const bundle = buildClaimBundle({ claimId: 'CLM-FHIR-2025-001', claimNumber: 'CLM-2025-001', patient: { id: 'pat-001', firstName: 'Jane', lastName: 'Smith', dateOfBirth: '1978-04-12', memberId: 'M-00123', }, policy: { id: 'pol-001', policyNumber: 'GRP-2025-ACME', effectiveDate: '2025-01-01', }, payer: { id: 'org-payer', name: 'Acme Health Plan' }, provider: { id: 'org-provider', name: 'University Medical Center', npi: '1234567890' }, diagnosisCodes: ['J18.9'], lines: [ { code: '99291', unitPrice: 4_200.0, quantity: 1, serviceDate: '2025-06-15' }, { code: '99292', unitPrice: 2_100.0, quantity: 3, serviceDate: '2025-06-15' }, ],});
// bundle → FHIR R4 Bundle (collection type)// Serialize with JSON.stringify(bundle) for API submissionExplanationOfBenefit
Section titled “ExplanationOfBenefit”Build an EOB from a settled claim to provide the member with an adjudicated benefit statement:
import { buildEobResource, buildClaimResource } from '@openinsure/fhir';
const claim = buildClaimResource(input);const eob = buildEobResource(claim, { paidAmount: 8_925.0, // dollars — converted to Money internally deniedAmount: 1_575.0, // deductible + coinsurance outcome: 'complete',});
// eob.total[0].amount → { currency: 'USD', value: 8925 } (FhirMoney wire format)Mapping OpenInsure → FHIR
Section titled “Mapping OpenInsure → FHIR”| OpenInsure field | FHIR resource | Element |
|---|---|---|
claim.claimNumber | Claim.identifier[0].value | Business identifier |
policy.policyNumber | Coverage.identifier[0].value | Coverage ID |
member.memberId | Patient.identifier[0].value | Member ID |
claim.dateOfLoss | Claim.billablePeriod.start | Service date |
claim.totalIncurred | Claim.total.value | Total charge |
claim.status | Claim.status | active / cancelled / draft |
Serialization
Section titled “Serialization”FHIR resources are serialized to JSON by default. XML is available via serializeFhirResource():
import { serializeFhirResource } from '@openinsure/fhir';
const xml = serializeFhirResource(bundle);// → <Bundle xmlns="http://hl7.org/fhir">...</Bundle>HIPAA PHI Fields
Section titled “HIPAA PHI Fields”The following fields in FHIR resources are classified as PHI and are subject to HIPAA controls:
Patient.name,Patient.birthDate,Patient.address,Patient.telecomPatient.identifier(member ID, SSN, MBI)Claim.patientreference- All
ExplanationOfBenefitfields linked to aPatient
PHI fields are:
- Redacted in Langfuse observability traces (see
HIPAA_REDACT_FIELDSconfig) - Isolated in the HIPAA schema partition in PlanetScale
- Encrypted at rest in R2 using envelope encryption
See HIPAA Compliance for the complete PHI taxonomy and audit log requirements.
Financial Precision
Section titled “Financial Precision”Internal calculations use the integer-cent Money type from @openinsure/rating to avoid floating-point rounding errors. The FHIR wire format (FhirMoney) uses a decimal value field per the FHIR R4 spec.
Conversion utilities are exported from @openinsure/fhir:
fhirMoneyToMoney(fm)— Converts a FHIR{ currency, value }object to a canonicalMoney(integer cents).moneyToFhirMoney(m)— Converts aMoneyto the FHIR decimal wire format.
import { fhirMoneyToMoney, moneyToFhirMoney } from '@openinsure/fhir';import { money, toDollars } from '@openinsure/rating';
const m = money(275.5); // { cents: 27550, currency: 'USD' }const fhir = moneyToFhirMoney(m); // { currency: 'USD', value: 275.5 }const back = fhirMoneyToMoney(fhir); // { cents: 27550, currency: 'USD' }Integration Points
Section titled “Integration Points”- Stop-loss claims →
buildClaimBundle()formats claims for reinsurer submission via 837P or FHIR REST API - EOB delivery →
buildEOB()generates member-facing EOBs stored in R2 and surfaced in the portal Documents tab - Member enrollment →
PatientandCoverageresources are created from 834 EDI enrollment feeds (see X12 EDI) - Data export → FHIR Bundle export for payer-to-payer data exchange under CMS interoperability rules