Visit Templates and the SOAP Approach | Medplum
Visit Template Lifecycle
- Author a
PlanDefinitionwhoseactionentries reference Questionnaires and ActivityDefinitions. Authoring detail lives in Authoring Clinical Protocols. - Invoke
$applywithsubject(Patient) and optionallyencounter,practitioner, andorganization. - Medplum creates Tasks (and ServiceRequests when
ActivityDefinition.kindis ServiceRequest). - Clinicians complete Questionnaires and orders; parse responses into FHIR resources using Parsing Questionnaire Responses or Bots.
- Sign the visit using
ClinicalImpression.statusand aProvenanceon the Encounter (see Signing and Locking Notes).
Common Visit-Template Patterns
A few shapes recur in real implementations.
- Questionnaire-driven capture (primary care) – a standard form per visit type (vitals, intake screen) submits a
QuestionnaireResponsewhose answers are parsed intoObservationresources via$extractor a Bot. - Template-driven plan (specialty protocols) – a
PlanDefinitionfor the protocol instantiatesServiceRequest,MedicationRequest, orCarePlanfromActivityDefinitionactions on$applyrather than free-text plan sections. See Authoring Clinical Protocols. - Pre-filled context from intake – when intake narrows the problem list (e.g. dermatology lesions), prepopulate Questionnaire or Observation drafts before the clinician opens the chart.
Avoid storing everything as raw QuestionnaireResponse only – answers there are not first-class searchable fields the way Observations and Conditions are. Parse into the proper resources (see Parsing Questionnaire Responses).
How Visits, FHIR, and SOAP Line Up
The diagram below is intentionally simplified – real encounters interleave steps – but shows how common visit steps map to FHIR resources and SOAP letters. Template mechanics (what $apply creates first) are separate from documentation; everything eventually references the same Encounter.
| SOAP | FHIR resources | Visit steps |
|---|---|---|
| S | Observations from questionnaires Tasks and parsing | Patient-reported findings and forms |
| O | Observations vitals and exam | Vitals and measured exam data |
| A | ClinicalImpression and Condition | Assessment reasoning and diagnoses |
| P | ServiceRequest MedicationRequest CarePlan | Orders referrals meds follow-up |
The encounter graph below shows the same resources hanging off a single Encounter:
- subject
- encounter
Example: full SOAP note FHIR R4 Bundle
{
"resourceType": "Bundle",
"type": "collection",
"entry": [
{
"fullUrl": "urn:uuid:example-encounter",
"resource": {
"resourceType": "Encounter",
"id": "example-encounter",
"status": "finished",
"class": {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "AMB",
"display": "ambulatory"
},
"subject": { "reference": "Patient/homer-simpson" },
"participant": [
{
"individual": { "reference": "Practitioner/dr-alice-smith" }
}
],
"period": {
"start": "2024-01-15T10:00:00Z",
"end": "2024-01-15T11:30:00Z"
}
}
},
{
"fullUrl": "urn:uuid:obs-subjective-fatigue",
"resource": {
"resourceType": "Observation",
"id": "obs-subjective-fatigue",
"status": "final",
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "75325-1",
"display": "Symptom"
}
],
"text": "Fatigue"
},
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" },
"performer": [{ "reference": "Patient/homer-simpson" }],
"valueString": "Patient reports feeling lethargic for the past week"
}
},
{
"fullUrl": "urn:uuid:obs-objective-heart-rate",
"resource": {
"resourceType": "Observation",
"id": "obs-objective-heart-rate",
"status": "final",
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8867-4",
"display": "Heart rate"
}
]
},
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" },
"performer": [{ "reference": "Practitioner/dr-alice-smith" }],
"valueQuantity": {
"value": 112,
"unit": "beats/min",
"system": "http://unitsofmeasure.org",
"code": "{Beats}/min"
}
}
},
{
"fullUrl": "urn:uuid:clinical-impression-assessment",
"resource": {
"resourceType": "ClinicalImpression",
"id": "clinical-impression-assessment",
"status": "completed",
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" },
"date": "2024-01-15T11:00:00Z",
"description": "Patient presents with fatigue and abdominal pain.",
"finding": [
{ "itemReference": { "reference": "Condition/condition-gastritis" }}
],
"note": [
{ "text": "Assessment: symptoms consistent with gastritis. Differential includes peptic ulcer disease. Will monitor response to treatment." }
]
}
},
{
"fullUrl": "urn:uuid:condition-gastritis",
"resource": {
"resourceType": "Condition",
"id": "condition-gastritis",
"clinicalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active"
}
]
},
"verificationStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code": "confirmed"
}
]
},
"code": {
"coding": [
{
"system": "http://hl7.org/fhir/sid/icd-10-cm",
"code": "K29.70",
"display": "Gastritis, unspecified, without bleeding"
}
]
},
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" }
}
},
{
"fullUrl": "urn:uuid:service-request-lab",
"resource": {
"resourceType": "ServiceRequest",
"id": "service-request-lab",
"status": "active",
"intent": "order",
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "13958-0",
"display": "Helicobacter pylori [Presence] in Stool by Immunoassay"
}
]
},
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" },
"requester": { "reference": "Practitioner/dr-alice-smith" }
}
},
{
"fullUrl": "urn:uuid:provenance-note-signed",
"resource": {
"resourceType": "Provenance",
"id": "provenance-note-signed",
"target": [{ "reference": "Encounter/example-encounter" }],
"recorded": "2024-01-15T11:30:00Z",
"reason": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
"code": "SIGN",
"display": "Signed"
}
]
}
],
"agent": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type",
"code": "author"
}
]
},
"who": { "reference": "Practitioner/dr-alice-smith" }
}
]
}
}
]
}
Subjective and Objective – Observation
Both Subjective and Objective are Observation resources. The distinction is usually performer:
- Subjective: patient as
performerfor self-reported symptoms. - Objective: clinician or device as
performerfor measured findings.
Use appropriate coding (typically LOINC) and value[x]. For measurement details see Observations and vital signs.
Example: patient-reported fatigue (Subjective)
{
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "75325-1",
"display": "Symptom"
}
],
"text": "Fatigue"
},
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" },
"performer": [{ "reference": "Patient/homer-simpson" }],
"valueString": "Patient reports feeling lethargic for the past week"
}
Example: elevated heart rate (Objective)
{
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8867-4",
"display": "Heart rate"
}
]
},
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" },
"performer": [{ "reference": "Practitioner/dr-alice-smith" }],
"valueQuantity": {
"value": 112,
"unit": "beats/min",
"system": "http://unitsofmeasure.org",
"code": "{Beats}/min"
}
}
Assessment – Clinical Impression
ClinicalImpression is the FHIR-native assessment resource – the “A” in SOAP.
Why ClinicalImpression instead of DocumentReference or raw QuestionnaireResponse?
Some apps store assessment as DocumentReference or leave narrative only in QuestionnaireResponse. ClinicalImpression gives findings, summary, and reasoning discrete fields other systems can consume. Prefer structured coded data and use free-text where clinicians need it.
Usually create ClinicalImpression early with statusin-progress, then transition to completed when signed.
| Field | Description | Example |
|---|---|---|
status |
Lifecycle state | in-progress, completed |
subject |
Patient | Patient/homer-simpson |
encounter |
Encounter | Encounter/example-encounter |
date |
When assessed | 2024-01-15T10:00:00Z |
description |
Short summary | Patient presents with fatigue and abdominal pain. |
note |
Narrative; note[0].text is common for the note |
Assessment narrative text |
Example: ClinicalImpression at encounter start
{
"resourceType": "ClinicalImpression",
"status": "in-progress",
"subject": { "reference": "Patient/homer-simpson" },
"encounter": { "reference": "Encounter/example-encounter" },
"date": "2024-01-15T10:00:00Z",
"description": "Patient presents with fatigue and abdominal pain.",
"note": [
{ "text": "Assessment: symptoms consistent with gastritis. Differential includes peptic ulcer disease. Will monitor response to treatment." }
]
}
Formal diagnoses are often modeled as Condition while ClinicalImpression carries reasoning. See Diagnoses and problem list.
Plan – Orders and Care
Plan items are concrete FHIR requests: ServiceRequest for labs, imaging, and referrals (use category to distinguish), MedicationRequest for prescriptions, and CarePlan for ongoing care strategy. Generate them inline from ActivityDefinition actions on the visit template rather than free text. See Ordering Labs and Imaging and Representing Prescriptions for detail.
Signing and Locking Notes
When the note is complete, set ClinicalImpression.status to completed and create Provenance targeting the Encounter to record signer and time. "Signed" and "locked" are separate product decisions – co-signing, post-sign editable windows, and amendment workflows belong in your own discovery; see Designing Charting for the structure-vs-narrative framing.
Example: Provenance for clinician sign-off
{
"resourceType": "Provenance",
"target": [{ "reference": "Encounter/example-encounter" }],
"recorded": "2024-01-15T11:30:00Z",
"reason": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
"code": "SIGN",
"display": "Signed"
}
]
}
],
"agent": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type",
"code": "author"
}
]
},
"who": { "reference": "Practitioner/dr-alice-smith" }
}
]
}