Start profiling


In this module you will learn how to build your first profile. 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:

  • Building your first profile
  • Constraining elements
  • Constraining data types

Reading material

The process of making a profile is a process of constraining different aspects of a base resource or data type. Any change you make to a base resource is called a constraint and can only limit the information contained in the base resources. Constraints are any limitations to elements in a base resource in terms of limiting the allowable ValueSets, limiting or eliminating cardinality and adding elements (extensions). Through various constraints you make the profile more specific to your needs, thereby making it more limited in terms of the information that satisfies the requirements set forth in the profile.

1. Building your first profile

The first step in building any profile is to select a base resource or data type (e.g. a Patient). You may also choose to further constrain a profile (e.g. MyPatient) and select this profile as your base profile. The next step after choosing your base resource, is to give your resource a name and a unique canonical URL. In Forge, you can do so in the Properties tab.

2. Constraining elements

Now that you have built your profile, you can start constraining its elements. For example, the following properties can be constrained: Cardinality, Fixed values, Data types, Must-Support and Is-Modifier. Each of these properties is explained in more detail below.

2.1 Cardinality

An important aspect in profiling is constraining the cardinality of different elements. The cardinality of an element sets the number of allowable repetitions for that element.

Cardinality Meaning
0..0 not used
0..1 optional to one
0..* optional to many
1..1 one required
1..* at least one

Profiles cannot break the rules established in the base specification. The rules of cardinality specify that the minimum cardinality of the new range must be less than or equal to the maximum cardinality and the maximum cardinality must be greater than or equal to the new minimum cardinality.

2.2 Fixed values

You can use fixed values to specify a value that SHALL be exactly the value for this element in the instance. For example, you can specify that identifier.system shall always be to specify that this identifier shall be a US Social Security Number.

Complex values can also be fixed. A complex data type is usually a composite of other existing data types, like Coding, which consists of multiple strings, a uri and a boolean.

An example of fixing a complex value is when creating a profile specifically for respiratory rate. You will create a profile on Observation that has a Fixed value on Observation.code (CodeableConcept) using a LOINC code, system and display name, to specify which vital sign is specified.


<element id="Observation.code">
    <path value="Observation.code"/>
            <system value=""/>
            <code value="9279-1"/>
            <display value=" Respiratory rate"/>

This instead of fixing the three individual elements separately.

2.3 Choice of Data types ( value[x] )

In FHIR resources, some elements end with an [x], meaning that this element has multiple types. For example, Patient.multipleBirth[x] can be either a boolean (example 1) or an integer (example 2). A boolean value indicates whether a Patient is one of many (true or false). If present, an integer value means that the patient is one of many, indicating the actual birth order.

Example 1

<Patient xmlns="">
  <gender value="female"/>
  <birthDate value="2017-01-01"/>
  <multipleBirthBoolean value="true"/>

Example 2

<Patient xmlns="">
  <gender value="female"/>
  <birthDate value="2017-01-01"/>
  <!-- Patient is the second born child of many -->
  <multipleBirthInteger value="2"/>

Choice data types always have a maximum cardinality of 1, meaning that the element cannot repeat. This means that only one of the optional data types must be chosen.

When profiling, you can't add optional data types to an element, you only constrain "value[x]" elements to the optional data types you want to allow. An example can be that you contain a Patient resource to only allow multipleBirth booleans and no integer, because your system does not have any support for birth order. Or if you are profiling an Observation resource for Body Weight, you may want to constrain Observation.value[x] to only allow for the Quantity data type and not the String, Integer, CodeableConcept or any other data type that doesn't make sense in the context of defining a person's body weight.

2.4 mustSupport

This is a boolean (true or false) property that identifies an element that must be supported, that is understandable, to all sending and receiving bodies. The minimum cardinality of "mustSupport" elements may be set to 0 meaning that it isn't required but if a value is sent it must be digestible by the receiving system. Note that the specification itself never labels any elements as mustSupport, this is done in Resource Profiles (StructureDefinitions). The flag is intended for use in profiles that have a defined implementation context. Since "mustSupport" is such an overloaded term in Health IT, it's up to the specifier to define what is meant by this.

One of the more common definitions of mustSupport
If the sending system has the information specified in the element, it should put it in the resource, and the receiving party cannot ignore and must process that information accordingly.

