HL7 MSH Message Headers

All HL7 messages have one segment in common, they all start with a message header (MSH). It’s used to describe all the metadata surrounding the message as it goes from one system to another. Here I will go through all the fields and attempt to shed some light on their usage from my own personal experience.

It’s important to remember that many of the fields listed below are optional, just because they are listed here doesn’t mean you have to use them. The HL7 Soup sample messages are based on real messages, and you’ll find that many don’t go past the HL7 version number at MSH-13, and none make it all the way to MSH-21.

So let's go through each of the fields available to us and describe their use.

MSH-1 and MSH-2: The Message Formatters

An HL7 message actually describes how it is formatted, and it uses the first two fields to do it.

The MSH-1 is a bit of an oddity in that it not only says what the field separator character is, but it also gets to be counted as a field in its own right. You can actually change it to another character; pretty much any that you like, then use this instead of pipes throughout the entire message. But before you do, just let me say one thing – Never do it! You're just going to end up in a world of hurt when you attempt to integrate with other systems that don't work with your format.

MSH-2 contain all the other characters that define the message format. ^'s separate Components, ~'s divide repeat fields, \'s allow for escape characters and & separate Sub Components. If you are unsure what these are then I suggest you take a look at the HL7 Message Structure Tutorial. Once again I suggest that you never change any of these from their defaults.

MSH-1 and MSH-2

MSH-3 to MSH-6: Applications and Instances

Here are our sender and receiver details. It allows the message to describe which system sent it, and which system is expected to receive it. The MSH-3 and MSH-5 describe the applications responsible for the send and receive. These can be divided into components if you need specifics, but I prefer to keep them simple. The MSH-4 and MSH-6 represent the facility, which I like to think of as the department or location. In a hospital there might be many instances of the same application, so the facility allows you to add some more details about what or where the application is being used from. Examples include "Lab1" or "Radiology Dept".

MSH-3 to MSH-6

MSH-7: The Message Date

Here we have the date the message is sent. It's the job of the sending application to make sure that this is set. Don't rely on it though as it might be a re-sent message that is dated in the past. It is in the usual HL7 format of yyyyMMddHHmmss for most applications.

Remember: If you select a date field in HL7 Soup it will show you it formatted to your local preferences.

MSH-8: Security

Here you might place a rolling code to confirm the sender isn’t being spoofed, or some other security related value. The HL7 standard itself doesn’t actually give any example of what you could use. Most messages I have encountered just leave this empty. It’s far more common to ensure the origins of the message from the sending protocol, or simply by sending the message on a closed network.

MSH-9: Message Types

Finally, nine fields in and we define what the message is about. It’s a big topic, so I created a video that covers this field in depth - HL7 Message Types. Common message types include ADT (Admission, Discharge, and Transfer), SIU (Appointments), ORM (Orders), ORU (Observations), and MDM (Documents), but it varies depending on what you are working on. Each of these Message Types have accompanying Event Types, which provide more depth to the message. HL7 Soup gives you a drop down that lists them all for you – easy.

MSH Message Type Selection

MSH-10: Message Control ID

This is the main identifier of the message, normally incrementing by one after each message. Created by the sending application, it is also returned back in the acknowledgement response message (ACK) from the receiving application.

MSH-11: Processing ID

Here we can provide details of how the message should be treated when processing. P is commonly used for production, where T is Training. It’s worth noting that just because you state it’s a training message doesn’t mean that the listening system cares – it may very well treat it the same as production. Make sure that the other system caters for this when you need to use it.

The same can be said for the second component. Here you can define A for Archive, R of Archive Restoration, and I for Initial Load. If you don’t provide a 2nd component then it is just treated a normal processing.

Table 0103 - Processing ID

Value

Description

D

Debugging

P

Production

T

Training


Table 0207 - Processing mode

Value

Description

A

Archive

R

Restore from archive

I

Initial load

not present

Normal Processing

MSH-12: HL7 Version

