In this module you will learn more about terminology. We will use Forge, the official HL7® FHIR® profile editor, to build our profiles. You can download Forge for free.

The topics covered in this module are:

  • Terminology module
  • Profiling terminology

Reading material

Terminology is about the codes you can record in your data - say a doctor picking a code for cough, or setting the status of a prescription to active.

1. The terminology module

There are a few resources in FHIR that cover (or are related to) terminology: CodeSystem, ValueSet, coded data types, ElementDefinition, NamingSystem, ConceptMap and ExpansionProfile.

A couple of these resources and their relations are shown in the image below. The next sections will explain them in more detail.

1.1 CodeSystem

A CodeSystem defines a set of concepts (codes) with a coherent meaning, for example condition-clinical is a CodeSystem in the core specification for setting the clinical status of a condition.

1.2 ValueSet

A ValueSet is a selection of codes for use in a particular context. The relation of a ValueSet to a CodeSystem is that it selects (codes from) one or more CodeSystems. The actual codes belong to the CodeSystem, while the ValueSet is composed by linking to these codes in the CodeSystem. For example, the ValueSet condition-clinical includes all codes defined in the CodeSystem condition-clinical. When the codes in the CodeSystem are updated, the ValueSet automatically contains the updated codes. The lockedDate element can be used to "freeze" the codes to a particular version of the CodeSystem. You can also link to another ValueSet to include all codes from this ValueSet.

To compose your ValueSet, use the compose element. With the include element you can add concepts or codes from one or more CodeSystems and/or other ValueSets. You can either:

  • List the codes you want to use by using the concept.code element
  • Use the filter element to select a group of codes or
  • Use the ValueSet element to refer to a ValueSet that contains a list of codes you want to include

Note that it is not possible to use both the concept and filter elements, you have to select either one of them to add codes from a CodeSystem. You can also explicitly state that particular codes from a code system or other ValueSets should be excluded by using the exclude element.

Below are examples of the use of the concept and filter elements. In the first example, two ICD-10 codes for breast cancer are included.

Example 1

      <system value='http://hl7.org/fhir/sid/icd-10-cm'/>
        <code value='C50'/>
        <code value='C50.01'/>

The second example is an example of a ValueSet that includes all codes from the Loinc CodeSystem where the parent property equals LP43571-6.

Example 2

      <system value="http://loinc.org"/> 
        <property value="parent"/> 
        <op value="="/> 
        <value value="LP43571-6"/> 

Besides the compose element, which is used to create the ValueSet, you may notice that there is also an element called expansion. This element is used in the response of a FHIR Terminology Server when a user wants to retrieve all codes from a ValueSet by using the $expand operation. This is also known as ValueSet expansion or ValueSet enumeration. The $expand operation is commonly used together with the filter operation to reduce the number of codes returned in an expansion. Note that this results in a reduced view of the ValueSet, not a change in the ValueSet itself

1.3 Coded data type

Codes in CodeSystems can have one of the following data types:

  • Code - bound to a fixed list of codes, for example gender (male - female - other - unknown)
  • Coding - contains elements to capture the system, its version, the value of the code itself and a textual representation
  • CodeableConcept - contains one or more Codings and an optional textual representation

When you are profiling and you need to choose one of these data types, the best and safest choice will usually be the CodeableConcept. As the CodeableConcept can have one or more Codings, the profile will be more reusable this way. The use of Codings is more limited and primarily used in extensions when there's need for finer control over use of translations and text.

The relation of coded data types to the other resources in the terminology module is that they refer to a CodeSystem and conform to an ElementDefinition.

1.4 ElementDefinition

An ElementDefinition defines an element in a resource or extension. For example, the Patient resource has an element called name, which is the name of the patient. The ElementDefinition of name defines the properties of the name element, for example it defines that its data type is HumanName and its cardinality is 0..*. Within the terminology module, the ElementDefinition defines the (coded) data type and the ValueSet containing the codes that you can select in this element. The ElementDefinition binds a ValueSet. The binding strength is defined in the ElementDefinition as well. We will explain this in more detail in the next chapter.

For example, let's take a look at the ElementDefinition of the clinicalStatus element.

