Introducing FHIR Data Types
In this lesson, we’re going to take a closer look at FHIR Data Types. The official FHIR documentation covers them in great detail, but if you’re new to FHIR, that amount of detail can feel overwhelming.
Instead of diving into everything at once, we’ll go through the different data types step-by-step, using an easy-to-follow patient example so you can see exactly how they work in real life.
1. Primitive Types
Primitive data types in FHIR are the most basic building blocks for representing information. They are called “primitive” because they hold simple values rather than complex structures. Think of them as the raw ingredients that other, more complex data types are built from.
Each primitive data type represents a single kind of value, such as a string of text, a number, a date, or a true/false value. For example, a patient’s first name might be stored as a simple string, their age as a number, and whether they are currently active in the system as a true/false value.
Let’s learn with an example :
{
"resourceType" : "Patient",
/* Primitive Data Types */
"active" : True,
"birthDate" : "2000-06-06",
"multipleBirthInteger": 2
}
active
– This is a boolean primitive data type. It can only be true or false. In this case, true means the patient record is currently active — for example, they are still receiving care or their information is still relevant.
birthDate
– This is a date primitive data type. It records the patient’s date of birth in the YYYY-MM-DD format. In FHIR, birthDate can also be less specific if the exact date is unknown — you could provide just the year (2000) or the year and month (2000-06). The value must always be a valid calendar date, meaning it cannot have impossible values like the 30th of February.
multipleBirthInteger
– This is an integer primitive data type. It stores whole numbers without any decimals. In this case, 2 means the patient was born as part of a multiple birth — for example, they might be a twin (second child) or part of another multiple birth scenario.
2. General Purpose Complex Types
General purpose complex types in FHIR are data types made up of multiple elements that work together to represent a more detailed piece of information. Unlike primitive data types, which hold a single simple value, these can bundle different kinds of values into one structured format.
They are called “general purpose” because they are used across many different FHIR resources, not tied to a specific medical concept. Types like HumanName, Address, and ContactPoint appear almost everywhere in FHIR and are used very commonly, whether you’re describing a patient, a practitioner, or even an organization.
Let’s look at some general purpose complex types in action using our patient example:
{
"identifier": [{
"system": "http://hospital.org/mrn",
"value": "NB-20250806-002"
}],
"name": [{
"given": ["Aarav"],
"family": "Ramesh"
}],
"address": [{
"line": ["12 MG Road"],
"city": "Bengaluru",
"country": "IN"
}],
"telecom": [{
"system": "phone",
"value": "+91-80-4444-1234",
"use": "mobile"
}]
}
identifier
– Uses the Identifier complex type to store a unique ID for the patient. The system is the namespace that defines where this ID comes from — here it’s “http://hospital.org/mrn”. Even though it looks like a web address, it doesn’t have to point to an actual webpage. It’s simply a globally unique string (in URI format) that ensures the identifier’s meaning is clear when shared between systems. The value is the actual ID assigned to the patient within that system (“NB-20250806-002”).
name
– Uses the HumanName
complex type to store the patient’s name in parts. given holds the first name(s) (“Aarav”) and family holds the last name (“Ramesh”).
address
– Uses the Address
complex type to store location details. line is the street (“12 MG Road”), city is the city name (“Bengaluru”), and country is the 2-letter ISO code (“IN”).
telecom
– Uses the ContactPoint
complex type to store contact information. system says what kind (“phone”), value is the actual phone number, and use (“mobile”) tells how it’s used.
General purpose complex types like these show up in many FHIR resources, making them some of the most frequently used elements you’ll encounter.
3. Metadata Types
Metadata types in FHIR are used to store information about the resource itself, rather than the clinical details of the patient. Think of them as extra layers that make the resource easier to understand for humans and more flexible for different systems.
One common metadata type is the Narrative, which provides a plain-language summary of the resource so that someone reading it can quickly understand the key details without looking at every field. Another is the Extension, which lets us safely add new information that isn’t part of the standard FHIR definition — without breaking compatibility with other systems.
These types don’t change the core medical facts, but they make the resource more understandable for humans and more adaptable for different use cases.
Let’s check the example below to better understand the metadata types.
{
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Baby Aarav Ramesh, born 06-Aug-2025, twin 2 of 2.</div>"
},
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-birthPlace",
"valueAddress": {
"city": "Bengaluru",
"state": "KA",
"country": "IN"
}
}
]
}
text
– Uses the Narrative data type to provide a human-readable summary of the resource.
-
status
(code) shows how the summary was created; “generated” means it was produced automatically by the system. Other values like “extensions” or “additional” indicate if the text includes extra details beyond the base data. -
div (xhtml)
contains the summary itself in XHTML format. In this example, it clearly describes the patient: “Baby Aarav Ramesh, born 06-Aug-2025, twin 2 of 2.” The XHTML namespace (xmlns=“http://www.w3.org/1999/xhtml”) must be present for the field to be valid.
extension
– Uses the Extension data type to store extra information that isn’t part of the standard Patient resource.
-
url
(uri) is a globally unique address that defines the extension’s meaning — here it’s the official HL7 patient-birthPlace extension. Even though it looks like a link, it doesn’t have to be a webpage; it just needs to be a unique, stable identifier. -
valueAddress
(Address complex type) contains the actual data for the extension, here recording the patient’s birth city (“Bengaluru”), state code (“KA”), and country code (“IN”).
4. Special Purpose Complex Types
Special-purpose complex types in FHIR are designed for very specific kinds of data that have a well-defined meaning and structure. Unlike general-purpose complex types — such as HumanName
, Address
, or Identifier
— which are flexible and appear across many resources in various contexts, special-purpose types are used only in situations where that exact structure is needed. They solve a targeted problem rather than acting as a reusable building block for many different purposes.
For example, if you want to include a file (like an image, PDF, or scanned document) inside a resource, you wouldn’t use string or Identifier
— you’d use the Attachment type, because it knows exactly how to describe a file, its format, and where it’s stored. Similarly, if you need to link to another FHIR resource, you’d use the Reference
type, which is purpose-built for pointing to other resources safely and consistently.
Let’s learn with an example.
{
"photo": [{
"contentType": "image/jpeg",
"url": "https://pics.org/patients/NB-20250806-002.jpg",
"title": "ID Wristband Photo"
}],
"managingOrganization": {
"reference": "Organization/medblocks-general",
"display": "Medblocks General Hospital"
}
}
photo
– Uses the Attachment
data type to store details about a file associated with the patient.
-
contentType
(code) tells what type of file it is, here “image/jpeg” for a JPEG image. -
url
(uri) is the location of the file. This can be an external link, an internal server path, or even inline base64 data. -
title
(string) is a human-readable label for the file, here “ID Wristband Photo”.
managingOrganization
– Uses the Reference data type to point to another FHIR resource.
-
reference
(string) identifies the target resource by type and ID, here pointing to anOrganization
resource with the ID medblocks-general. -
display
(string) provides a friendly name to show in user interfaces, here “Medblocks General Hospital”. This is for convenience — the actual details should be fetched from the referenced resource.
If you want to go further, I highly recommend exploring the official FHIR documentation on data types. It’s the most complete reference, with every detail, rule, and edge case you might need. The more time you spend with it, the easier it will become to design clean, consistent, and interoperable FHIR resources.