Skip to content

The openEHR Reference model defines a relatively small set of information model constructs which openEHR back-ends must support. This includes a number of generic classes and datatypes.

The Reference model contains virtually no clinical content e.g concepts for Medication, or Diagnosis. These are defined and managed separately as archetypes.

Key openEHR datatypes

openEHR has a very rich set of allowable datatypes. A full definition is beyond the scope of this document but developers new to this field may find the following notes helpful.

Datatype: text

Allows the recording of simple, unformatted text. openEHR does not normally constrain the length of string.

asthma_diary_entry/history:0/story_history/comment: Feeling much better,

Datatype: codedText

Is a commonly used datatype in openEHR systems and is a sub-class of text. i.e where-ever text is specified codedText can be used instead.

Codes may be 'external' e.g. SNOMED CT or 'local', where they are defined within archetypes, have the form 'atxxxxx' and are commonly referred to as 'atCodes'

A codedText element always includes the terminologyID, the code itself and the text of the coded concept (Rubric). Where a codedText item is required, allowed value(s) are expressed in the form:

terminologyId::code::rubric

local::at0007::Dental swelling
SNOMED-CT::123456::No pathology found

When a codedText item is added to a FLAT JSON format document, you must give the code, value and terminology, unless this is a local (atCode) code, in which case only the code needs to be provided.

External terminology e.g SNOMED CT

Code, terminology and value must be specified

'asthma_diary_entry/history:0/story_history/symptom:0/symptom_name|code': '23924001',
'asthma_diary_entry/history:0/story_history/symptom:0/symptom_name|value': 'chest tightness',
'asthma_diary_entry/history:0/story_history/symptom:0/symptom_name|terminology': 'SNOMED-CT',

Local 'atCode' e.g at0007

Only the code needs to be specified - the value and terminology are not required since they are pre-defined in the openEHR template..

'asthma_diary_entry/examination_findings:0/pulmonary_function_testing:0/result_details/pulmonary_flow_rate_result/test_result_name|code': 'at0071'

Datatype: ordinal

Combines codedText with a score, expressed as an integer.

0: Green  `local::at0022::Green`
1: Amber  `local::at0023::Amber`
2: Red    `local::at0024::Red`

'community_dental_final_assessment_letter/assessment_scales/dental_rag_score:0/caries_tooth_decay/caries_risk|code': 'at0024',
'community_dental_final_assessment_letter/assessment_scales/dental_rag_score:0/caries_tooth_decay/caries_risk|ordinal': 2,
'community_dental_final_assessment_letter/assessment_scales/dental_rag_score:0/caries_tooth_decay/caries_risk|value': 'Red',

Datatype: count

count is a simple integer.

'community_dental_final_assessment_letter/investigations_and_results:0/imaging_examination_result:0/result_group/decayed_teeth/decayed_teeth': 4,

Datatype: datetime

Records a date or date and time using the ISO8061 format.

'ctx/time': '2014-09-23T00:11:02.518+02:00'

Datatype: quantity

Records a physical quantity along with the appropriate SI units, which should normally be compliant with UCUM.

"asthma_diary_entry/examination_findings:0/pulmonary_function_testing:0/result_details/pulmonary_flow_rate_result/actual_result|magnitude": 550,
"asthma_diary_entry/examination_findings:0/pulmonary_function_testing:0/result_details/pulmonary_flow_rate_result/actual_result|unit": "l/min",

Key openEHR concepts and classes

External identifiers

The subjectId (sometimes called externalId) is a patient identifier by which the patient is known outwith the openEHR system e.g. a hospital identifier or NHS number.

EHR

In an openEHR system, each patient has an ehr (a per-patient electronic health record) with a unique ehrId identifier (usually a guid). All references to openEHR patient data are via this ehrId. An API call GET ehr/ is used to reference the ehrId from the provided subjectId/externalId.

Example ehrId: 8fa77360-683c-4989-be5e-89a192624b43

Other subsequent calls to the openEHR system for that particular patient are via the ehrId.

COMPOSITION

All openEHR data is committed inside a composition, a document-level container which is given a unique compositionId. If the composition is subsequently updated the root compositionId remain unchanged but its version number is incremented. All previous composition versions are retained for audit/legal purposes.

Initial version
2cf04d6c-31e8-4599-a14b-9a0add4de5d9::fivium.ehrscape.com::1

Revised version
2cf04d6c-31e8-4599-a14b-9a0add4de5d9::fivium.ehrscape.com::2

If you need to retrieve a composition, it is normally ok to simply use the root part 2cf04d6c-31e8-4599-a14b-9a0add4de5d9 which will return the latest revision in the current repository.

openEHR Composition file formats

In general, committing or retrieving a composition to/from an openEHR system involves sending or receiving a structured XML or JSON file via a simple API.

The current standard 'canonical XML' openEHR Composition format is defined by a set of standard schema.

More recently, openEHR implementers have started to develop alternative custom JSON formats (usuually with converters to/from the canonical XML format).

The Better Ehrscape API,eveloped by Better, provides a simple restful API which hides much of the complexity of the underlying openEHR server accepting simpler, flatter forms of composition data, using defaults within the template schema to correctly populate the raw openEHR data which is stored internally.

