Reliable HL7® v2 → FHIR® Integration Platform for Modern Healthcare

Focus on your healthcare application. Let FireSonic handle interoperability.

Receive HL7 v2, transform it into production-ready FHIR R4, apply site-specific workflow logic, validate clinical context, and deliver with durable processing and operational visibility.

FireSonic Console dashboard
FireSonic Console messages list
FireSonic Console TLS certificates
FireSonic Console semantic rules
Platform pillars

Interoperability designed for production

A focused interoperability layer built around reliable processing, Groovy™ customization, semantic quality, operational visibility, and practical modernization.

Reliable Processing

Durable persistence, queueing, retries, restart recovery, and explicit processing states.

Code-First Customization

FireSonic handles standard mapping in the platform core. Customize local workflows with Groovy.

Semantic Validation

Context-aware checks catch technically valid but operationally suspicious clinical data before delivery.

Production Observability

Administration, health, metrics, status tracking, diagnostics, and operational traceability.

Modernization Without Replacement

Integrate existing hospital systems and expose reliable FHIR without replacing the systems that run care.

Modernization path

Don’t Replace Legacy. Modernize It.

Keep the HIS/EMR, LIS, RIS/PACS, and device workflows you already operate. Add FireSonic as the interoperability layer between HL7 v2 and modern FHIR applications.

FireSonic modernization architecture connecting legacy healthcare systems over HL7 v2 to a FHIR Server or CDR and modern applications.
Less custom engine code

Produce production-ready FHIR with less custom interface-engine code

FireSonic handles the standard HL7 v2 → FHIR transformation in the platform core. Use Groovy for site-specific normalization, enrichment, reconciliation, workflow behavior, and external integrations.

From event messages to reliable FHIR state

1

HL7 event → FHIR state

Interpret event-driven messages into the resulting resource state.

2

HL7 action code → transaction operation

Create, update, cancel, and merge semantics influence transaction behavior.

3

Business identifier → idempotency

Stable identifiers help determine create versus update decisions.

4

Segment grouping → resource topology

Preserve relationships when groups become linked FHIR resources.

Start building

Community Edition and Developer SDK

Run the platform locally, inspect real HL7 → FHIR output, and develop customer-specific logic in a familiar code-first workflow directly in your IDE — including IntelliJ IDEA or Eclipse.

Community Edition

Run FireSonic locally or with Docker®

Evaluate the platform with HL7 intake, FHIR R4 transformation, Groovy scripting, semantic rules, FHIR delivery, and administration.

  • MLLP intake
  • Built-in core mapping
  • Groovy customization
  • Semantic validation
  • Administration console
Developer SDK

Develop and test customer workflows locally

Use lifecycle hooks, FHIR client APIs, managed HTTP access, caches, retry utilities, metrics, and semantic rule DSLs.

  • Groovy lifecycle hooks
  • FHIR client
  • Managed HTTP client
  • Cache and retry APIs
  • Semantic rule DSL
Groovy examples
@Override
Bundle postConvert(MessageEnvelope envelope, Bundle bundle) {
    bundle.entry
        .findAll { it.getResource() instanceof Patient }
        .each {
            it.getResource().getMeta().addProfile(
                "http://hl7.org/fhir/us/core/" +
                "StructureDefinition/us-core-patient"
            )
        }

    return bundle
}
@Override
MessageEnvelope preConvert(MessageEnvelope envelope) {
    def msg = envelope.hl7Message

    // Normalize local sex value W to F before conversion.
    if (HL7Helper.get(msg, "/PID-8") == "W") {
        HL7Helper.set(msg, "/PID-8", "F")
    }

    // Customer sends visit number in a non-standard field.
    HL7Helper.copy(msg, "/PV1-50-1", "/PV1-19-1")

    return envelope
}
@ScriptProperty("defaultTimezone")
String defaultTimezone = "-0800"

@Override
MessageEnvelope preConvert(MessageEnvelope envelope) {
    def msg = envelope.hl7Message

    HL7TimezoneNormalizer.applyTimezone(
        msg, defaultTimezone,
        ["/MSH-7", "/EVN-2-1", "/PV1-44-1"]
    )

    HL7TimezoneNormalizer.applyTimezoneRepeated(
        msg,
        "OBR",
        [6, 7, 8, 14, 22],
        defaultTimezone
    )

    return envelope
}

Focus on your healthcare application.

Let FireSonic handle interoperability.