Immunization order
DSP immunization orders split cleanly on intent. A proposed vaccine (“give flu shot at next visit”) lands as ImmunizationRecommendation; an administered dose (“gave flu shot today”) lands as Immunization. Both carry CVX codes. Unlike the generic ServiceRequest pattern, FHIR has two purpose-built resources here — pick by DSP intent.
order.immunization
ImmunizationRecommendation (proposal) or Immunization (administered)
Field-by-field
| DSP | FHIR R4 | Notes |
|---|---|---|
type: IMMUNIZATION_ORDER, intent=proposal|plan|order | ImmunizationRecommendation | For not-yet-given vaccines. Use when DSP intent is proposal, plan, or order and order_data.administered is false/absent. |
type: IMMUNIZATION_ORDER, intent=order with administration details | Immunization | For doses actually given in-encounter. Immunization.status = completed. |
order_data.vaccine_code | vaccineCode | CVX (http://hl7.org/fhir/sid/cvx) preferred; SNOMED as fallback. |
order_data.dose_number | protocolApplied.doseNumberPositiveInt (Immunization) / doseNumberPositiveInt (ImmunizationRecommendation) | 1, 2, booster, etc. |
order_data.series | protocolApplied.series | Free text series name. |
order_data.route | route | SNOMED route. |
order_data.site | site | Body site. |
order_data.lot_number | lotNumber | Administered only. |
order_data.administered_at | occurrenceDateTime | If DSP emits it, treat as "administered". |
order_data.due_by / recommended_date | dateCriterion (ImmunizationRecommendation) | Earliest/recommended/overdue dates. |
reason | reasonCode |
Side-by-side example (proposal — ImmunizationRecommendation)
DSP
{
"id": "imm-001",
"type": "IMMUNIZATION_ORDER",
"context": { "content_type": "order.immunization" },
"description": "Seasonal influenza vaccine, recommend at next visit",
"intent": "proposal",
"reason": "Annual flu prevention",
"provenance": [78, 79],
"order_data": {
"vaccine_code": "88",
"vaccine_code_system": "CVX",
"dose_number": 1,
"recommended_date": "2026-10-01"
}
} FHIR R4 (DSP-FHIR profile)
{
"resourceType":"ImmunizationRecommendation",
"patient":{"reference":"Patient/pat-67890"},
"date":"2026-04-23T14:32:00Z",
"authority":{"reference":"Organization/dsp-tenant"},
"recommendation":[{
"vaccineCode":[{"coding":[{
"system":"http://hl7.org/fhir/sid/cvx","code":"88","display":"Influenza, unspecified formulation"
}]}],
"forecastStatus":{"coding":[{
"system":"http://terminology.hl7.org/CodeSystem/immunization-recommendation-status",
"code":"due"
}]},
"doseNumberPositiveInt":1,
"dateCriterion":[{
"code":{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/immunization-recommendation-date-criterion","code":"recommended"}]},
"value":"2026-10-01"
}]
}]
} Side-by-side example (administered — Immunization)
DSP
{
"id": "imm-002",
"type": "IMMUNIZATION_ORDER",
"context": { "content_type": "order.immunization" },
"description": "Tdap administered in office",
"intent": "order",
"order_data": {
"vaccine_code": "115",
"vaccine_code_system": "CVX",
"administered_at": "2026-04-23T14:10:00Z",
"route": "intramuscular",
"site": "left_deltoid",
"lot_number": "AB12345"
}
} FHIR R4
{
"resourceType":"Immunization",
"status":"completed",
"vaccineCode":{"coding":[{
"system":"http://hl7.org/fhir/sid/cvx","code":"115","display":"Tdap"
}]},
"patient":{"reference":"Patient/pat-67890"},
"encounter":{"reference":"Encounter/enc-12345"},
"occurrenceDateTime":"2026-04-23T14:10:00Z",
"lotNumber":"AB12345",
"site":{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v3-ActSite","code":"LD","display":"Left deltoid"}]},
"route":{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v3-RouteOfAdministration","code":"IM","display":"Intramuscular"}]}
} DSP → FHIR mapping
Routing-split map — the FML below covers the "administered" branch. The recommendation branch is sketched as a comment; see the downloadable IG package for the pre-split convention.
// Routing-split map. The FML below covers the "administered" branch only;
// callers should invoke either this map or DspImmunizationOrderToImmunizationRecommendation
// based on presence of administration evidence (administered_at, lot_number, status=completed).
// Pre-splitting upstream of $transform is the IG's recommended pattern.
map "https://dsp-fhir.org/StructureMap/DspImmunizationOrderToImmunization" = "DspImmunizationOrderToImmunization"
uses "https://dsp-fhir.org/StructureDefinition/DspResource" alias DspResource as source
uses "http://hl7.org/fhir/StructureDefinition/Immunization" alias Immunization as target
group DspImmunizationOrderToImmunization(source src : DspResource, target tgt : Immunization) {
src.id as id -> tgt.id = id;
src -> tgt.status = 'completed';
src.payload as p then {
p.vaccine_code as vc -> tgt.vaccineCode as v, v.coding as co,
co.system = 'http://hl7.org/fhir/sid/cvx', co.code = vc "cvx";
p.administered_at as at -> tgt.occurrenceDateTime = at "occurrence";
p.lot_number as lot -> tgt.lotNumber = lot "lot";
p.route as r -> tgt.route as rt, rt.text = r "route";
p.site as s -> tgt.site as st, st.text = s "site";
p.dose_number as dn -> tgt.protocolApplied as pa, pa.doseNumberPositiveInt = dn "dose";
};
src.confidence as conf -> tgt.extension as ext then {
conf -> ext.url = 'https://dsp-fhir.org/StructureDefinition/dsp-confidence-score',
ext.value = create('decimal') as v, v.value = conf;
} "confidence";
}
// Recommendation branch (sketch):
// map "https://dsp-fhir.org/StructureMap/DspImmunizationOrderToImmunizationRecommendation"
// - forecastStatus.code = 'due'
// - dateCriterion from p.recommended_date
// - vaccineCode[] from p.vaccine_code FHIR → DSP (canonical $graphql read)
DSP IMMUNIZATION_ORDER routes to two FHIR resource types. The reader runs the matching query for the resource type it has and dispatches to the right adapter.
Canonical query (administered branch — Immunization)
query DspImmunization($id: ID!) {
Immunization(id: $id) {
id status
vaccineCode { coding { system code display } text }
occurrenceDateTime
lotNumber
site { coding { system code display } text }
route { coding { system code display } text }
protocolApplied {
doseNumberPositiveInt
doseNumberString
series
}
reasonCode { text }
confidence: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-confidence-score") {
valueDecimal
}
turnRefs: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-transcript-turn-ref") {
transcript: extension(url: "transcript") { valueReference { reference } }
turn: extension(url: "turn") { valueInteger }
}
}
} Canonical query (proposal branch — ImmunizationRecommendation)
query DspImmunizationProposal($id: ID!) {
ImmunizationRecommendation(id: $id) {
id date
recommendation {
vaccineCode { coding { system code display } }
forecastStatus { coding { system code display } }
doseNumberPositiveInt
dateCriterion {
code { coding { system code display } }
value
}
}
confidence: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-confidence-score") {
valueDecimal
}
}
} DSP reconstruction adapter
function toDspImmunizationOrder(r) {
// Discriminate on resourceType (returned in __typename or known by query)
if (r.__typename === 'Immunization' || r.occurrenceDateTime) {
const turnRefs = r.turnRefs ?? [];
return {
type: 'IMMUNIZATION_ORDER',
id: r.id,
intent: 'order',
order_data: {
vaccine_code: r.vaccineCode?.coding?.[0]?.code,
vaccine_code_system: 'CVX',
administered_at: r.occurrenceDateTime,
lot_number: r.lotNumber,
site: r.site?.coding?.[0]?.code ?? r.site?.text,
route: r.route?.coding?.[0]?.code ?? r.route?.text,
dose_number: r.protocolApplied?.[0]?.doseNumberPositiveInt,
series: r.protocolApplied?.[0]?.series,
},
reason: r.reasonCode?.[0]?.text,
confidence_score: r.confidence?.[0]?.valueDecimal,
provenance: turnRefs.map(t => t.turn?.valueInteger),
transcript_ref: turnRefs[0]?.transcript?.valueReference?.reference,
};
}
// Recommendation branch
const rec = r.recommendation?.[0];
return {
type: 'IMMUNIZATION_ORDER',
id: r.id,
intent: 'proposal',
order_data: {
vaccine_code: rec?.vaccineCode?.[0]?.coding?.[0]?.code,
vaccine_code_system: 'CVX',
dose_number: rec?.doseNumberPositiveInt,
recommended_date: rec?.dateCriterion?.find(d => d.code?.coding?.[0]?.code === 'recommended')?.value,
},
confidence_score: r.confidence?.[0]?.valueDecimal,
};
} SQL-on-FHIR v2 ViewDefinitions that flatten every field above — including DSP extensions — into a tabular projection. Runnable as-is on any spec-conformant engine (Pathling, sof-exec, Aidbox SQL-on-FHIR, Databricks). See the SQL-on-FHIR v2 spec. These ViewDefinitions also ship as JSON in the IG zip.
dsp_immunization_recommendation — DSP Immunization proposal (ImmunizationRecommendation)
Flattens DSP proposed immunizations (order.immunization before administration).
{
"resourceType": "ViewDefinition",
"url": "https://dsp-fhir.org/ViewDefinition/dsp-immunization-recommendation",
"name": "dsp_immunization_recommendation",
"title": "DSP Immunization proposal (ImmunizationRecommendation)",
"status": "draft",
"description": "Flattens DSP proposed immunizations (order.immunization before administration).",
"resource": "ImmunizationRecommendation",
"fhirVersion": [
"4.0.1"
],
"select": [
{
"column": [
{
"name": "id",
"path": "id",
"type": "id",
"description": "Server-assigned logical id."
},
{
"name": "version_id",
"path": "meta.versionId",
"type": "id",
"description": "FHIR version id (drives NEW/UPDATED classification)."
},
{
"name": "last_updated",
"path": "meta.lastUpdated",
"type": "instant",
"description": "Instant of last mutation."
},
{
"name": "meta_source",
"path": "meta.source",
"type": "uri"
},
{
"name": "payload_version",
"path": "meta.tag.where(system='https://dsp-fhir.org/CodeSystem/payload-version').code.first()",
"type": "code",
"description": "DSP payload version this resource was last emitted under."
},
{
"name": "confidence_score",
"path": "extension('https://dsp-fhir.org/StructureDefinition/confidence-score').value.ofType(decimal)",
"type": "decimal",
"description": "DSP confidence (0..1)."
},
{
"name": "transcript_ref",
"path": "extension('https://dsp-fhir.org/StructureDefinition/transcript-turn-refs').extension('transcript').value.ofType(Reference).reference",
"type": "string",
"description": "DocumentReference/<id>/_history/<v> that pins the transcript version for turn indices."
},
{
"name": "turn_indices",
"path": "extension('https://dsp-fhir.org/StructureDefinition/transcript-turn-refs').extension('turn').value.ofType(integer)",
"type": "integer",
"collection": true,
"description": "Turn indices joined by $ground into transcript content."
},
{
"name": "spoken_forms",
"path": "extension('https://dsp-fhir.org/StructureDefinition/spoken-forms').extension('form').value.ofType(string)",
"type": "string",
"collection": true
},
{
"name": "search_terms",
"path": "extension('https://dsp-fhir.org/StructureDefinition/search-terms').extension('term').value.ofType(string)",
"type": "string",
"collection": true
},
{
"name": "patient_id",
"path": "patient.reference.substring(8)",
"type": "string"
},
{
"name": "date",
"path": "date",
"type": "dateTime"
},
{
"name": "authority_org_id",
"path": "authority.reference.substring(13)",
"type": "string"
}
],
"select": [
{
"forEach": "recommendation",
"column": [
{
"name": "vaccine_code",
"path": "vaccineCode.coding.code.first()",
"type": "code"
},
{
"name": "vaccine_system",
"path": "vaccineCode.coding.system.first()",
"type": "uri"
},
{
"name": "vaccine_display",
"path": "vaccineCode.coding.display.first()",
"type": "string"
},
{
"name": "target_disease_code",
"path": "targetDisease.coding.code.first()",
"type": "code"
},
{
"name": "forecast_status_code",
"path": "forecastStatus.coding.code.first()",
"type": "code"
},
{
"name": "dose_number",
"path": "doseNumber.ofType(positiveInt)",
"type": "positiveInt"
},
{
"name": "recommended_date",
"path": "dateCriterion.where(code.coding.code='30981-5').value.first()",
"type": "dateTime",
"description": "LOINC 30981-5 = Earliest date to give."
}
]
}
]
}
]
}dsp_immunization — DSP Immunization (administered)
Flattens an administered Immunization (post-administration).
{
"resourceType": "ViewDefinition",
"url": "https://dsp-fhir.org/ViewDefinition/dsp-immunization",
"name": "dsp_immunization",
"title": "DSP Immunization (administered)",
"status": "draft",
"description": "Flattens an administered Immunization (post-administration).",
"resource": "Immunization",
"fhirVersion": [
"4.0.1"
],
"select": [
{
"column": [
{
"name": "id",
"path": "id",
"type": "id",
"description": "Server-assigned logical id."
},
{
"name": "version_id",
"path": "meta.versionId",
"type": "id",
"description": "FHIR version id (drives NEW/UPDATED classification)."
},
{
"name": "last_updated",
"path": "meta.lastUpdated",
"type": "instant",
"description": "Instant of last mutation."
},
{
"name": "meta_source",
"path": "meta.source",
"type": "uri"
},
{
"name": "payload_version",
"path": "meta.tag.where(system='https://dsp-fhir.org/CodeSystem/payload-version').code.first()",
"type": "code",
"description": "DSP payload version this resource was last emitted under."
},
{
"name": "confidence_score",
"path": "extension('https://dsp-fhir.org/StructureDefinition/confidence-score').value.ofType(decimal)",
"type": "decimal",
"description": "DSP confidence (0..1)."
},
{
"name": "transcript_ref",
"path": "extension('https://dsp-fhir.org/StructureDefinition/transcript-turn-refs').extension('transcript').value.ofType(Reference).reference",
"type": "string",
"description": "DocumentReference/<id>/_history/<v> that pins the transcript version for turn indices."
},
{
"name": "turn_indices",
"path": "extension('https://dsp-fhir.org/StructureDefinition/transcript-turn-refs').extension('turn').value.ofType(integer)",
"type": "integer",
"collection": true,
"description": "Turn indices joined by $ground into transcript content."
},
{
"name": "spoken_forms",
"path": "extension('https://dsp-fhir.org/StructureDefinition/spoken-forms').extension('form').value.ofType(string)",
"type": "string",
"collection": true
},
{
"name": "search_terms",
"path": "extension('https://dsp-fhir.org/StructureDefinition/search-terms').extension('term').value.ofType(string)",
"type": "string",
"collection": true
},
{
"name": "status",
"path": "status",
"type": "code"
},
{
"name": "patient_id",
"path": "patient.reference.substring(8)",
"type": "string"
},
{
"name": "encounter_id",
"path": "encounter.reference.substring(10)",
"type": "string"
},
{
"name": "occurrence_datetime",
"path": "occurrence.ofType(dateTime)",
"type": "dateTime"
},
{
"name": "vaccine_code",
"path": "vaccineCode.coding.code.first()",
"type": "code"
},
{
"name": "vaccine_system",
"path": "vaccineCode.coding.system.first()",
"type": "uri"
},
{
"name": "vaccine_display",
"path": "vaccineCode.coding.display.first()",
"type": "string"
},
{
"name": "lot_number",
"path": "lotNumber",
"type": "string"
},
{
"name": "expiration_date",
"path": "expirationDate",
"type": "date"
},
{
"name": "site_code",
"path": "site.coding.code.first()",
"type": "code"
},
{
"name": "route_code",
"path": "route.coding.code.first()",
"type": "code"
},
{
"name": "dose_quantity_value",
"path": "doseQuantity.value",
"type": "decimal"
},
{
"name": "dose_quantity_unit",
"path": "doseQuantity.unit",
"type": "string"
},
{
"name": "performer_practitioner_id",
"path": "performer.actor.reference.where($this.startsWith('Practitioner/')).substring(13).first()",
"type": "string"
}
]
}
]
}IMMUNIZATION_ORDER
type collapses two FHIR concepts. The IG routes based on whether the DSP payload
carries evidence of administration (administered_at, lot_number,
status=completed). Producers should split in-band where
possible; consumers treat either shape as valid.