clinicalStatusΣ ?! I0..1codeBinding
verificationStatusΣ ?! I0..1codeBinding
subjectΣ I1..1Reference(Patient | Group)
contextΣ I0..1Reference(Encounter | EpisodeOfCare)
asserterΣ I0..1Reference(Practitioner | Patient | RelatedPerson)
assessmentI0..*Reference(ClinicalImpression | DiagnosticReport | Observation)
codeΣ I0..*CodeableConcept
detailΣ I0..*Reference(Resource)


The type of this element is a code and it binds the ValueSet condition-clinical. Below you see part of the XML code of the ElementDefinition.

Condition.clinicalStatus element

<element id="Condition.clinicalStatus">
     <path value="Condition.clinicalStatus" />
     <short value="active | recurrence | inactive | remission | resolved" />
     <definition value="The clinical status of the condition." />
        <code value="code" />

ValueSet binding

    <strength value="required" />
    <description value="The clinical status of the condition or diagnosis." />
        <reference value="http://hl7.org/fhir/ValueSet/condition-clinical" />

1.5 NamingSystem

A NamingSystem is used for the unique identification of concepts, people, devices etc. A NamingSystem can either be used to define an identifier system (e.g. a patient number) or a code system (e.g. UCUM or LOINC). The kind element defines the way in which the NamingSystem is used (identifier, codesystem or root). Root means that the NamingSystem is used as the root for other naming systems. Below we’ll explain the difference between the use of the NamingSystem for identifiers and its use for CodeSystems.

1.5.1 NamingSystem for identifier

The most common use of the NamingSystem is to manage identifiers. For example, if you wanted to describe the Dutch BSN number (i.e. the Dutch security number) which used to uniquely identify Dutch citizens as a FHIR resource - you'd create a NamingSystem. This resource would have a description of what the BSN does, who manages it, and most importantly, it would also declare the identifier that can be used to refer to it in FHIR resources.

Command 'render' could not render: File was not found for nictizstu3-zib2017/bsn

1.5.2 NamingSystem for CodeSystem

It is also possible to use the NamingSystem resource to define the existence of an external CodeSystem that you don’t have control over. In this case, you can use the NamingSystem to describe the CodeSystem’s use, its owner and create an identifier for it. If you are the owner of the CodeSystem resource you would of course use the CodeSystem resource itself to define it. Below is an example of the use of the NamingSystem to define a CodeSystem.


<NamingSystem xmlns="http://hl7.org/fhir">
  <id value="example"/> 
  <name value="SNOMED CT"/> 
  <status value="active"/> 
  <kind value="codesystem"/> 
  <date value="2014-12-13"/> 
  <publisher value="HL7 International on behalf of IHTSDO"/> 
    <name value="FHIR project team"/> 
      <system value="url"/> 
      <value value="http://hl7.org/fhir"/> 
  <responsible value="IHTSDO &amp; affiliates"/> 
  <description value="SNOMED CT is a concept-based, scientifically validated terminology that provides a unique and permanent concept identifier that can be included in multiple HL7 data types including CD and CE.  The concepts are managed to avoid semantic drift; so the meaning remains constant. If the concept is found to be ambiguous or the meaning changes, the concept is inactivated but still retained and the identifier is never reused. SNOMED CT's concepts are interrelated hierarchically and using description logic. SNOMED CT concepts have a unique fully-specified name, a preferred term, and, optionally, synonyms. The description languages include English and Spanish."/> 
    <type value="oid"/> 
    <value value="2.16.840.1.113883.6.96"/> 
    <type value="uri"/> 
    <value value="http://snomed.info/sct"/> 
    <preferred value="true"/> 


1.6 ConceptMap

A ConceptMap defines a mapping from a set of concepts defined in a CodeSystem to one or more concepts defined in other CodeSystems. The source element refers to the original ValueSet and the target element to the destination ValueSet. The actual mappings are defined in the group element, where group.element.code is the original value from the source and group.element.target.code is the new value in the target destination.


    <source value="http://hl7.org/fhir/address-use"/> 
    <target value="http://hl7.org/fhir/v3/AddressUse"/> 
      <code value="home"/> 
      <display value="home"/> 
        <code value="H"/> 
        <display value="home"/> 

In this example, the home code in from the address-use ValueSet from HL7 FHIR version DSTU2 is mapped to H in the AddressUse ValueSet from version HL7 FHIR version STU3.

1.7 ExpansionProfile

An ExpansionProfile is used to configure the behaviour of a terminology server when it processes ValueSet resources. It's not necessary to understand all its details at this point, but it's good to know that they are used for the ValueSet expansion and validation operations.

