Skip to content

Immunization Profile

Canonical../StructureDefinition/nexus-emr-core-immunization
Statusdraft · 1.26.0
BaseImmunization (constraint)
SourceFSH · JSON

Nexus EMR profile for Immunization resources, aligned with CA-Core+ and CII requirements. Records details about vaccines administered to a patient.

TypedFhir API / Pydantic schema

The typed accessor surface Immunization exposes for Immunization — generated from this IG's compiled profile; each typed accessor has a validating raw-FHIR twin (xRaw) where marked. The three ports are parity-enforced.

The AI-facing shape: from typed_fhir.facade.generated.schemas import ImmunizationSchemamodel_json_schema() is a structured-output / tool definition; instantiating validates an extraction. Generated source.

class ImmunizationSchema(BaseModel):
    """AI-facing shape of the Immunization profile: the facade's typed accessor
    surface (curated + salient fields) as a pydantic model. `model_json_schema()` is a
    structured-output / tool schema; instantiating validates an extraction."""

    model_config = ConfigDict(extra="forbid")

    status: Literal["completed", "entered-in-error", "not-done"] | None = Field(
        None,
        description=(
            "completed | entered-in-error | not-done. Indicates the current status of the "
            "immunization event. Note: Will generally be 'completed' for administered vaccines. "
            "Immunization.status — 1..1"
        ),
    )
    status_reason: Concept | None = Field(
        None,
        description=(
            "Why the dose was not given (with status = not-done). Why this dose was not "
            "administered: patient objection, a contraindication, an out-of-stock product, a "
            "deferral. Read with `status`. This element is meaningful only where `status` is "
            "`not-done`; a `completed` immunization carrying a status reason is contradicting "
            "itself. Conversely, a `not-done` immunization SHOULD carry one -- a record that says "
            "only that a dose was not given tells a later reader nothing about whether to offer "
            "it again. Note: This is the element a patient refusal lands on for an Immunization, "
            "which is why `Immunization` carries no prevention-status extension: `status = "
            "not-done` plus a patient-objection status reason expresses refusal natively, where "
            "an Observation needs the extension to say the same thing. The binding is R4's own "
            "(`immunization-status-reason`, example strength) and is not narrowed here; carry the "
            "source system's own coding alongside where the value was mapped. "
            "Immunization.statusReason — 0..1"
        ),
    )
    vaccine_code: Concept | None = Field(
        None,
        description=(
            "Vaccine product with raw code support. Vaccine product administered or to be "
            "administered. REQUIRED: text element for human readability RECOMMENDED: a Canadian "
            "vaccine vocabulary where a coded value is available -- the National Vaccine "
            "Catalogue (NVC), whose generic-agent, tradename and antigen value sets are published "
            "over SNOMED CT CA, or SNOMED CT itself ACCEPTED: CVX on a record imported from a US "
            "source, carried as received rather than rewritten OPTIONAL: Raw EMR codes for source "
            "system preservation CVX is the US CDC's vaccine vocabulary and is not used in "
            "Canada's immunization stack; Ontario, OntarioMD and PHAC all work from NVC or SNOMED "
            "CT. A record that already carries a CVX code is still valid here -- this element is "
            "unbound, and rewriting a code received from a sending system would lose what that "
            "system meant. The text element ensures human readability even when coded values are "
            "not recognized. Note: Where this code was mapped from a source system's own "
            "vocabulary, carry the raw coding alongside the mapped one, flagged `userSelected = "
            "true`. See [Carrying the raw "
            "code](../guide/patterns/raw-codes.md). "
            "Immunization.vaccineCode — 1..1"
        ),
    )
    patient: Reference | None = Field(
        None,
        description=(
            "Who was immunized. The patient who received or is to receive the immunization. Must "
            "reference using Nexus EMR patient identifier. Note: References should use "
            "identifier-based references following Nexus EMR patterns. Immunization.patient — "
            "1..1"
        ),
    )
    encounter: Reference | None = Field(
        None,
        description=(
            "Encounter when immunization was given. The encounter during which this immunization "
            "was administered. Optional but provides important clinical context. Note: Linking to "
            "encounter helps establish the clinical context of the immunization. "
            "Immunization.encounter — 0..1"
        ),
    )
    report_origin: Concept | None = Field(
        None,
        description=(
            "Indicates the source of a secondarily reported record. The source of the data when "
            "the report of the immunization event is not based on information from the person who "
            "administered the vaccine. Note: Should not be populated if primarySource = True, not "
            "required even if primarySource = False. Immunization.reportOrigin — 0..1"
        ),
    )
    lot_number: str | None = Field(
        None,
        description=(
            "Vaccine lot number. Lot number of the vaccine product. Immunization.lotNumber — 0..1"
        ),
    )
    expiration_date: FuzzyDate | None = Field(
        None,
        description=(
            "Vaccine expiration date. Date vaccine batch expires. Immunization.expirationDate — "
            "0..1"
        ),
    )
    site: Concept | None = Field(
        None,
        description=(
            "Body site with raw code support. Body site where vaccine was administered. "
            "RECOMMENDED: SNOMED CT or other standard terminology when available OPTIONAL: Raw "
            "EMR codes for source system preservation. Note: Useful for tracking injection site "
            "reactions and following protocols. Immunization.site — 0..1"
        ),
    )
    route: Concept | None = Field(
        None,
        description=(
            "Administration route with raw code support. The path by which the vaccine product is "
            "taken into the body. RECOMMENDED: SNOMED CT or other standard terminology when "
            "available OPTIONAL: Raw EMR codes for source system preservation. Note: The route "
            "affects absorption and effectiveness of the vaccine. Immunization.route — 0..1"
        ),
    )
    dose_quantity: Quantity | None = Field(
        None,
        description=(
            "Amount of vaccine administered. The quantity of vaccine product that was "
            "administered. Immunization.doseQuantity — 0..1"
        ),
    )
    performer: dict | None = Field(
        None,
        description=(
            "Who performed the immunization; repeat for an outside performer. Who administered "
            "the vaccine. A performer this system holds a record for is referenced normally, with "
            "`actor.reference` and an `actor.display` carrying the readable name. A performer it "
            "does NOT hold a record for -- a clinician at an outside clinic whose administration "
            "is being recorded here -- is a **display-only** reference: `actor.display` carries "
            "the name as recorded and `actor.reference` is absent. The element repeats, so a "
            "record may name both. A consumer distinguishes them by whether `actor.reference` is "
            "present, never by position. Note: A display-only performer has no `actor.reference` "
            "to resolve and therefore does not conform to the referenced profiles below -- that "
            "is intended, and is the R4 shape for naming a party that has no resource. `function` "
            "is available to say in what capacity each performer acted and is not constrained "
            "here. Immunization.performer — 0..*"
        ),
    )
    note: dict | None = Field(
        None,
        description=(
            "Clinical comments on the immunization -- one whole comment per repeat. Free-text "
            "clinical comment about this immunization: what a person wanted to say about it that "
            "no other element carries. **One whole comment per repeat.** `note.text` is the "
            "comment in full, and a consumer renders it verbatim. **`note.text` is not a carrier "
            "for other fields.** A consumer MUST NOT parse it for prefixes, markers, keys or any "
            "other in-band convention, and a producer MUST NOT encode in it a value that belongs "
            "to an element or an extension of its own. Anything with its own editing lifecycle "
            "gets its own address: the instructions given to the patient are the [prevention "
            "instructions](../fhir/StructureDefinition-nexus-prevention-instructions.md) "
            "extension, an outside administering provider is a display-only `performer`, and the "
            "reason a dose was not given is `statusReason`. Note: Attribution is OPTIONAL here, "
            "unlike on a task. `author[x]` and `time` keep their base R4 cardinality: a producer "
            "that has them SHOULD write them, a consumer displays them when present, and no "
            "consumer may require them -- comments reaching this element from a source system "
            "routinely carry neither. This is why the element is a plain `Annotation` rather than "
            "the [Task "
            "Note](../fhir/StructureDefinition-nexus-emr-task-note.md) "
            "profile, which requires both because a task's turns must each say who said it. "
            "Immunization.note — 0..*"
        ),
    )
    reason_code: Concept | None = Field(
        None,
        description=(
            "Why immunization occurred. Reasons why the vaccine was administered. "
            "Immunization.reasonCode — 0..*"
        ),
    )
    subpotent_reason: Concept | None = Field(
        None,
        description=(
            "Reason for being subpotent. Reason why a dose is considered to be subpotent. "
            "Immunization.subpotentReason — 0..*"
        ),
    )
    program_eligibility: Concept | None = Field(
        None,
        description=(
            "Patient eligibility for a vaccination program. Indicates a patient's eligibility for "
            "a funding program. Immunization.programEligibility — 0..*"
        ),
    )
    funding_source: Concept | None = Field(
        None,
        description=(
            "Funding source for the vaccine. Indicates the source of the vaccine actually "
            "administered. This may be different than the patient eligibility (e.g. the patient "
            "may be eligible for a publically purchased vaccine but due to inventory issues, "
            "vaccine purchased with private funds was actually administered). "
            "Immunization.fundingSource — 0..1"
        ),
    )
    occurrence: FuzzyDate | None = Field(
        None,
        description=(
            "When vaccine was administered. The date/time when the vaccine was administered to "
            "the patient. Note: This is the administration date, not when the immunization was "
            "recorded. Salient field — occurrenceDateTime"
        ),
    )