Aotearoa Immunisation Register (AIR) FHIR Implementation Guide (API-V2)
2.2.0-SNAPSHOT - ci-build
New Zealand
Aotearoa Immunisation Register (AIR) FHIR Implementation Guide (API-V2) - Local Development build (v2.2.0-SNAPSHOT) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
The "upsert" operation is a conditional-create operation, which checks whether a single immunisation event with the same primary attributes exists, and if it does, it updates the event with the new details provided. If no corresponding event is found, or multiple are found, then a create operation is performed. If an exact duplicate is found, no change is made and the existing record is returned with a meta tag indicating what happened.
The operation is used by a PMS (Practice Management System) where the AIR Identifier (Immunization.id) for the record is not yet known to the PMS and the record is updated locally.
The method also performs validation checks to ensure that the event is valid before it is saved. Validation includes Rejection Rules and Data Quality Rules.
Upon a successful response, AIR will return the AIR Identifier and current version number. The PMS system SHALL persist these values in its data store, so that subsequent updates use the Update operation.
The upsert operation achieves the following:
It performs the following:
meta.tag exact-duplicate-not-created and publish a duplicate resolution event via NEMS.meta.tag patient-identifier-immutable is returned in the response.POST https://api_endpoint/Immunization/$upsert
All headers listed in the request headers.
Post a full set of immunisation resource details. See below. The FHIR specification for an AIR Immunization resource is the AIR Immunization Profile
{
"resource": {
"resourceType": "Immunization",
"patient": {
"reference": "https://api.hip.digital.health.nz/fhir/nhi/v1/Patient/ZZZ7541",
"identifier": {
"system": "https://standards.digital.health.nz/ns/nhi-id",
"value": "ZZZ7541"
}
},
"occurrenceDateTime": "2023-01-29T00:00:00.000+13:00",
"location": {
"reference": "https://api.hip.digital.health.nz/fhir/hpi/v1/Location/FZZ835-E",
"identifier": {
"system": "https://standards.digital.health.nz/ns/hpi-facility-id",
"value": "FZZ835-E"
}
},
"status": "completed",
"statusReason": {
"coding": [
{
"system": "https://standards.digital.health.nz/ns/air-status-reason-terms",
"code": "GIVEN"
}
]
},
"vaccineCode": {
"coding": [
{
"system": "http://hl7.org/fhir/sid/cvx",
"code": "03"
}
],
"text": "Priorix"
}
}
}
AIR compares to all existing events with the Patient Identifier for the incoming event. If an exact match is found, then it does not create a new event, instead returning the existing record marked with meta.tag exact-duplicate-not-created and a duplicate resolution event is published via NEMS citing both AIR Identifiers (Immunization.id).
See Handling of Exact Duplicates for an example response.
Following that, AIR attempts to find an existing record that can be linked on NHI, Event Date (occurrence[x]), Vaccine Code and/or Indication.
For more about duplicates see Duplicate Record Handling.
AIR returns the created or updated Immunization record. If there were any issues with the operation, the response will contain an OperationOutcome resource array. The OperationOutcome resource has an informational issue indicating that the upsert operation failed. The issue array of the OperationOutcome resource would contain additional issues with appropriate severity and code values.
{
"resourceType": "Immunization",
"id": "c3640160-ad52-4aff-9bf3-fcf454c3962d",
"meta": {
"extension": [
{
"url": "https://standards.digital.health.nz/fhir/air/StructureDefinition/air-created-source-system",
"valueString": "Postman"
},
{
"url": "https://standards.digital.health.nz/fhir/air/StructureDefinition/air-created-by",
"valueString": "PostmanUser"
},
{
"url": "http://hl7.org/fhir/StructureDefinition/firstCreated",
"valueInstant": "2023-10-09T21:34:29.475+13:00"
},
{
"url": "https://standards.digital.health.nz/fhir/air/StructureDefinition/air-modified-by",
"valueString": "PostmanUser"
},
{
"url": "https://standards.digital.health.nz/fhir/air/StructureDefinition/air-modified-source-system",
"valueString": "Postman"
}
],
"versionId": "1",
"lastUpdated": "2023-10-09T21:46:16.918+13:00",
"profile": [
"https://standards.digital.health.nz/fhir/air/StructureDefinition/air-immunization"
]
},
"patient": {
"reference": "https://api.hip.digital.health.nz/fhir/nhi/v1/Patient/ZZZ7541",
"identifier": {
"system": "https://standards.digital.health.nz/ns/nhi-id",
"value": "ZZZ7541"
}
},
"occurrenceDateTime": "2023-01-29T00:00:00.000+13:00",
"location": {
"reference": "https://api.hip.digital.health.nz/fhir/hpi/v1/Location/FZZ835-E",
"identifier": {
"system": "https://standards.digital.health.nz/ns/hpi-facility-id",
"value": "FZZ835-E"
}
},
"status": "completed",
"statusReason": {
"coding": [
{
"system": "https://standards.digital.health.nz/ns/air-status-reason-terms",
"code": "GIVEN",
"display": "Vaccination given"
}
]
},
"vaccineCode": {
"coding": [
{
"system": "http://hl7.org/fhir/sid/cvx",
"version": "1.0.0",
"code": "03",
"display": "MMR"
}
],
"text": "Priorix"
}
}
The NHI number is immutable. When the NHI number in the request does not match the NHI of the stored record, then the meta.tag "patient-identifier-immutable" is inserted in the response. The updated record is stored with the existing NHI number, not the one provided.
"meta" : {
...
"tag" : [
{
"system" : "https://standards.digital.health.nz/ns/air-processing-terms",
"code" : "patient-identifier-immutable",
"display" : "Patient identifier not updated - identifier is immutable for this operation"
}
]
}
The response upon identifying an exact duplicate is:
exact-duplicate-not-createdresource.id....
"meta" : {
...
"tag" : [
{
"system" : "https://standards.digital.health.nz/ns/air-processing-terms",
"code" : "exact-duplicate-not-created",
"display" : "Record already exists"
}
]
} ...
...
"meta": {
"extension": [
// ... other meta extensions ...
{
"url": "https://standards.digital.health.nz/fhir/air/StructureDefinition/air-data-quality-assessment",
"extension": [
{
"url": "dqScore",
"valueInteger": 100
},
{
"url": "dqLastUpdated",
"valueDateTime": "2026-10-12T23:38:49.276+00:00"
},
{
"url": "dqStatus",
"valueString": "I"
},
{
"url": "DQViolations",
"extension": [
{
"url": "DQViolation",
"extension": [
{
"url": "violationCode",
"valueString": "800"
},
{
"url": "violationType",
"valueString": "duplicate"
},
{
"url": "violationWeighting",
"valueInteger": 0
},
{
"url": "violationMessage",
"valueString": "This Immunization resource has been identified as a duplicate of existing Immunization resources"
},
{
"url": "violationElement",
"valueString": "Immunization.where(id in '7b992ec3-9c71-4ae4-9ab2-42a9f75d5f4c')"
}
]
}
]
}
]
}
], ...
Any FHIR scope that includes system/immunization.c or system/immunization.u, for example system/immunization.cruds or system/immunization.c
The Upsert API may be invoked only when a PMS updates a record that was persisted in its local data store prior to the AIR API coming into use. The record would have been sent to the AIR via HL7 messaging, in which case it has yet to be linked to the AIR by the AIR Identifier. Applications that do not persist immunisation event records locally shall not use the Upsert API.