Some options to consider when thinking about your mustSupport strategy are:

  • Make everything in the differential mustSupport=true like US core (
  • Make nothing mustSupport=true and instead add a notion that altered elements in the profile in itself suggests "mustSupport" for those elements.
  • Weigh at least every optional element path for importance and potentially make paths with a minimum cardinality of 1 mustSupport=true (although that is sort of redundant)

2.5 isModifier

This is a boolean (true or false) property that identifies an element as a modifier for a resource. If an element shows a true value in the “IsModifer" property then its contents, once filled in, have the ability to change the meaning of the resource. The value of the element then shape the interpretation of the rest of the elements in this resource and the overall meaning. The "IsModifier" elements should have a minimum cardinality of 1 within a resource and should be explained in the narrative of a resource. For example, if the value of the verificationStatus element of the resource AllergyIntolerance is set to 'Refuted' this affects the entire meaning of the resource.

Only the definition of an element can set IsModifier to true - either the specification itself or where an extension is originally defined. IsModifier of already existing elements cannot be set from true to false in profiles.

3. Constraining data types

There are situations in which you want to constrain data types instead of individual resources. This is efficient when you want to apply the same constraints across different resources. It also makes it easier to maintain as changes only need to be made one place, your new data type. SimpleQuantity is an example of a Profile on a data type. Another example is given below.

    In the Netherlands it is common to use prefixes in last names. For example, the last name "de Bakker" consists of the prefix "de" and the name "Bakker". Let's say you want to use the resources Patient, Practitioner, and RelatedPerson and add this prefix to the name element for these resources. Instead of applying the same change to all three resources, you can constrain the data type "HumanName" once and use your new data type in each profile. Follow the steps below to accomplish this:
  • Create a new profile on HumanName (e.g. NL-HumanName)
  • Add constraints that are applicable to all instances of HumanName in your scenario (e.g. add the element Prefix)
  • Now in the profiles of Patient, Practitioner, RelatedPerson, or any other resource where it would also be useful, change the data type from "HumanName" to "NL-HumanName".

Real-life examples

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


ZorgDomein is a digital platform where care providers can request or offer care and exchange patient information in a safe and secure way. To facilitate the implementation of a FHIR-interface between ZorgDomein and hospital information systems, profiles are specified on the following core resources: Patient, Practitioner, Organization, Coverage, Composition, DocumentReference, ReferralRequest, EpisodeOfCare, Encounter, Observation, AllergyIntolerance and MedicationStatement.

The example below shows the differential of the zd-practitioner profile, so it only shows the differences compared to the core resource Practitioner. In this case, the differences are as following:

  • The minimum cardinality of the following elements are set to 1 (meaning these elements are mandatory):
    • Identifier.system
    • Identifier.value
    • Telecom.system
    • Telecom.value
    • Gender
  • The value for the naming system of the identifier is fixed to the UZI number of the care provider
  • The data types of the name and address elements are set to the Dutch core profiles for these data types:
    • nl-core-humanname
    • nl-core-address


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).

The example below shows the Dutch national profile for Patient. It contains the following constraints and extensions:

  • An extension to specify preferredPharmacy, with the data type set to nl-core-organization
  • An extension to specify nationality, with a binding on a national code list)
  • A slice on identifier for the Dutch national identifier (BSN) where:
    • The value of system is fixed to the BSN naming system
    • The minimum cardinality of system and value elements are set to 1
  • The data types of the name, address and generalPractitioner elements are set to the Dutch core profiles for these data types:
    • nl-core-humanname
    • nl-core-address
    • nl-core-organization or nl-core-practitioner


useΣ ?!0..1codeBinding
systemΣ1..1uriFixed Value
activeΣ ?!0..1boolean
useΣ ?!0..1codeBinding
useΣ ?!0..1codeBinding
generalPractitioner0..1Reference(nl-core-organization | nl-core-practitioner)
otherΣ1..1Reference(Patient | RelatedPerson)


The next example shows the Dutch national profile for the data type HumanName. The family name has some extensions to include the prefix that is commonly used in a Dutch family name.


useΣ ?!0..1codeBinding


See the xml code below for an example of a Dutch patient called "Piet de Bakker".

<Patient xmlns="">
      <given value="Piet"/>
      <family value="de Bakker">
        <extension url= "">
        <extension url= "">


In this exercise you will build your first profile. Start by reading the case description. 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, starting with administrative data of patients and their general practitioner. The following requirements are specified:
  • A patient has at least 1 family name and 1 given name
  • Date of birth is mandatory
  • Gender is mandatory
  • The hospital wants to record if a patient is deceased or not, not the actual dateTime

Steps to follow

  1. Start Forge and build a new profile. Choose the basis resource that is best fit for exchanging administrative patient data. Take a look at the FHIR resource list.
  2. Give the profile a valid, unique URL (tab ‘Properties’), for example:
  3. Complement the remaining metadata in the profile (name, description, etc.).
  4. Set the constraints according to the requirements of the hospital.


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 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.