ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

MessageHeader — Messaging routing header

The FHIR equivalent of HL7 v2's MSH segment. Always the first entry of a Bundle of type message, it carries sender, receiver, event and routing data.

Purpose

FHIR messaging is one of the four interoperability paradigms (alongside REST, documents, services). It consists of carrying a Bundle of type message containing a business event — typically clinical or administrative — from a sending system to a receiver, with asynchronous acknowledgment.

MessageHeader is required to be the first entry of that Bundle. It carries the routing semantics: event code, source, destination, focus (subject), reason, and optionally the asynchronous response to a previous message.

Key fields

FieldTypeCardinalityRole
event[x]Coding | canonical(MessageDefinition)1..1Mandatory. Event code (MSH-9 equivalent).
destinationBackboneElement[]0..*Recipient(s).
destination.endpointUrlurl0..1FHIR URL of the recipient.
destination.receiverReference(Organization | Device | Practitioner | PractitionerRole)0..1Receiver Organization/Device.
senderReference(Practitioner | PractitionerRole | Organization)0..1Logical sender.
authorReference(Practitioner | PractitionerRole | Device | Organization)0..1Author (clinician driving the event).
sourceBackboneElement1..1Mandatory. Technical source system.
source.endpointUrlurl1..1Technical URL of the sender.
responsibleReference(Practitioner | PractitionerRole | Organization)0..1Legally responsible for the content.
reasonCodeableConcept0..1Reason of the message (e.g. admit, transfer).
responseBackboneElement0..1For response messages: ack of the original.
response.identifierIdentifier1..1ID of acknowledged message.
response.codecode1..1ok | transient-error | fatal-error.
response.detailsReference(OperationOutcome)0..1Error detail.
focusReference(Any)[]0..*Resources concerned by the event (Patient, Encounter...).
definitioncanonical(MessageDefinition)0..1MessageDefinition describing this event.

FHIR messaging pattern

The typical FHIR messaging exchange:

  1. System A builds a Bundle type=message with MessageHeader as the first entry and clinical resources following.
  2. A POSTs the Bundle to [base]/$process-message on receiver B.
  3. B answers either:
    • Synchronous: an immediate message-response Bundle with MessageHeader response.code=ok.
    • Asynchronous: 202 Accepted, then later B POSTs a response Bundle to A's source.endpointUrl.

JSON example

A MessageHeader notifying a patient admission (admin-notify) with an Encounter in focus:

json messageheader-example.json
{
  "resourceType": "MessageHeader",
  "id": "example",
  "eventCoding": {
    "system": "http://example.org/fhir/message-events",
    "code": "admin-notify"
  },
  "destination": [{
    "name": "PMS",
    "endpointUrl": "https://pms.example.org/fhir/messaging",
    "receiver": { "reference": "Organization/pms-org" }
  }],
  "sender": { "reference": "Organization/hospital-1" },
  "author": { "reference": "Practitioner/dr-jones" },
  "source": {
    "name": "HIS",
    "software": "Acme HIS v3.4",
    "version": "3.4.1",
    "endpointUrl": "https://hospital-1.example.org/fhir/messaging"
  },
  "responsible": { "reference": "Organization/hospital-1" },
  "reason": {
    "coding": [{
      "system": "http://terminology.hl7.org/CodeSystem/message-reasons-encounter",
      "code": "admit"
    }]
  },
  "focus": [{ "reference": "Encounter/example" }]
}

Common pitfalls

  • MessageHeader not in first position — a Bundle type=message must have MessageHeader as entry[0].resource. Otherwise rejected.
  • No source.endpointUrl — without a technical return URL, asynchronous acknowledgment is impossible.
  • Untyped event[x] — the event code must be typed by a Coding or canonical MessageDefinition.
  • Unresolvable focus — every Reference in focus must be present in the same Bundle.
  • Mixing REST and messaging — the messaging pattern is asynchronous and event-driven. Don't use it for routine CRUD: prefer REST.