
SMART on FHIR: How It Works and How to Build Apps That Launch Inside EHRs
Learn how SMART on FHIR connects apps to EHRs using FHIR APIs and OAuth2. Covers launch flows, scopes, Epic and Cerner setup, SMART v2, and building your first app.
August 26, 2025
Starting with FHIR can feel overwhelming. The FHIR specification has more than 160 resources! Where do you even begin?
Don’t worry. In this guide, we’ll cover 12 essential FHIR resources that you’ll use in almost every healthcare workflow. We’ll follow the journey of a patient with a common cold to see how these resources work together.
Let’s start with the basics. Administrative resources identify people, places, and interactions. They’re the foundation of every clinical workflow.
The Patient resource represents the person receiving care. It could be anyone - even animals in veterinary settings!
Here’s what a basic patient looks like:
{
"resourceType": "Patient",
"id": "pat-1",
"active": true,
"name": [{
"use": "official",
"family": "Smith",
"given": ["Bob"]
}],
"birthDate": "1980-05-10"
}
The patient has a name, birth date, and an active status. Simple, right?
Someone needs to provide care to the patient. That’s where the Practitioner resource comes in. A practitioner doesn’t have to be a doctor - it’s anyone providing healthcare services.
{
"resourceType": "Practitioner",
"id": "prac-1",
"active": true,
"name": [{
"family": "Doe",
"given": ["Alice"],
"prefix": ["Dr."]
}],
"telecom": [{
"system": "phone",
"value": "+1-555-0300"
}],
"qualification": [{
"code": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v2-0360/2.7",
"code": "BS",
"display": "Bachelor of Science"
}]
}
}]
}
Practitioners have qualifications and contact information. You need to know exactly who’s providing care and what their credentials are.
The patient and practitioner need to interact somehow. That’s what an Encounter resource represents - any interaction with the healthcare system.
It could be:
{
"resourceType": "Encounter",
"id": "enc-1",
"status": "finished",
"class": {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "AMB"
},
"subject": { "reference": "Patient/pat-1" },
"participant": [{
"individual": { "reference": "Practitioner/prac-1" }
}],
"period": {
"start": "2025-08-08T09:00:00-05:00",
"end": "2025-08-08T09:30:00-05:00"
}
}
This encounter shows Bob Smith visiting Dr. Alice Doe for 30 minutes. The “AMB” code means it’s an ambulatory (outpatient) visit.
Now that we have the who, when, and where, let’s capture what’s happening clinically.
Before treating a patient, you need to know their allergies! The AllergyIntolerance resource captures this critical information.
{
"resourceType": "AllergyIntolerance",
"id": "allergy-1",
"clinicalStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical",
"code": "active"
}]
},
"type": "allergy",
"category": ["food"],
"code": {
"coding": [{
"system": "http://snomed.info/sct",
"code": "91935009",
"display": "Allergy to peanuts"
}]
},
"patient": { "reference": "Patient/pat-1" }
}
Bob has a peanut allergy. This could be:
Medication allergies are especially important - you don’t want to give penicillin to someone who’s allergic to it!
The Observation resource captures anything you can observe about a patient. It’s incredibly versatile!
Quick note on codes:
Here’s Bob’s temperature:
{
"resourceType": "Observation",
"id": "obs-temp-1",
"status": "final",
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "8310-5",
"display": "Body temperature"
}]
},
"subject": { "reference": "Patient/pat-1" },
"valueQuantity": {
"value": 38.1,
"unit": "°C",
"system": "http://unitsofmeasure.org",
"code": "Cel"
}
}
Observations can capture:
For blood pressure, you can use components to capture both systolic and diastolic in one observation:
{
"resourceType": "Observation",
"id": "obs-bp-1",
"status": "final",
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "85354-9",
"display": "Blood pressure panel"
}]
},
"component": [
{
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "8462-4",
"display": "Diastolic blood pressure"
}]
},
"valueQuantity": {
"value": 70,
"unit": "mm[Hg]"
}
},
{
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "8480-6",
"display": "Systolic blood pressure"
}]
},
"valueQuantity": {
"value": 120,
"unit": "mm[Hg]"
}
}
]
}
After examining the patient and reviewing observations, the doctor makes a diagnosis. That’s a Condition resource.
{
"resourceType": "Condition",
"id": "cond-cold-1",
"clinicalStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active"
}]
},
"code": {
"coding": [{
"system": "http://snomed.info/sct",
"code": "82272006",
"display": "Common cold"
}]
},
"subject": { "reference": "Patient/pat-1" },
"onsetDateTime": "2025-08-08"
}
Bob has been diagnosed with a common cold. What’s the difference between Observation and Condition?
The FHIR spec isn’t always clear on the boundary. Even doctors sometimes aren’t sure! But generally, conditions are diagnoses made by clinicians.
To help Bob feel better, the doctor might perform a procedure. The Procedure resource captures any action done to a patient.
{
"resourceType": "Procedure",
"id": "proc-1",
"status": "completed",
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "433853007",
"display": "Infusion of drug via intravenous route"
},
{
"system": "http://www.ama-assn.org/go/cpt",
"code": "96365",
"display": "Initial IV infusion"
}
]
},
"subject": { "reference": "Patient/pat-1" },
"performedDateTime": "2025-08-08T11:00:00-05:00",
"reasonReference": [{ "reference": "Condition/cond-cold-1" }]
}
The doctor gave Bob an IV drip to reduce his temperature. Notice the CPT code? That’s often needed for billing and claims.
Sometimes you need lab tests or other diagnostics to confirm what’s wrong.
First, the doctor orders a test using a ServiceRequest resource. Think of it as the doctor’s instructions for what test to perform.
{
"resourceType": "ServiceRequest",
"id": "sreq-rvp-1",
"status": "active",
"intent": "order",
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "94499-1",
"display": "Respiratory viral pathogens panel"
}]
},
"subject": { "reference": "Patient/pat-1" },
"reasonReference": [{ "reference": "Condition/cond-cold-1" }]
}
The doctor wants a respiratory viral panel to confirm what’s causing Bob’s symptoms.
When the lab results come back, they’re grouped in a DiagnosticReport resource. This ties together all the individual test results.
{
"resourceType": "DiagnosticReport",
"id": "drpt-uri-1",
"status": "final",
"code": {
"text": "Respiratory infection assessment"
},
"subject": { "reference": "Patient/pat-1" },
"result": [
{ "reference": "Observation/obs-flu-a" },
{ "reference": "Observation/obs-flu-b" },
{ "reference": "Observation/obs-rsv" },
{ "reference": "Observation/obs-rhinovirus" }
],
"conclusion": "Rhinovirus detected. Consistent with common cold."
}
The report shows multiple observations (flu A, flu B, RSV, rhinovirus tests) all interpreted together. In Bob’s case, rhinovirus was detected - confirming the common cold diagnosis.
Think of it like this:
Finally, let’s treat Bob’s symptoms with medication.
The Medication resource defines what medications are available. It’s like a drug catalog.
{
"resourceType": "Medication",
"id": "med-acetaminophen-1",
"code": {
"coding": [{
"system": "http://snomed.info/sct",
"code": "322236009",
"display": "Acetaminophen 500 mg oral tablet"
}]
},
"form": {
"coding": [{
"system": "http://snomed.info/sct",
"code": "385219001",
"display": "Conventional release oral tablet"
}]
}
}
This defines acetaminophen (Tylenol) as an available medication.
When the doctor prescribes medication, that’s a MedicationRequest resource. It’s like a prescription.
{
"resourceType": "MedicationRequest",
"id": "medreq-acetaminophen-1",
"status": "active",
"intent": "order",
"medicationReference": {
"reference": "Medication/med-acetaminophen-1"
},
"subject": { "reference": "Patient/pat-1" },
"authoredOn": "2025-08-08",
"reasonReference": [{
"reference": "Condition/cond-cold-1"
}],
"dosageInstruction": [{
"text": "Take one tablet by mouth every 6 hours as needed for fever"
}]
}
The doctor prescribed acetaminophen for Bob’s fever. But this doesn’t mean Bob actually took it! It’s just the prescription.
When medication is actually given to the patient (like in a hospital), that’s captured with a MedicationAdministration resource.
{
"resourceType": "MedicationAdministration",
"id": "medadmin-acetaminophen-1",
"status": "completed",
"medicationReference": {
"reference": "Medication/med-acetaminophen-1"
},
"subject": { "reference": "Patient/pat-1" },
"effectiveDateTime": "2025-08-08T11:15:00-05:00",
"request": {
"reference": "MedicationRequest/medreq-acetaminophen-1"
},
"dosage": {
"dose": {
"value": 500,
"unit": "mg"
},
"route": { "text": "oral" }
}
}
A nurse gave Bob 500mg of acetaminophen at 11:15 AM. This administration links back to the doctor’s original request.
These 12 resources work together to tell Bob’s story:
Notice how some resources work in pairs?
Someone requests something, then another resource fulfills that request. This pattern appears throughout FHIR.
These 12 resources cover most basic healthcare workflows. Once you understand these, you’ll be ready to explore more specialized resources.
Want to learn more? Check out our free FHIR Fundamentals course where we:
Remember: FHIR might seem complex at first, but it’s just representing what happens in healthcare every day. Start with these 12 resources, and you’ll be building healthcare apps in no time!

Learn how SMART on FHIR connects apps to EHRs using FHIR APIs and OAuth2. Covers launch flows, scopes, Epic and Cerner setup, SMART v2, and building your first app.

This article details HL7's role in healthcare data exchange since 1987. It explores the standards family including legacy v2, CDA, and modern FHIR APIs highlighting their necessity for interoperability, regulatory compliance, and system integration.

The complete guide to FHIR (Fast Healthcare Interoperability Resources). Learn FHIR resources, R4, Profiles and Implementation Guides, SMART on FHIR, HL7 history, and how to start.
No comments yet. Be the first to comment!