Skip to main content

Overview

Metriport sends webhook messages to your app as data becomes available in our system. This allows you to react to events in real-time rather than polling for updates. For information on how to set up webhooks, see Implementing Webhooks.
When you receive a webhook message, you should respond with a 200 status code within 4 seconds. We recommend processing the webhook request asynchronously.

Webhook Categories

Metriport webhooks are organized into three categories based on their event type prefix:
CategoryPrefixPurpose
Network Querynetwork-query.*Data retrieval from health networks (HIEs, pharmacies, labs)
Medical Datamedical.*Consolidated data, bulk operations, and document downloads
Patient Notificationspatient.*Real-time ADT events (admissions, transfers, discharges)

Network Query Events

Prefix: network-query.*
Network Query events are emitted when you start a Network Query to retrieve patient data from health networks. You receive one webhook per source as each completes. Recommended flow:
  1. Start a Network Query for a patient
  2. Receive network-query.* webhooks as each source completes
  3. Download the patient record from the consolidatedDataUrl in the payload

Event Types

EventDescription
network-query.hieHIE data (documents from Health Information Exchanges) is ready
network-query.pharmacyPharmacy data (medication prescription and pickup history) is ready
network-query.labLaboratory data (lab results) is ready
Each webhook includes a consolidatedDataUrl - a presigned S3 URL to download the patient’s aggregated record, i.e. their ‘consolidated data’. This allows you to reingest the record as soon as any data source is ready.
HIE Example:
{
  "meta": {
    "messageId": "11111111-1111-1111-1111-111111111111",
    "requestId": "22222222-2222-2222-2222-222222222222",
    "when": "2024-12-26T10:03:22.000Z",
    "type": "network-query.hie",
    "data": {
      "youCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "patientId": "00000000-0000-0000-0000-000000000000",
    "externalId": "1234567890",
    "consolidatedDataUrl": "https://documents.s3.amazonaws.com/consolidated-abc123-Amz-SignedHeaders=host",
    "source": {
      "type": "hie",
      "status": "completed",
      "completedAt": "2024-12-26T10:03:20.000Z"
    }
  }
}
Pharmacy Example:
{
  "meta": {
    "messageId": "11111111-1111-1111-1111-111111111111",
    "requestId": "22222222-2222-2222-2222-222222222222",
    "when": "2024-12-26T10:04:15.000Z",
    "type": "network-query.pharmacy",
    "data": {
      "youCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "patientId": "00000000-0000-0000-0000-000000000000",
    "externalId": "1234567890",
    "consolidatedDataUrl": "https://documents.s3.amazonaws.com/consolidated-abc123-Amz-SignedHeaders=host",
    "source": {
      "type": "pharmacy",
      "source": "surescripts",
      "status": "completed",
      "completedAt": "2024-12-26T10:04:12.000Z"
    }
  }
}
Lab Example:
{
  "meta": {
    "messageId": "11111111-1111-1111-1111-111111111111",
    "requestId": "22222222-2222-2222-2222-222222222222",
    "when": "2024-12-26T10:05:30.000Z",
    "type": "network-query.lab",
    "data": {
      "youCan": "putAny",
      "stringKeyValue": "pairsHere"
    }
  },
  "payload": {
    "patientId": "00000000-0000-0000-0000-000000000000",
    "externalId": "1234567890",
    "consolidatedDataUrl": "https://documents.s3.amazonaws.com/consolidated-abc123-Amz-SignedHeaders=host",
    "source": {
      "type": "lab",
      "source": "quest",
      "status": "completed",
      "completedAt": "2024-12-26T10:05:28.000Z"
    }
  }
}
meta
required
Metadata about the message. The full format is described here.
payload
NetworkQueryPayload
required
The network query result payload for the patient.

Medical Data Events

Prefix: medical.*
Medical Data events are emitted for consolidated data queries, bulk operations, and document downloads. Unlike Network Query events which are triggered automatically after data retrieval, these events are triggered by explicit API calls.

Event Types

EventDescription
medical.consolidated-dataResult of a Consolidated Data Query
medical.bulk-patient-createStatus updates for Bulk Patient Create
medical.document-bulk-download-urlsDownload URLs for Bulk Document Download

medical.consolidated-data

You’ll receive this webhook after invoking a Consolidated Query via POST Start Consolidated Data Query. The payload contains the patient’s consolidated medical record as deduplicated, standardized FHIR data. This includes all converted documents from network queries plus any FHIR data your application has inserted directly. Note that inside the Bundle you’ll find a DocumentReference resource with attachments in the content array:
  • The first item contains an attachment with a url which can be used to download the data.
  • If requested conversionType is json, an additional attachment with contentType: "application/gzip" provides a gzip-compressed copy for faster downloads.
  • Download URLs are valid for 3 minutes
If there was no data available for the Patient, the Bundle will be empty (the entry array will have no elements).
Recommended flow:
  1. Call Start Consolidated Data Query for a patient
  2. Receive this webhook
  3. Download the data from the presigned URLs in the bundle
{
  "meta": {
    "messageId": "11111111-1111-1111-1111-111111111111",
    "requestId": "22222222-2222-2222-2222-222222222222",
    "when": "2023-08-23T22:09:11.373Z",
    "type": "medical.consolidated-data"
  },
  "patients": [
    {
      "patientId": "00000000-0000-0000-0000-000000000000",
      "externalId": "1234567890",
      "additionalIds": {
        "athenahealth": ["99992"]
      },
      "status": "completed",
      "filters": {
        "resources": "Encounter,Observation"
      },
      "bundle": {
        "resourceType": "Bundle",
        "total": 1,
        "type": "collection",
        "entry": [
          {
            "resource": {
              "resourceType": "DocumentReference",
              "subject": {
                "reference": "Patient/00000000-0000-0000-0000-000000000000"
              },
              "content": [
                {
                  "attachment": {
                    "contentType": "application/json",
                    "url": "https://documents.s3.amazonaws.com/abc123-Amz-SignedHeaders=host"
                  }
                },
                {
                  "attachment": {
                    "contentType": "application/gzip",
                    "url": "https://documents.s3.amazonaws.com/abc123.gz-Amz-SignedHeaders=host"
                  }
                }
              ]
            }
          }
        ]
      }
    }
  ]
}
meta
required
Metadata about the message. The full format is described here.
patients
PatientConsolidatedData[]
required
Array of consolidated data query results - one item per patient.

medical.bulk-patient-create

You’ll receive this webhook after invoking a bulk patient creation via POST Bulk Create Patient. The payload reports the status of the bulk creation job, allowing you to process large CSV files of patient demographics asynchronously. Note that you’ll receive multiple webhooks for a single bulk create request:
  • First, a webhook with status: "processing" confirming the job started
  • Then, a webhook with status: "completed" containing a presigned URL to download the results CSV with created patient IDs
  • Or, a webhook with status: "failed" containing a reason explaining what went wrong
  • Download URLs are valid for 3 minutes
Recommended flow:
  1. Call Bulk Create Patient with a CSV file
  2. Receive webhooks as the job progresses
  3. Download the results CSV from the presigned URL
{
  "meta": {
    "messageId": "11111111-1111-1111-1111-111111111111",
    "requestId": "22222222-2222-2222-2222-222222222222",
    "when": "2024-12-30T05:05:12.215Z",
    "type": "medical.bulk-patient-create"
  },
  "bulkPatientCreate": {
    "requestId": "22222222-2222-2222-2222-222222222222",
    "status": "completed",
    "result": "<presigned-download-url>"
  }
}
meta
required
Metadata about the message. The full format is described here.
bulkPatientCreate
BulkPatientCreate
required
The bulk patient create job status.

medical.document-bulk-download-urls

You’ll receive this webhook after invoking a bulk document download via POST Bulk Get Document URL. The payload provides presigned download URLs for all documents belonging to the specified patients, allowing you to efficiently download multiple documents in bulk. Note that the payload contains a patients array with results for each patient:
  • Each patient entry includes a status (completed or failed) and a documents array
  • Each document includes metadata (id, fileName, mimeType, etc.) and a presigned url
  • Download URLs are valid for 10 minutes
Recommended flow:
  1. Call Bulk Get Document URL with patient IDs
  2. Receive this webhook
  3. Download documents using the presigned URLs before they expire
{
  "meta": {
    "messageId": "11111111-1111-1111-1111-111111111111",
    "requestId": "22222222-2222-2222-2222-222222222222",
    "when": "2023-11-30T05:05:12.215Z",
    "type": "medical.document-bulk-download-urls"
  },
  "patients": [
    {
      "status": "completed",
      "patientId": "00000000-0000-0000-0000-000000000000",
      "externalId": "1234567890",
      "additionalIds": {
        "athenahealth": ["99992"]
      },
      "documents": [
        {
          "id": "33333333-3333-3333-3333-333333333333",
          "size": 40670,
          "fileName": "document.xml",
          "description": "Patient Diagnoses",
          "status": "current",
          "indexed": "2019-09-07T15:50:00.000Z",
          "mimeType": "application/xml",
          "url": "<presigned-download-url>"
        }
      ]
    }
  ]
}
meta
required
Metadata about the message. The full format is described here.
patients
DocumentBulkDownloadUrls[]
required
Array of results per patient.

Patient Notification Events

Prefix: patient.*
Patient Notification events provide real-time ADT (Admission, Discharge, Transfer) updates as patients move through healthcare facilities. These are part of Real-time Patient Notifications.

Event Types

EventDescription
patient.admitPatient has been admitted to a healthcare facility
patient.transferPatient has been transferred between locations
patient.dischargePatient has been discharged from a healthcare facility
To enable patient notifications, configure them in a Cohort and associate the patients you want to monitor.
Each webhook includes a url to download a FHIR Bundle containing the complete encounter data.
{
  "meta": {
    "messageId": "11111111-1111-1111-1111-111111111111",
    "requestId": "22222222-2222-2222-2222-222222222222",
    "when": "2025-01-30T23:00:01.000Z",
    "type": "patient.admit"
  },
  "payload": {
    "url": "<presigned-download-url>",
    "patientId": "00000000-0000-0000-0000-000000000000",
    "externalId": "1234567890",
    "additionalIds": {
      "athenahealth": ["99992"]
    },
    "admitTimestamp": "2025-01-28T23:00:00.000Z"
  }
}

Full Documentation

See the complete Real-time Patient Notifications guide for detailed schemas, all event types, and the FHIR Encounter model.

Passing Metadata

You can pass metadata when calling endpoints that support webhooks. This metadata will be returned in the meta.data field of the webhook. You may use this to attach whatever metadata is relevant for your use-case - for example, external IDs. Below is an example payload you could send in the request body of one of those endpoints and how you would use the sdk: Note that the metadata param supports up to 50 custom string key-value pairs, with keys up to 40 chars, and values of up to 500 chars.
{
  "metadata": {
     "youCan": "putAny",
     "stringKeyValue": "pairsHere",
  }
}
Metriport SDK
import { MetriportMedicalApi } from "@metriport/api-sdk";

const metadata = {
    youCan: "putAny",
    stringKeyValue: "pairsHere",
};

const metriport = new MetriportMedicalApi(apiToken);

const consolidatedData = await metriport.startConsolidatedQuery(
  patientId,
  ["AllergyIntolerance", "Appointment"] as const,
  "2023-03-01",
  "2023-04-01",
  undefined,
  metadata
);