2. Profiling terminology

ValueSet and CodeSystem are the two most important resources covering terminology that you will be working with. To learn more about them, head over to the excellent FHIR Drills ValueSet and CodeSystem page that describes them in detail. Read on to learn how can you profile terminology, starting with changing the binding strength.

The very first thing that you need to know is: the strength of the binding that a field has to a ValueSet. There can be four, summarised below:


Binding strength Meaning How you can profile this
Required You can only select codes from this valueset and none other You can remove codes from the valueset but you cannot add any new codes
Extensible You must select codes from this valueset, but you can use other codes if the valueset doesn't have a matching code You can add and removes codes from the valueset, but don't duplicate or replace existing ones
Preferred You should select codes from the valueset, but it's not strictly necessary You don't have to use these codes, but it's recommended that you do
Example This is just an example of codes you could use You should set this to a ValueSet of your own, or at least strengthen the binding (raise it)


2.1 Changing the binding strength

The easiest type of profiling you could do with terminology, besides fixing an element to be a specific code, is to change the binding strength. Similar to how you can only constrain and not relax the cardinality of an element (make it tighter), you can only constrain the binding of of a valueset - that is, make it stricter. You can do this in Forge by selecting an element with a coded data type (e.g. Patient.maritalStatus) and changing the strength field.



2.2 Changing the codes of the valueset

In some cases you may want to add or remove codes from an existing ValueSet. However, you can't actually edit someone else's ValueSet. In this case you will need to create your own ValueSet and define which codes you want to include. Note that you can only add codes if the binding strength is not required.

For example, let's say you want to constrain Patient.gender, which currently has a required binding to AdministrativeGender. For example, you want to constrain the "unknown" code out from this required ValueSet. This ValueSet is managed by HL7, so you will need to create your own ValueSet which includes all of the codes except the ones you'd like to exclude. Once you've got your ValueSet, change the ValueSet reference in the binding.



2.3 Binding to multiple valuesets

A common usecase that comes up is binding a file to multiple valuesets. You can't do that directly in FHIR, but here are two solutions:

  1. Create a union valueset (using ValueSet.compose.include.valueSet) that includes all the ValueSets you'd like to bind to and then bind to that. This does, however, enable users to pick from any of the codes presented.
  2. If you'd like to limit codes to a particular context, you can create derived profiles that set the binding to the specific ValueSet that is appropriate for that context.


2.4 Fixed system vs a valueset binding

While constraining terminology, you may notice that you have two ways of going about it: 1) valueset binding, and 2) fixed value:

Prefer using the valueset binding as it is more flexible: with a valueset you can include a subsection of a codesystem, codes from several codesystems, and you are not limiting supplementary codes from other codesystems from being sent along with the required ones.

Real-life examples

Here below are examples of customers that we helped building profiles.


Nictiz is the centre of expertise for standardization and eHealth in The Netherlands. HL7 Netherlands core and MedMij profiles are published on Simplifier. MedMij is a national project that aims to give Dutch citizens integrated access to all their health data in one personal health environment. FHIR is used as a standard to exchange health information between the involved parties. The profiles are based on standardized clinical building blocks called Health and Care Information Models (HCIM).

Below is an example of the Dutch profile on Medication, which is defined as the HCIM called ZIB Product.

Command 'tree' could not render: You don't have rights to view this resource.


In the Netherlands, the Z-Index maintains a classification system called the G-Standaard for medication. Different CodeSystems can be used to describe medication products and ingredients:

  • GRP - Generic product codes to describe material, strength and way of prescription.
  • HPK - Trade product codes to describe all information of a product and its supplier. Physicians use these codes to prescribe specific medication from a specific brand, for example when a patient has an allergy or intolerance for a particular material present in the same product from other suppliers.
  • PRL - Prescription codes to describe material in a broader sentence, giving a broader choice between brands. For example, a pharmacist may choose to issue a cheaper variant of the same product.

Besides the registration of G-Standaard codes, ATC codes are registered as well. The Anatomical Chemical Therapeutical (ACT) classification is a hierarchical classification of medicines on organ (system) and therapeutical and chemical properties.

Nictiz has defined different ValueSets to capture the codes from these CodeSystems. In the Dutch Medication profile called ZIB-Product, the medication.code.coding and ingredient.itemCodeableConcept.coding elements are sliced. Each slice contains a required binding to one of these ValueSets. In this way, all codes are allowed, but the receiving party can distinguish between the different CodeSystems that are used.


