> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metriport.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Real-time Patient Notifications

> Monitor your patient's journey through health systems in real-time

# Overview

Metriport's **Real-time Patient Notifications** are your way to receive real-time updates on a patient's journey through a health system. You can trigger a workflow once a patient is admitted to a health system, check their diagnosis within moments of them being discharged, and so much more.

## Working with Real-time Patient Notifications

### Webhook schema [(Event Reference)](#event-reference)

Each real-time notification we send via webhook has a payload that includes key information about
the event and a `url` field to a patient notification bundle containing the FHIR data relevant to
that notification. The exact payload shape and bundle contents vary by event type. For ADT events,
the `url` points to a [Patient Encounter Bundle](/medical-api/handling-data/patient-encounter-bundle).

```json theme={null}
{
  "meta": {
    "messageId": "00000000-0000-0000-0000-000000000000",
    "requestId": "11111111-1111-1111-1111-111111111111",
    "when": "2025-01-30T23:00:01.000Z",
    "type": "patient.admit",
    "data": {
      "cxCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "url": "<presigned-download-url>",
    "patientId": "metriport-patient-uuid",
    "externalId": "your-first-party-id",
    "whenSourceSent": "2025-01-30T22:58:45.000Z",
    "additionalIds": {
      "athenahealth": ["00000"]
    },
    "admitTimestamp": "2025-01-28T23:00:00.000Z"
  }
}
```