The FLAT JSON format is just a set of simple name/value pairs where the 'name' carries the path to each element. You do not need to parse this path. You should normally use this FLAT JSON format, which is easier for new openEHR users. e.g.

  • FLAT JSON format
    "community_dental_final_assessment_letter/assessment_scales/dental_rag_score:0/caries_tooth_decay/clinical_factors|code": "at0025", …

  • STRUCTURED JSON format

    
    "clinical_factors": [
     {
     "|code": "at0025",
     "|terminology": "local",
     "|value": "Teeth with carious lesions"
     }
     ]
    
    
  • RAW XML format

    <ns2:value xsi:type="ns2:DV_CODED_TEXT">
    <ns2:value<Teeth with carious lesions</ns2:value>
    <ns2:defining_code>
    <ns2:terminology_id>
    <ns2:value<local</ns2:value>
    </ns2:terminology_id>
    <ns2:code_string<at0025</ns2:code_string>
    </ns2:defining_code>
    </ns2:value>
    </ns2:value>

Key openEHR Reference model attributes

A number of key data points need to be populated in an openEHR composition, which may not be apparent from the archetypes or templates. Developers can largely use the example instance documents and APIs for guidance but these notes may give useful background in addition to viewing the UML view of the openEHR reference model.

committer

This is the name of the person physically committing the document ie. the person logged on to the account. If omitted from API calls, Ehrscape will use the domain login name.

composition/composer

This is the clinical author of the document i.e the person with clinical responsibility. Ehrscape FLAT and STRCTURTED formats handle this as composer_name.

composition/context/start_time

This is the time that the clinical interaction with the patient began. Ehrscape FLAT and STRUCTURED formats handle this as ctx/time.

composition/context/health_care_facility

This is the healthcare facility / oragnisation under who’s remit the encounter took place.

observation/time

This is the time that a patient’s signs and symptoms were observed or a test was run. It is set automatically by the value of the ctx/time attribute. If you need to set the time of a specific observation you can use

The Ehrscape FLAT and STRUCTURED formats hide much of the complexity of these attributes, providing sensible defaults. In particular the ctx header common to both JSON STRUCTURED and FLAT formats, considerably simplifies the composition header …

'ctx/composer_name': 'Rebecca Wassall',
'ctx/health_care_facility|id': '999999-345',
'ctx/health_care_facility|name': 'Northumbria Community NHS',
'ctx/id_namespace': 'NHS-UK',
'ctx/id_scheme': '2.16.840.1.113883.2.1.4.3',
'ctx/language': 'en',
'ctx/territory': 'GB',
'ctx/time': '2014-09-23T00:11:02.518+02:00',

Handling specific openEHR datatypes

text

Text handling is normally straightforward.

FLAT + STRUCTURED

"synopsis": [
 "Significant dental issues."
 ]

codedText

For an external terminology, the terminologyId, code and text value must be supplied but in JSON FLAT and STRUCTURED formats only the local 'atcode' needs to be supplied.

STRUCTURED JSON format

 Internal (local) code:
 "dental_swelling": [
 {
 "|code": "at0006",
 }
 ]

 External terminology:
 "symptom_name": [
 {
 "|code": "102616008",
 "|terminology": "SNOMED-CT",
 "|value": "Painful mouth"
 }
 ]

FLAT JSON format

 Internal (local) code:
 "community_dental_final_assessment_letter/examination_findings:0/physical_examination_findings:0/oral_examination/dental_swelling|code": "at0006"

 External terminology:
 "community_dental_final_assessment_letter/history:0/story_history:0/symptom:0/symptom_name|value": "Painful mouth",
 "community_dental_final_assessment_letter/history:0/story_history:0/symptom:0/symptom_name|code": "102616008",
 "community_dental_final_assessment_letter/history:0/story_history:0/symptom:0/symptom_name|terminology": "SNOMED-CT"

ordinal

For JSON FLAT and STRUCTURED formats only the local 'atcode' needs to be supplied although the ordinal and text value are also accepted FLAT JSON format

"community_dental_final_assessment_letter/assessment_scales/dental_rag_score:0/caries_tooth_decay/caries_risk|code": "at0024"

STRUCTURED format

 "caries_risk": [
    {
    "|code": "at0024",
    }
    ]

or

 "caries_risk": [
 {
    "|code": "at0024",
    "|ordinal": 2,
    "|value": "Red"
 }
 ]

date

Dates need to be persisted in the ISO8061format and should be displayed in CUI format e.g. 12-Nov-1958

Tricky issues

Converting UI checkboxes to/from codedText

In a number of places, the UI may best be represented as a set of checkboxes, while the underlying data is modelled as codedText.

e.g. Symptoms

While it may seem more easier and more logical to use a boolean datatype, this is a common pattern in openEHR datasets which are designed to be interoperable and extensible. Experience has shown that expansion of the target valueset and alignment to external terminologies is easier if an enumerated list of codedText is used rather than boolean.

In the case of 'Symptom' the rule is …

  • If the checkbox is ticked, populate the Symptom name with the SNOMED-CT term

  • If the checkbox is unticked, omit the Symptom name element completely.

Conversely when loading a persisted dataset, the checkbox should only be checked if the Symptom name element is present and contains SNOMED-CT term 102616008.

Multiple occurrence data

Some aspects of the form e.g Symptoms are handled as multiple occurrences of the same data point in the underlying dataset.