Metriport · AsyncAPI Specification

Metriport Webhooks

Version

View Spec View on GitHub HealthcareMedical RecordsFHIRHealth DataWearablesOpen-SourceAsyncAPIWebhooksEvents

AsyncAPI Specification

Raw ↑
generated: '2026-08-14'
method: searched
source: >-
  https://docs.metriport.com/medical-api/handling-data/webhooks-with-nq and
  https://docs.metriport.com/medical-api/getting-started/webhooks
description: >-
  Metriport's event surface, captured as a webhook catalogue. No AsyncAPI
  document is published and none was authored here — the provider ships no
  machine-readable event contract, only prose tables. The surface itself is
  substantial: fifteen event types across five prefixed categories, HMAC-signed,
  with a ping handshake and manual replay. It is outbound HTTP POST only; there
  is no WebSocket, SSE or message-broker surface (see review.yml).
asyncapi_published: false
asyncapi_document: null
transport: outbound HTTPS POST to a customer-configured URL
configuration:
  dashboard: https://dash.metriport.com/developers
  api: Update Settings (POST /medical/v1/settings)
  status: Get Webhook Status (GET /medical/v1/settings/webhook)
  retry: Retry Webhook requests
security:
  signature_header: x-metriport-signature
  algorithm: HMAC-SHA256 over the raw request body
  key: Account webhook key, regenerated by clearing and re-setting the webhook URL
  guidance: Do not parse the body before computing the signature; compare with a constant-time equality check.
delivery:
  automatic_retries: false
  manual_retry: Dashboard button, or the Retry Webhook operation after checking Get Webhook Status
  response_deadline_seconds: 4
  expected_response: HTTP 200, empty body
  redirects_followed: false
  at_least_once: true
  consumer_requirement: The endpoint must be idempotent — the same payload may arrive more than once.
envelope:
  meta.messageId: Message identifier from Metriport, for debugging.
  meta.requestId: Identifier of the request that started the async flow. Optional.
  meta.when: ISO-8601 UTC timestamp of original send.
  meta.type: The event type, or "ping".
  meta.data: Metadata echoed back from the initiating API call. Absent on real-time patient notifications.
handshake:
  type: ping
  request: '{ "ping": "<random-sequence>", "meta": { ... , "type": "ping" } }'
  expected_response: '{ "pong": "<random-sequence>" }'
categories:
  - prefix: network-query.*
    name: Network Query
    purpose: Data retrieval from health networks (HIEs, pharmacies, labs). One webhook per source as each completes.
    payload_note: Each carries consolidatedDataUrl, a presigned S3 URL for the patient's aggregated record.
    events:
      - {type: network-query.hie, description: HIE data (documents from Health Information Exchanges) is ready.}
      - {type: network-query.pharmacy, description: Pharmacy data (medication prescription and pickup history) is ready.}
      - {type: network-query.lab, description: Laboratory data (lab results) is ready.}
      - {type: network-query.hie.first-data-ready, description: Early HIE data is available to reingest, before the full HIE query completes. Sent at most once.}
  - prefix: medical.*
    name: Medical Data
    purpose: Consolidated data queries, bulk operations and document downloads. Triggered by explicit API calls.
    events:
      - {type: medical.consolidated-data, description: Result of a Consolidated Data Query.}
      - {type: medical.bulk-patient-create, description: Status updates for Bulk Patient Create.}
      - {type: medical.document-bulk-download-paged, description: Download URLs for Bulk Document Download.}
  - prefix: message.*
    name: Message
    purpose: Secure practitioner-to-practitioner messaging, both directions.
    events:
      - {type: message.status, description: Final delivery status for an outbound Send Message request — acknowledged, or failed.}
      - {type: message.received, description: A new message received from another practitioner.}
  - prefix: patient.*
    name: Patient Notifications
    purpose: Real-time ADT, pharmacy and laboratory updates. Enabled per Cohort.
    payload_note: Each carries a url to download a FHIR Bundle with the complete encounter data.
    events:
      - {type: patient.laboratory, description: Patient has received Laboratory data.}
      - {type: patient.pharmacy, description: Patient has received Medication data.}
      - {type: patient.admit, description: Patient has been admitted to a healthcare facility.}
      - {type: patient.transfer, description: Patient has been transferred between locations.}
      - {type: patient.discharge, description: Patient has been discharged from a healthcare facility.}
  - prefix: ias.*
    name: Individual Access (IAS)
    purpose: Identity verification for Individual Access Services flows. Delivered to the same webhook URL.
    events:
      - {type: ias.identity.verified, description: The user completed hosted identity verification; includes proofedIdentityId for IAS queries.}
  - prefix: ping
    name: Handshake
    purpose: Connection validation.
    events:
      - {type: ping, description: Validation of the webhook connection between Metriport and your app.}
event_count: 16
legacy:
  - url: https://docs.metriport.com/medical-api/handling-data/webhooks.md
    note: '"Receiving Webhooks (Legacy)" — superseded by the Network Query webhook guide.'
testing:
  sandbox: Dashboard "Test events" control sends Patient Admit / Transfer / Discharge payloads. See sandbox/metriport-sandbox.yml.
  sample_servers:
    - https://github.com/metriport/metriport/blob/develop/samples/typescript-express/src/mock-webhook.ts
    - https://github.com/metriport/metriport/blob/develop/samples/python-fast-api/mock-webhook.py
maintainers:
  - FN: Kin Lane
    email: kin@apievangelist.com