If you want to access the clinical data, download the bundle from the `url`. For ADT events, we
recommend understanding [The ADT Encounter Model](#the-adt-encounter-model) below before working
with the [Patient Encounter Bundle](/medical-api/handling-data/patient-encounter-bundle).

<Info>
  The URL remains valid and available for download for 600
  seconds (10 minutes).
</Info>

### The ADT Encounter Model

For ADT notifications, Metriport maintains the real-time state of a patient's journey through the
health system. Each of these patient journeys is represented via FHIR data through an
[Encounter](https://hl7.org/fhir/R4/encounter.html).

```json theme={null}
{
  "resourceType": "Encounter",
  "status": "finished",
  "period": {
    "start": "2024-03-15T14:20:00.000Z",
    "end": "2024-03-15T16:45:00.000Z"
  },
  "reasonCode": [
    {
      "text": "Chest pain"
    }
  ],
  "location": [
    {
      "location": {
        "reference": "Location/3ca5e8d2-7c84-45ab-91e7-834f8becde12",
        "type": "Location",
        "display": "Memorial Hospital"
      }
    }
  ]
  // And much more
}
```

But FHIR data relies on references to function. An Encounter might reference a subject, a practitioner, or a location - as the example above does (see the `reference` field in location.). Each root unit of data in FHIR is called a 'Resource' and each of type of resource has its own corresponding schema. It's common for resources to include references to one another.

To provide comprehensive data about the Encounter for ADT events, we serve a
[Patient Encounter Bundle](/medical-api/handling-data/patient-encounter-bundle) (a FHIR
[Bundle](https://hl7.org/fhir/R4/bundle.html)) via the `url` in the patient notification.

```json theme={null}
{
    "resourceType": "Bundle",
    "type": "message",
    "timestamp": "2020-05-08T13:10:15Z",
    "id": "message-uuid",
    "entry": [
      { /* the FHIR Patient */ },
      { /* a FHIR Encounter */ },
      // Other resources that are directly or transitively referenced via the FHIR encounter
      { /* Another resource */ },
      { /* Another resource */ },
      { /* Another resource */ },
      ...
    ]
}
```

For ADT notifications, the first two items in the bundle are the applicable patient and root
Encounter. Every item thereafter is a resource referenced by the Encounter.

If you're unfamiliar with FHIR, read our [FHIR Overview](medical-api/fhir/overview).

### Handling Patient Notifications

We may extend the patient notification types, so we recommend that you do a **strict** match when checking the handler type. If using a typed language like typescript, this also allows you to typecast the payload based on the appropriate event type.

See below.

```typescript theme={null}
import {
  PatientAdmitPayload,
  PatientDischargePayload,
} from "@metriport/api-sdk";

if (event.meta.type === "patient.admit") {
  const payload = event.payload as PatientAdmitPayload;
  // process admit message
}
if (event.meta.type === "patient.transfer") {
  const payload = event.payload as PatientTransferPayload;
  // process transfer message
}
if (event.meta.type === "patient.discharge") {
  const payload = event.payload as PatientDischargePayload;
  // process discharge message
}
```

## How to enable real-time notifications

You can enable real-time notifications for the following sources:

* **ADTs**: admission, discharge, and transfer notifications (and more) as patients move through healthcare facilities.

<Info>
  New updates to subscribe or remove patients from ADTs are only processed once a week, on Saturdays.
</Info>

* **Pharmacies**: notifications when patients get new prescriptions, pickup medications, and more.
* **Laboratories**: notifications for new patient lab results.

Set up [one or more Cohorts](/medical-api/handling-data/cohorts) and associate the patients you want to have notifications enabled to the Cohorts.

## Event Reference

### `patient.laboratory`

A Patient Laboratory event indicates that a new laboratory notification is available for a patient.

#### Schema

<ResponseField name="meta" required>
  Metadata about the message.

  <Expandable title="meta properties">
    <Snippet file="patient-notification-meta-properties-common.mdx" />

    <ResponseField name="type" type="string" required>
      The type of the patient webhook data message. For a laboratory notification, it will be
      `patient.laboratory`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="payload" required>
  <Expandable title="payload properties">
    <ResponseField name="url" type="string" required>
      The URL to download the patient notification bundle containing the FHIR data representing the
      comprehensive notification. It's valid for 10 minutes.
    </ResponseField>

    <Snippet file="patient-notification-patient-fields.mdx" />

    <Snippet file="patient-notification-additional-ids.mdx" />

    <ResponseField name="specimenCollectedDate" type="string">
      When the lab specimen was collected for this notification.
    </ResponseField>
  </Expandable>
</ResponseField>

#### Example payload

```json theme={null}
{
  "meta": {
    "messageId": "00000000-0000-0000-0000-000000000000",
    "requestId": "11111111-1111-1111-1111-111111111111",
    "when": "2026-03-26T18:00:00.000Z",
    "type": "patient.laboratory",
    "data": {
      "cxCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "url": "<presigned-download-url>",
    "patientId": "metriport-patient-uuid",
    "externalId": "your-first-party-id",
    "additionalIds": {
      "athenahealth": ["00000"]
    },
    "specimenCollectedDate": "2026-03-26T18:00:00.000Z"
  }
}
```

### `patient.pharmacy`

A Patient Pharmacy event indicates that a new pharmacy notification is available for a patient.

#### Schema

<ResponseField name="meta" required>
  Metadata about the message.

  <Expandable title="meta properties">
    <Snippet file="patient-notification-meta-properties-common.mdx" />

    <ResponseField name="type" type="string" required>
      The type of the patient webhook data message. For a pharmacy notification, it will be
      `patient.pharmacy`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="payload" required>
  <Expandable title="payload properties">
    <ResponseField name="url" type="string" required>
      The URL to download the patient notification bundle containing the FHIR data representing the
      comprehensive notification. It's valid for 10 minutes.
    </ResponseField>

    <Snippet file="patient-notification-patient-fields.mdx" />

    <Snippet file="patient-notification-additional-ids.mdx" />

    <ResponseField name="medicationDispensedDate" type="string">
      When the medication in this notification was dispensed.
    </ResponseField>
  </Expandable>
</ResponseField>

#### Example payload

```json theme={null}
{
  "meta": {
    "messageId": "00000000-0000-0000-0000-000000000000",
    "requestId": "11111111-1111-1111-1111-111111111111",
    "when": "2026-03-26T18:00:00.000Z",
    "type": "patient.pharmacy",
    "data": {
      "cxCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "url": "<presigned-download-url>",
    "patientId": "metriport-patient-uuid",
    "externalId": "your-first-party-id",
    "additionalIds": {
      "athenahealth": ["00000"]
    },
    "medicationDispensedDate": "2026-03-26T18:00:00.000Z"
  }
}
```

### `patient.admit`

A Patient Admit event is emitted when a patient undergoes the admission process, assigning them a bed. It signals the official start of a patient's stay in a healthcare facility. It includes short stay and "John Doe" (patient name unknown) admissions.

#### Schema

<ResponseField name="meta" required>
  Metadata about the message.

  <Expandable title="meta properties">
    <Snippet file="patient-notification-meta-properties-common.mdx" />

    <ResponseField name="type" type="string" required>
      The type of the patient webhook data message. For an admit, it will be `patient.admit`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="payload" type="PatientAdmitPayload" required>
  <Expandable title="payload properties">
    <ResponseField name="url" type="string" required>
      The URL to download the [Patient Encounter Bundle](/medical-api/handling-data/patient-encounter-bundle) containing the FHIR data representing the comprehensive encounter. It's valid for 10 minutes.
    </ResponseField>

    <Snippet file="patient-notification-patient-fields.mdx" />

    <ResponseField name="whenSourceSent" type="string" required>
      Specifies when this data was initially shared with Metriport.
    </ResponseField>

    <Snippet file="patient-notification-additional-ids.mdx" />

    <ResponseField name="admitTimestamp" type="string">
      When the patient for this encounter was officially admitted for care.
    </ResponseField>
  </Expandable>
</ResponseField>

#### Example payload

```json theme={null}
{
  "meta": {
    "messageId": "00000000-0000-0000-0000-000000000000",
    "requestId": "11111111-1111-1111-1111-111111111111",
    "when": "2025-01-30T23:00:01.000Z",
    "type": "patient.admit"
  },
  "payload": {
    "url": "<presigned-download-url>",
    "patientId": "metriport-patient-uuid",
    "externalId": "your-first-party-id",
    "whenSourceSent": "2025-01-30T22:58:45.000Z",
    "additionalIds": {
      "athenahealth": ["00000"]
    },
    "admitTimestamp": "2025-01-28T23:00:00.000Z"
  }
}
```

### `patient.transfer`

A Patient Transfer event indicates that a patient has been moved from one location to another within a healthcare system. This could represent a transfer between departments, units, or facilities.

#### Schema

<ResponseField name="meta" required>
  Metadata about the message.

  <Expandable title="meta properties">
    <Snippet file="patient-notification-meta-properties-common.mdx" />

    <ResponseField name="type" type="string" required>
      The type of the patient webhook data message. For a transfer, it will be `patient.transfer`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="payload" type="PatientTransferPayload" required>
  <Expandable title="payload properties">
    <ResponseField name="url" type="string" required>
      The URL to download the [Patient Encounter Bundle](/medical-api/handling-data/patient-encounter-bundle) containing the FHIR data representing the comprehensive encounter. It's valid for 10 minutes.
    </ResponseField>

    <Snippet file="patient-notification-patient-fields.mdx" />

    <ResponseField name="whenSourceSent" type="string" required>
      Specifies when this data was initially shared with Metriport.
    </ResponseField>

    <Snippet file="patient-notification-additional-ids.mdx" />

    <ResponseField name="admitTimestamp" type="string">
      When the patient for this encounter was officially admitted for care.
    </ResponseField>

    <ResponseField name="transfers" type="array" required>
      An array of transfer records, each representing a single transfer of the patient from one location to another.

      <Expandable title="array item properties">
        <ResponseField name="timestamp" type="string">
          When this specific transfer occurred.
        </ResponseField>

        <ResponseField name="sourceLocation" type="object">
          Information about the location the patient was transferred from.

          <Expandable title="object properties">
            <ResponseField name="name" type="string">
              The name of the source location.
            </ResponseField>

            <ResponseField name="type" type="string">
              The type of the source location (e.g., department, unit, facility).
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="destinationLocation" type="object">
          Information about the location the patient was transferred to.

          <Expandable title="object properties">
            <ResponseField name="name" type="string">
              The name of the destination location.
            </ResponseField>

            <ResponseField name="type" type="string">
              The type of the destination location (e.g., department, unit, facility).
            </ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

#### Example payload

```json theme={null}
{
  "meta": {
    "messageId": "00000000-0000-0000-0000-000000000000",
    "requestId": "11111111-1111-1111-1111-111111111111",
    "when": "2025-01-30T20:30:01.000Z",
    "type": "patient.transfer",
    "data": {
      "cxCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "url": "<presigned-download-url>",
    "patientId": "metriport-patient-uuid",
    "externalId": "your-first-party-id",
    "whenSourceSent": "2025-01-30T20:28:30.000Z",
    "additionalIds": {
      "athenahealth": ["00000"]
    },
    "admitTimestamp": "2025-01-28T23:00:00.000Z",
    "transfers": [
      {
        "timestamp": "2025-01-29T15:45:00.000Z",
        "sourceLocation": {
          "name": "Emergency Department",
          "type": "department"
        },
        "destinationLocation": {
          "name": "General Medical Ward",
          "type": "unit"
        }
      },
      {
        "timestamp": "2025-01-30T20:30:00.000Z",
        "sourceLocation": {
          "name": "General Medical Ward",
          "type": "unit"
        },
        "destinationLocation": {
          "name": "Intensive Care Unit",
          "type": "unit"
        }
      }
    ]
  }
}
```

### `patient.discharge`

A Patient Discharge event indicates the end of a patient's stay in a healthcare facility. The patient now has the status "discharged" and an officially recorded discharge date.

#### Schema

<ResponseField name="meta" required>
  Metadata about the message.

  <Expandable title="meta properties">
    <Snippet file="patient-notification-meta-properties-common.mdx" />

    <ResponseField name="type" type="string" required>
      The type of the patient webhook data message. For a discharge, it will be `patient.discharge`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="payload" type="PatientDischargePayload" required>
  <Expandable title="payload properties">
    <ResponseField name="url" type="string" required>
      The URL to download the [Patient Encounter Bundle](/medical-api/handling-data/patient-encounter-bundle) containing the FHIR data representing the comprehensive encounter. It's valid for 10 minutes.
    </ResponseField>

    <Snippet file="patient-notification-patient-fields.mdx" />

    <ResponseField name="whenSourceSent" type="string" required>
      Specifies when this data was initially shared with Metriport.
    </ResponseField>

    <Snippet file="patient-notification-additional-ids.mdx" />

    <ResponseField name="admitTimestamp" type="string">
      When the patient for this encounter was officially admitted for care.
    </ResponseField>

    <ResponseField name="dischargeTimestamp" type="string">
      When the patient for this encounter was officially discharged by the provider.
    </ResponseField>
  </Expandable>
</ResponseField>

#### Example payload

```json theme={null}
{
  "meta": {
    "messageId": "00000000-0000-0000-0000-000000000000",
    "requestId": "11111111-1111-1111-1111-111111111111",
    "when": "2025-01-30T23:00:01.000Z",
    "type": "patient.discharge",
    "data": {
      "cxCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "url": "<presigned-download-url>",
    "patientId": "metriport-patient-uuid",
    "externalId": "your-first-party-id",
    "whenSourceSent": "2025-01-30T22:58:45.000Z",
    "additionalIds": {
      "athenahealth": ["00000"]
    },
    "admitTimestamp": "2025-01-28T23:00:00.000Z",
    "dischargeTimestamp": "2025-01-30T23:00:00.000Z"
  }
}
```

## Additional Resources

### FHIR Encounter

For ADT notifications, the Encounter is the core resource in a
[Patient Encounter Bundle](/medical-api/handling-data/patient-encounter-bundle). Below is an
example of a FHIR Encounter resource, which is one piece of the data you'll receive when
downloading the bundle from the notification `url`.

<Snippet file="example-adt-encounter-json.mdx" />
