PPT HL7 Guide
The HL7 Guide helps IT staff who already handle HL7 data get started using PPT with their HL7 software. If you don't use an HL7 system, manual data entry is available from the user account. The instructions for user account Signup is presented separately.
To admit OBX or RXA messages into PPT, follow these instructions:
- Make three transforms on the source message (MSH.4.1, MSH.4.2, and MSH.21 to insert the provider code, provider name, and private key to match the user account).
- Move the patient recognized PIN to PID.4 if it's not in PID.3 and add "ANON" as CXT.5 to the segment containing the PIN, if necessary. Delete all other identifiers of type "ANON"
- Delete all personally identifiable information in PID or elsewhere (use the same rules used to report to Public Health).
- Transmit to publicpandemictools.com/hl7/receiver
- Let PPT parse and validate.
- Check ACK for an error description on reject
The test result or RXA will be available to patients after selecting their provider and entering their PIN. Querying and updating, as with a full blown HL7 server, is limited to a new message with an updated OBX result status.
If you're experienced with HL7, see the Documentation section below to discover details necessary to create your own custom workflow.
- MSH 4.1 as patient recognized Provider Code
- MSH 4.2 as patient recognized Provider Name
- MSH 21 as your Private Key
- Patient recognized PIN in PID.3 or PID.4 with CXT.5 "ANON"
- De-identified personal data
- OBX 3 as the LOINC code for the CDC approved test
- OBX.11, if used, must be "F" or "C"
- RXA.5 Admin Code (if reporting RXA)
- RXA.3 Start Date/Time (if reporting RXA)
- One MSH, PID, and OBX or RXA per message
If the message fails any one of these requirements, it will be rejected or result in unexpected behavior.
Sample HL7 Template:
The template shows the required values and placeholders for segments and components used by PPT.
The segments and components used by PPT may help overcome unusual limitations on creating your workflow. The processing rules may help you understand error output and implement a fix.
- MSH 4.1 and 4.2 Sending facility as provider (Required; must match user account)
- MSH 9, 10, 11, 14, 15 (Optional; used for ACK which defaults to enhanced)
- MSH 21 Message profile identifier (Required: must include key in user account)
- PID 3 Patient recognized PIN (included here or in PID 4)
- PID 3.5 Identification type (must be "ANON")
- PID 4 Patient recognized PIN (if not found in PID 3)
- PID 4.5 Identification type (must be "ANON", not used if PID 4 empty)
- PID 11.3 City name (Optional; use if permitted or leave blank if unsure)
- PID 11.7 Address type (Not 'BA' or 'RH'; list precedence 'C','H','P','B','O','n/a','L','M')
- PID 12 County code (Optional; use if permitted or leave blank if unsure)
- OBR 4 LOINC test code (Required; here or in OBX 6)
- OBR 7 Collection date (if not found in OBX 14)
- OBX 3 LOINC test code (if not found in OBR 4)
- OBX 6 LOINC result unit
- OBX 6.1 LOINC result code
- OBX 6.2 Result description
- OBX 6.3 Coding system ("SCT" is expected)
- OBX 8 Abnormal flags (Used if no OBX 6; anything not 'N' is 'Positive' else 'Negative')
- OBX 11 Result status (Must be 'F' or 'C')
- OBX 14 Collection date (If not given, OBR 7 used)
- OBX 19 Test date
OBX and RXA are processed as separate messages using the same authentication, patient information, and geolocation logic. If the Admin Code is on an approved list, the Vaccine Information Sheet may be available.
- RXA 2 Sub ID Counter (for display purposes only)
- RXA 3 Start date/time of administration (Required; RXA 4 end date is not used)
- RXA 5 Admin code (Required; should be CVX or other official code)
- RXA 6 Admin amount
- RXA 7 Admin units
- RXA 10 Administering provider
- RXA 11 At location
- RXA 15 Lot number
- RXA 16 Expiration date
- RXA 17 Manufacturer name
- RXA 18 Refusal reason
- RXA 20 Completion status (must be 'CP' or empty)
- Messages received after basic authentication are first validated against the user account provider code, provider name, and private key based on values in MSH.4.1, MSH.4.2, and MSH.21.
- The message is scanned for the first PID containing an identifier in PID.3 or PID.4 of type 'ANON'. Any following OBX or RXA segments are assumed to be for that PID. Scanning for OBXs and RXAs does not resume from the last PID.
- The message is scanned for all RXAs with RXA.5 Admin Code non-empty, RXA.20 Completion Status empty or 'CP', and RXA.3 Admin Start Date valid. If region is USA, the RXA is rejected if RXA.5 using CVX values is not on the CDC approved list else processing for the RXA continues.
- The message is scanned for all OBXs with OBX.11 Result Status 'C' or 'F' and OBX.3 on the approved CDC list and OBX.14 a valid date. If OBX does not contain values for OBX.14 Observation Date or OBX.3 Observation Identifier, the message is scanned upward for the first OBR before the next previous OBX having OBR.4 or OBR.7. Those values are used if available.
- If no RXAs or OBXs are found, the message is rejected with error message "RXA or OBX with a LOINC code on the CDC list of approved Covid-19 tests was not found..."
- The region is checked for centralized test result delivery. If not from the designated sender, the message is rejected with the error "Your regional public health is using centralized test result delivery for aggressive pandemic suppression. You must submit to the regional public health system for automatic forwarding to this System."
- IP or Host name restrictions are enforced if given in the user account. If the check fails, the message is rejected with error "Authentication failed. Verify allowed IP / Host source addresses in data settings of your user account. Current IP [listed here], host [hostname here]."
- Geolocation data (city, postal code, county) is extracted from the PID if available and is emptied if found unusable by the user account else location is the concantonation of county, city, and postal code. If postal code is present, the region and postal code is geocoded. If city is present, the city and region is geocoded. If county is present, the county and region is geocoded. If geocoding fails, the OBX will not appear in public searches for the virus.
- The OBXs are iterated and checked for a LOINC code, collection date or test date, and the custom result unit (OBX.6.1). The duplicate check is based on user id, PIN, LOINC, collection date, test date, and result. If any one check fails, an error string is appended to the response as an ERR segment with a description.
- The OBXs are saved as user id, PIN, LOINC, result, collection date, test date, GPS point, and location.
- The RXAs are iterated and checked for a valid RXA.3 Admin Start Date and non-empty RXA.5 Admin Code. If either are not found, an ERR segment is appended to output with a description. RXA components are made human readable by replacing the component separator with a space for RXA.6, RXA.7, RXA.9, RXA.10, RXA.11, RXA.15, RXA.16, RXA.17, RXA.18, RXA.20. Those values will be used for the vaccination record.
- If the region is not USA and RXA.5 Admin Code is not on the CDC approved list, an ERR segment is appended to output "Vaccine not found on approved list for Covid-19 but continuing anyway..." The duplicate check uses user id, PIN, admin code, admin start date, and completion status. If found, an ERR segment is appended to output "Duplicate vaccination record (user, PIN, admin_code, admin_date exact match)." The RXA save fails.
- The RXA is saved as user id, PIN, admin sub id, admin date, admin code, admin amount, admin units, admin provider, admin at location, lot number, expiration date, manufacturer, refusal reason, completion status, location, and GPS point. If save fails, an ERR segment is appended to output "Unable to save RXA. Service temporarily unavailable." RXAs iteration continue.
- The ACK message is formulated based on MSH.14 and MSH.15 and the message control id, processing id, and version id is included if given in MSH. Any ERR segments are appended.
- The MSA acknowledgment and associated ERR segments are printed and the script shutsdown without a "Connection: close" header.