HelseVest is a Norwegian health authority, responsible for the western region of Norway. One of their projects is the Helsevest Prescription project, which aims to provide integrations for medication prescription. Below is an example of one of the ValueSets that is used in this project.

ValueSet 'Benevning tidsenhet'

Format URLhttp://hl7.no/fhir/ValueSet/kule-benevning-tidsenhet
Published byHL7 Norge
StatusDraft (since 2017-01-27)

Dette kodeverket inneholder benevning for tidsenheter. Skal benyttes for datatypen PQ når enhet skal være tidsenhet.

This value set includes codes from the following code systems:

The ValueSet includes all codes from the core units-of-time ValueSet, but excludes the code wk for week. Here below is the corresponding XML code.

        <status value="generated" />
                Benevning tidsenhet
                Dette kodeverket inneholder benevning for tidsenheter. Skal benyttes for datatypen PQ når enhet skal være tidsenhet.
    <url value="http://hl7.no/fhir/ValueSet/kule-benevning-tidsenhet" />
        <system value="urn:ietf:rfc:3986" />
        <value value="urn:oid:2.16.578." />
    <name value="Benevning tidsenhet" />
    <status value="draft" />
    <experimental value="false" />
    <publisher value="HL7 Norge" />
    <date value="2017-01-27" />
    <description value="Dette kodeverket inneholder benevning for tidsenheter. Skal benyttes for datatypen PQ når enhet skal være tidsenhet." />
        <import value="http://hl7.org/fhir/ValueSet/units-of-time" />
            <system value="http://hl7.org/fhir/ValueSet/units-of-time" />
                <code value="wk" />
                <display value="week" />


In this exercise you will create your own ValueSets and include these in your profile.

Here below are a couple of links that you may find useful during this exercise:

    Case description
    Hospital X wants to receive patient data from general practitioners. The hospital has decided to build conform the FHIR standard. The hospital has already built profiles on Patient and Practitioner, but now the hospital wants to include family history. The following requirements are specified:
  • The hospital wants to limit the family history to family members only.
  • The hospital wants to exclude in-law family.

Steps to follow

1. Customize your ValueSet for family relationship

  1. Take a look at the specification if you can reuse an existing CodeSystem or ValueSet for relationship codes.
  2. Use Snapper to create your ValueSet. Of course you may use any other tool that you like, but in this assignment we will assume the use of Snapper.
  • In the menu on the left, click on the + on the right of FHIR Value Sets to create your ValueSet.
  • Complete the Name, URL and Description fields (e.g. name=MyRelationshipCodes, URL=https://example.org/fhir/ValueSet/MyRelationshipCodes)
  1. Use the filter element to include only family member codes by following the steps below.
  • Complete the Code System field with the URL of the system you want to select codes from.
  • Complete the Property, Operation and Value fields in the first row to add the filter criterium. Hint: these codes will have an is-a relationship with the code fammemb.
  1. Exclude in-law codes by following the steps below.
  • Scroll down until the end of the page and click on + Exclude Filter.
  • Complete the Code System field with the URL of the system you want to exclude codes from.
  • Complete the Property, Operation and Value fields in the first row to add the filter criterium. Hint: these codes will have an is-a relationship with the code inlaw.
  1. Go to Upload to FHIR server and choose Validate Value Set. You may also upload your ValueSet to a FHIR server in this step. Click on Download Value Set to download and save the JSON code of your created ValueSet.

2. Use your customized ValueSet in your own profile

  1. Open Forge and create a new profile. Choose the basis resource that is best fit for exchanging family history.
  2. Bind the element that captures family relationship to your own ValueSet.
  3. Change the binding strength to only allow codes from your ValueSet.


We are always looking for ways to improve our products. The Profiling Academy was built using our own IG-editor in Simplifier. If you have any feedback on this module or on our Profiling Academy in general, please leave a comment in the Issue Tracker of the project.

Get in touch

Start profiling

Most modules end with an exercise. Use Forge to start profiling yourself. Just contact us at simplifier@fire.ly if you need any help.

Learn more

Follow one of our predefined or tailor-made courses. We will make sure you know FHIR inside-out.

Need help or advice?

Let us assist you with your FHIR use case. Visit our company website to know more about our services or get into contact with Rien Wertheim right away.