States which version of HL7 the message conforms to. Newer formats maintain backwards compatibility with the old ones, but not every Segment, Field, or Component can be understood in older versions. There is no need to try and get your system to the highest version possible, rather if you stick to the oldest version your data requires then it does keep things simpler (version 2.3.1 is normally the lowest I commonly use – it’s pretty functional considering it’s from the mid 90’s). Often a country or regional governing body will provide a recommendation of which version to use in your area.

MSH-13: Sequence Number

If Messages need to be kept in an exact order then you can use the sequence number to ensure it. Increment it by one each time. Like many fields, you need to make sure both the sender and receiver agree to use this field to ensure everything is in order.

MSH-14: Separation Pointer

If you are have broken your message up into multiple messages, then you can use this to help reassemble them. It’s up to you how you do that though.

MSH-15: Accept Acknowledgement Type

Here you define when you expect a response from the receiving application.

There are two common use cases here called “Original” and “Enhanced” modes. With Original mode you just leave MSH-15 and MSH-16 empty. This implies that the receiving application will not only receive the message, but also successfully process it before it sends a response. Only after processing is the response sent.

In Enhanced mode two independent responses can be triggered. The Accept Acknowledgement Type MSH-15 is sent after the receiving application receives the message and has potentially persisted it for later processing.

MSH-16: Application Acknowledgement Type

After the message has been fully processed (e.g. written to the receiver’s database) the Application Acknowledgement Type rule kicks in and potentially returns an ACK to the sender.

The original acknowledgment protocol is equivalent to MSH-15 = NE and MSH-16 = AL.

Table 0155 - Accept/application acknowledgment conditions

Value

Description

AL

Always

NE

Never

ER

Error/reject conditions only

SU

Successful completion only

Note: IfMSH-15-accept acknowledgment typeandMSH-16-applictation acknowledgment typeare omitted (or are both null), the original acknowledgment mode rules are used.

MSH-17: Country Code

States the country of origin for the message. It uses the ISO 3166 list of countries to define regional related values - things like currency. It doesn’t however affect the date format of message – that sticks to the usual yyyyMMddHHmmss format. In my experience I find this field more appropriate for European countries where messages are more likely to go across political boundaries. Countries like USA, Canada, Australia and New Zealand tend to always stay within their own borders.

MSH-18: Character Set

The default is ASCII, but it really isn't up to the task. If you want to support European characters such as ö or ä then you use UTF-8 by putting "UNICODE UTF-8" into the MSH-18. In fact UTF-8 is really what all modern HL7 applications use as their default send/receive encoding, including HL7 Soup. If UTF-8 isn’t going to cut it in your region, then have the sending application state their encoding. This ensures that the receiver will be able to decode it properly.

MSH-19: Principle language

The principal language of the message. That is really just the user defined fields you might use as HL7 tables tend to have more of an English mapping to them. You’re welcome to make things how you like them for your language though.

MSH-20: Alternative Character set

Only available in HL7 version 2.3.1 or greater, it allows for character set switching in the message.

MSH-21: Message Profile Identifier

Only available in HL7 version 2.4 or greater. Claims that message conforms to a set of requirements that is agreed upon in a shared profile between the sender and the receiver.

Here are all the MSH Fields and their properties

 

Number

NAME

Max Length

Data Type

Required /Optional

1

Field Separator

1

ST

R

2

Encoding Characters

4

ST

R

3

Sending Application

180

HD

O

4

Sending Facility

180

HD

O

5

Receiving Application

180

HD

O

6

Receiving Facility

180

HD

O

7

Date/Time Of Message

26

TS

O

8

Security

40

ST

O

9

Message Type

7

CM

R

10

Message Control ID

20

ST

R

11

Processing ID

3

PT

R

12

Version ID

8

ID

R

13

Sequence Number

15

NM

O

14

Continuation Pointer

180

ST

O

15

Accept Acknowledgment Type

2

ID

O

16

Application Acknowledgment Type

2

ID

O

17

Country Code

2

ID

O

18

Character Set

6

ID

O

19

Principal Language

60

CE

O

Download 30 Day Free Trial of HL7 Soup