# Convert C-CDA to FHIR R4 Source: https://docs.metriport.com/converter-api/api-reference/ccda/ccda-to-fhir POST /convert/v1/ccda/to/fhir Converts the provided C-CDA document to a FHIR R4 Bundle. ## Body A valid C-CDA (R2.1) XML document. ```xml theme={null} ``` You can use [this example C-CDA from HL7](https://github.com/HL7/CDA-ccda-2.1/blob/master/examples/C-CDA_R2-1_CCD.xml) for testing purposes. ## Query Params Your internal identifier for the patient that the provided C-CDA document corresponds to. This will be used to populated the patient-related references in the returned FHIR Bundle. ## Response Returns a [FHIR R4 Bundle](/medical-api/fhir/resources/bundle) of type `batch` with the `entry` containing an array of FHIR R4 Resources being the outcome of the conversion. ```json theme={null} { "resourceType": "Bundle", "type": "batch", "entry": [ { "fullUrl": "urn:uuid:adc44b9c-3083-396f-877f-463120f6b26a", "resource": { "resourceType": "Location", "id": "adc44b9c-3083-396f-877f-463120f6b26a", "name": "Good Health Urgent Care", "address": { "line": [ "1007 Health Drive" ], "city": "Portland", "state": "OR", "country": "US", "postalCode": "99123" }, "telecom": [ { "system": "phone", "value": "+1(555)555-1030", "use": "work" } ], "type": [ { "coding": [ { "code": "1160-1", "display": "Urgent Care Center", "system": "urn:oid:2.16.840.1.113883.6.259" } ] } ] }, "request": { "method": "PUT", "url": "Location/adc44b9c-3083-396f-877f-463120f6b26a" } }, { "fullUrl": "urn:uuid:7134ccce-d097-300c-a811-e4d2fc04a4c7", "resource": { "resourceType": "Immunization", "id": "7134ccce-d097-300c-a811-e4d2fc04a4c7", "identifier": [ { "system": "urn:ietf:rfc:3986", "value": "urn:uuid:e6f1ba43-c0ed-4b9b-9f12-f435d8ad8f92" } ], "occurrenceDateTime": "1998-12-15", "vaccineCode": { "coding": [ { "code": "88", "display": "Influenza virus vaccine", "system": "http://hl7.org/fhir/sid/cvx" } ] }, "lotNumber": "1", "manufacturer": { "display": "Health LS - Immuno Inc." }, "doseQuantity": { "value": "50", "unit": "ug", "system": "http://unitsofmeasure.org" }, "status": "completed", "route": { "coding": [ { "code": "C28161", "display": "Intramuscular injection", "system": "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl" } ] }, "patient": { "reference": "Patient/123" } }, "request": { "method": "PUT", "url": "Immunization/7134ccce-d097-300c-a811-e4d2fc04a4c7" } }, ] } ``` # FHIR Converter API Source: https://docs.metriport.com/converter-api/getting-started/quickstart Follow this guide to get started converting C-CDA documents to FHIR. ## Overview Getting started with our FHIR Converter API is pretty easy, you'll just need take the following steps: 1. [Create a developer account](#1-create-a-developer-account). 2. [Generate an API key](#2-generate-an-api-key). 3. [Convert C-CDA to FHIR](#3-convert-c-cda-to-fhir). 4. [Request Production access](#4-request-api-access). Let's get into it! 🤘 ## 1. Create a developer account *** ## 2. Generate an API key Once you've created an account and confirmed your email, you'll be taken to the [dashboard home page](https://dash.metriport.com/). From here, take the following steps to get your API key: * Toggle the `Sandbox` switch in the Dashboard navbar to enter `Sandbox` mode (learn more about this [here](/converter-api/more-info/sandbox)). * In the left hand menu, click `Developers`. * On the Developers page, you'll be able to click the "Generate Secret Key" button. This Secret Key will allow you to start making requests to the Metriport API. Treat this like a password, and keep it somewhere safe! You can read the [API Keys](/medical-api/getting-started/api-keys) page to learn more about API key security best practices. If you believe your key has been compromised, you can always revoke it and then generate a new one on the Developers page by clicking the trash button beside the key. *** ## 3. Convert C-CDA to FHIR Essentially, you'll just need to send a `POST` request to the [Convert C-CDA to FHIR endpoint](/converter-api/api-reference/ccda/ccda-to-fhir), with the body containing a valid C-CDA (R2.1) XML document to convert: ```xml theme={null} ``` You can use [this example C-CDA from HL7](https://github.com/HL7/CDA-ccda-2.1/blob/master/examples/C-CDA_R2-1_CCD.xml) for testing purposes. Since C-CDAs correspond to a particular patient, you should also specify the `patientId` query param to match your patient's identifier. You'll get back a [FHIR R4 Bundle](/medical-api/fhir/resources/bundle) back, with `entry` containing an array of FHIR R4 Resources being the outcome of the conversion. ```json theme={null} { "resourceType": "Bundle", "type": "batch", "entry": [ { "fullUrl": "urn:uuid:adc44b9c-3083-396f-877f-463120f6b26a", "resource": { "resourceType": "Location", "id": "adc44b9c-3083-396f-877f-463120f6b26a", "name": "Good Health Urgent Care" } } ] } ``` See the [Convert C-CDA to FHIR endpoint](/converter-api/api-reference/ccda/ccda-to-fhir) in our API reference for more details. *** ## 4. Request Production access 🚀 To start using the Convert API for production workloads, you can take the following steps to request production API access: * In the left hand menu, click `Products & Billing`. * Click `Get Started` on the Converter API product. * Press `Book an Intro Call` and select a time and a date to talk to us. After the call, we will promptly setup your account for production access. *** ## Wrapping up That's it! 🤘 You're now well equipped to use the Metriport Converter API to convert healthcare data to various standards. For next steps, we'd recommend scoping out our [Converter API Reference](/converter-api/api-reference/ccda/ccda-to-fhir) in further detail to see the other things you can do with the API. # Athena Source: https://docs.metriport.com/ehr-apps/athena Metriport's Athena app enables seamless access to patient health data directly within the Athena EHR workflow through an embedded application in the patient's Chart. The embedded app provides access to all health data available via Metriport's dashboard and API, including the ability to initiate new Network Queries. ``` The iframe's `src` should be the embedded app URL for the view you want to render. *** ## Transitions of Care (TCM) Use the Transitions of Care view to monitor patient admissions, transfers, and discharges. ### URL format ```text Production theme={null} https://ehr.metriport.com/embed/app/transitions-of-care#access_token={token} ``` ```text Sandbox theme={null} https://ehr.sandbox.metriport.com/embed/app/transitions-of-care#access_token={token} ``` Replace `{token}` with the embed token generated by your backend. ### Redirect example Use a redirect when you want to send the user from your application to the embedded Metriport page. ```javascript Redirect theme={null} const token = "11111111-1111-1111-1111-111111111111"; const embedUrl = `https://ehr.metriport.com/embed/app/transitions-of-care#access_token=${token}`; window.location.href = embedUrl; ``` ### Iframe example Use an iframe when you want to render the embedded Metriport view directly inside a page in your application. ```html Iframe theme={null} ``` *** ## Security considerations * **Generate tokens server-side**: Embed tokens require your Metriport API key, so they should be created by your backend. * **Do not expose your API key**: Never include your Metriport API key in frontend code, mobile apps, or publicly accessible files. * **Use short token expirations**: Embed tokens can expire after up to 10 hours, but shorter durations reduce risk. * **Use the correct environment**: Sandbox tokens should only be used with sandbox URLs, and production tokens should only be used with production URLs. ## Related resources * [Create Embed Token API Reference](/medical-api/api-reference/token/create-embed-token) # Individual Access (IAS) Source: https://docs.metriport.com/medical-api/getting-started/ias Let your users pull their own medical records into your application. IAS lets a person retrieve their own medical records through your application - it's distinct from Metriport's Treatment data flow. Treatment is for clinicians providing treatment to the patient; IAS is for the patient themselves. ## How it works Create the patient that will be querying their records in Metriport using the [Create Patient](/medical-api/api-reference/patient/create-patient) endpoint, if they don't exist already. What changes between Treatment and IAS is the **purpose** of the request. You signal this with the `purposeOfUse` query parameter on [Start Network Query](/medical-api/api-reference/network/start-network-query) (`treatment` or `ias`; defaults to `treatment` when omitted). For example, [Start Network Query](/medical-api/api-reference/network/start-network-query) with IAS: ``` POST /medical/v1/network/query?patientId=018f7c31-bbbb...&purposeOfUse=ias ``` ```json theme={null} { "sources": { "hie": { "enabled": true }, "pharmacy": { "enabled": true }, "lab": { "enabled": true } }, "proofedIdentityId": "pid_018f7c30..." } ``` When `purposeOfUse` is `ias`, Metriport routes the request through IAS using identity verification artifacts that the network requires for individual access. When it's `treatment` (or omitted), Metriport routes through the Treatment rail like it does today. Data returned from IAS will be integrated into the consolidated patient record, like everything else. ## What you need to do To use IAS, your application needs to do two things on top of your existing Treatment integration: 1. **Verify the user's identity** via a Metriport-hosted session before their first IAS retrieval. Verification happens at NIST IAL2 with an approved Credential Service Provider. Metriport hosts the flow — you redirect the user in and receive a `proofedIdentityId` via webhook when they finish. 2. **Pass the `proofedIdentityId` and an active AAL2 session** on every IAS-purposed network query. AAL2 is a multifactor challenge the user satisfies in your app's session; Metriport provides the challenge flow and returns a session ID you pass via the `x-aal2-session` header. ## The full flow For a user who's never used IAS in your app: 1. Verify their identity with [Create Identity Session](/medical-api/api-reference/ias/create-identity-session). Receive `proofedIdentityId` via the [`ias.identity.verified`](/medical-api/handling-data/webhooks-with-nq#ias-identity-verified) webhook. 2. Issue a multifactor challenge with [Create AAL2 Challenge](/medical-api/api-reference/ias/create-aal2-challenge). Receive `aal2SessionId` after the user completes it. 3. Call your existing [Start Network Query](/medical-api/api-reference/network/start-network-query) with `purposeOfUse=ias` in the query string, `proofedIdentityId` in the request body, and the `x-aal2-session` header. 4. When the query completes, fetch results with your existing [Start Consolidated Data Query](/medical-api/api-reference/fhir/consolidated-data-query-post). Subsequent retrievals for the same user skip step 1. Once the user has a verified identity, you only need to refresh the AAL2 session before each new query. # Message Delivery Source: https://docs.metriport.com/medical-api/getting-started/message-delivery Exchange clinical data directly with another practitioner. This functionality is currently under construction. Please reach out to support if you'd like to use it. Message Delivery lets a practitioner exchange patient clinical data, referrals, and other communications directly with another practitioner on the network in a secure manner. ## How it works Metriport supports two methods of Message Delivery - Direct Message and Cross-Community Document Reliable Interchange (aka XCDR). To learn how to activate either one for your account, please reach out to our support. When you send a message, you are required to set the `destination` for the recipient, and Metriport determines which method to use for the exchange. All messages are stored as FHIR [Communication](/medical-api/fhir/resources/communication) resources and merged into the patient's [Consolidated Data](/medical-api/api-reference/fhir/consolidated-data-query-post), like everything else. ### Outbound The message must be in reference to a specific patient. Create the patient that you intend to exchange information about in Metriport using the [Create Patient](/medical-api/api-reference/patient/create-patient) endpoint, if they don't exist already. The message must contain a subject line, and at least one of `body` or `attachments`. If you're attaching documents, upload them first using [Upload Document](/medical-api/api-reference/document/post-upload-url) and pass the returned document IDs in `attachments`. Otherwise, you can use the [List Documents](/medical-api/api-reference/document/list-documents) endpoint with a source filter for `Metriport` to pull all document references for the document you have uploaded for the patient. To send a message to another practitioner, you will need: 1. The `patientId` from the Patient Create step mentioned above. 2. The `destination` for the recipient - refer to the [Finding a destination](#finding-a-destination) section below. 3. Optionally, the NPI of the intended recipient in `intendedRecipientNpi`. This is especially useful when the `destination` points to an organization but the message is intended for a specific practitioner. For example, [Send Message](/medical-api/api-reference/message/send-message) with an example body: ```json theme={null} { "destination": "intake@cardio.direct.partner.com", "subject": "Referral - cardiology", "body": "Please review the attached referral for cardiology consultation.", "attachments": ["00000000-0000-0000-0000-000000000000"], "intendedRecipientNpi": ["1234567890"] } ``` The endpoint returns immediately with Communication resource with the `in-progress` status while Metriport delivers the message. When the recipient acknowledges receipt, or if delivery fails, Metriport sends a [`message.status`](/medical-api/handling-data/webhooks-with-nq#message-status) webhook to [your configured URL](/medical-api/api-reference/settings/post-settings). You can also check status by polling [Get Message Status](/medical-api/api-reference/message/get-message-status), though we recommend using webhooks instead. ### Inbound When another practitioner sends a message to your organization, Metriport receives it and emits a [`message.received`](/medical-api/handling-data/webhooks-with-nq#message-received) webhook. The payload includes a presigned URL to download the full message content and attachments. Inbound messages are also available via [List Messages](/medical-api/api-reference/message/list-messages). Note that some inbound messages might not be tied to a specific patient. However, if Metriport is able to match the message to a patient, the data from the message will also be included in the patient's [Consolidated Data](/medical-api/api-reference/fhir/consolidated-data-query-post). ## What you need to do To use Message Delivery, your application needs to: 1. Configure a webhook URL so Metriport can notify you when messages are received or when outbound delivery completes. See [Implementing Webhooks](/medical-api/getting-started/webhooks). 2. Handle `message.received` and `message.status` webhooks - see [Message Events](/medical-api/handling-data/webhooks-with-nq#message-events) for payload details. 3. Upload documents before sending, if your message includes attachments - see [Upload Document](/medical-api/api-reference/document/post-upload-url). ## The full flow ### Sending a message 1. [Create Patient](/medical-api/api-reference/patient/create-patient), if they don't exist already. 2. Optionally upload documents with [Upload Document](/medical-api/api-reference/document/post-upload-url) or FHIR data with [Create Patient's Consolidated Data](/medical-api/api-reference/fhir/create-patient-consolidated) and note the document IDs. 3. Find the recipient's `destination` with [Search Destinations](/medical-api/api-reference/message/search-destinations). 4. Call [Send Message](/medical-api/api-reference/message/send-message). 5. Await the [`message.status`](/medical-api/handling-data/webhooks-with-nq#message-status) webhook, or poll [Get Message Status](/medical-api/api-reference/message/get-message-status). ### Receiving a message 1. Await the [`message.received`](/medical-api/handling-data/webhooks-with-nq#message-received) webhook. 2. Download the message from the presigned URL in the payload. 3. Optionally list historical messages with [List Messages](/medical-api/api-reference/message/list-messages). ## Finding a destination Use [Search Destinations](/medical-api/api-reference/message/search-destinations) to find where to send a message. Search by provider name and location, organization name, or the NPI. The response is a list of potential matches containing names and locations to help you disambiguate between them. Pick the one that matches best and use its `destination` property to [Send Message](/medical-api/api-reference/message/send-message). Results are ordered by Metriport's recommended preference for your account. If you already know the recipient's `destination`, you can verify it with the same endpoint, or skip search and pass it directly on send. The `destination` is an OID or a Direct email # Quickstart Source: https://docs.metriport.com/medical-api/getting-started/quickstart Follow this guide to start exchanging comprehensive patient medical data. ## Overview Getting started with our Medical API is pretty easy, you'll just need take the following steps: 1. [Create a developer account](#1-create-a-developer-account). 2. [Generate an API key](#2-generate-an-api-key). 3. [Integrate your app with Metriport](#3-integrate-your-app-with-metriport). 4. [Create Facilities and Patients](#4-create-facilities-and-patients). 5. [Query for Patient Data](#5-query-for-patient-data). 6. [Get Patient Medical Data](#6-get-patient-medical-data). 7. [Contribute Medical Data](#7-contribute-medical-data). 8. [Request API access](#8-request-api-access). Let's get into it! 🤘 ## 1. Create a developer account *** ## 2. Generate an API key After we approve your access request, take the following steps to get your API key: * Toggle the `Sandbox` switch in the Dashboard navbar to enter `Sandbox` mode (learn more about this [here](/medical-api/getting-started/sandbox)). * In the left hand menu, click `Developers`. * On the Developers page, you'll be able to click the `Generate API Key` button. The API key will only be displayed once. Please make sure to save it to a secure location before leaving the page. This API Key will allow you to start making requests to the entire Metriport API on your behalf. Treat this like a password, and keep it somewhere safe! You can read the [API Keys](/medical-api/getting-started/api-keys) page to learn more about API key security best practices. You can have up to two API keys active at once, so you can [rotate your keys](/medical-api/getting-started/api-keys#rotating-your-api-keys) without any downtime. If you believe a key has been compromised, you can always revoke it on the Developers page by clicking the trash button beside the key. *** ## 3. Integrate your app with Metriport Note that there are two ways to receive data from Metriport: * Webhook: Metriport sends patient data to your app when it becomes available: * your application exposes a webhook (endpoint), which Metriport calls when there's Patient data available after initiating a query; * to learn more about how the Webhook flow works, see [our Webhooks guide](/medical-api/getting-started/webhooks). * API: Your app requests data from Metriport: * your application polls Metriport for Patients' medical data after initiating a query to fetch a Patient's documents; We recommend using Webhooks to ensure you're able to get patient data as quickly and easily as possible. *** ## 4. Create Facilities and Patients For the remainder of the steps, you are able to either use the Dashboard UI, or the API - whatever you prefer! Pro-tip: you can use our handy [SDK](/medical-api/api-tools/sdk) on your server if you're using Node: Now you can now create `Facilities` and `Patients`. First, you'll need to create your `Facilities`. In Metriport, a `Facility` is a location that a `Patient` receives some form of treatment. You can create multiple `Facilities` to represent each of your care locations. Note that for telehealth practices, these can be virtual locations. In Sandbox mode, you can use the test NPI `1234567893` when creating Facilities. You can create a `Facility` by either: ### Creating Facilities using the API See the [Create Facility endpoint](/medical-api/api-reference/facility/create-facility) in our API reference. ### Creating Facilities using the Dashboard * On the `Facilities` page, click `Create Facility`. * Fill in the details and submit the form to add your Facility. Once you've created all of your `Facilities`, you can create the `Patients` that you treat in each facility. In Sandbox mode, you can create Patients with pre-defined patient demographics to simulate a match and pull example clinical data - see our [Sandbox guide](/medical-api/getting-started/sandbox#example-clinical-data) for more details. You can create `Patients` by either: ### Creating Patients using the API See the [Create Patient endpoint](/medical-api/api-reference/patient/create-patient) in our API reference. ### Creating Patients using the Dashboard * On the `Patients` page, click `Create Patient`. * Fill in the details and submit the form to add your Patient. When you create a Patient, Metriport automatically links the Patient to all HIE data sources related to the Patient based on the demographic and/or identification information provided when creating the Patient. *** ## 5. Query for Patient Data Now, you're able to query for your Patients' medical data from all available health data networks including HIEs, pharmacies, and laboratories. As we query for data, we automatically convert outside records (like XML C-CDA docs) into `FHIR` resources 🔥, deduplicate the data, standardize it, enrich it with medical code lookups and crosswalks, and store the resulting data on our servers for you to access at any time through a single endpoint. To query for a Patient's available data, you can either: ### Query for Patient Data using the API Start an asynchronous [Network Query](/medical-api/api-reference/network/start-network-query) to initiate a query for the Patient's medical data from all available health data networks. When data from each source is ready, we'll send you webhooks (`network-query.hie`, `network-query.pharmacy`, `network-query.lab`) - see [the webhooks page](/medical-api/handling-data/webhooks-with-nq) for more details. If you don't have webhooks integrated, you can use the [Get Network Query Status](/medical-api/api-reference/network/get-network-query) endpoint to check the status of the query. ### Query for Patient Data using the Dashboard * On the `Patients` page, click on the desired Patient row to be taken to their interactive medical record chart summary page. * If this is the first time viewing this Patient's chart, Metriport will automatically retrieve the Patient's medical data from all available health data networks; * Otherwise, you can click `Refresh Patient Data` anytime to get the latest medical data from external sources. Note: Only \~95% of patients will have data. ## 6. Get Patient Medical Data The aforementioned deduplicated, standardized, and enriched `FHIR` data will allow you to get the source of truth for a Patient's medical data to better understand and treat your Patients. We refer to this as `Consolidated Data` in Metriport. The Consolidated Data Query retrieves the **cached** result of your most recent Network Query. It does not fetch new data from external sources - use Network Query for that. Read our [FHIR guide](/medical-api/fhir/overview) to learn more about how Metriport leverages FHIR. To learn more on how to obtain a Patient's Consolidated data via API, please see the [Start Consolidated Data Query](/medical-api/api-reference/fhir/consolidated-data-query-post) endpoint - note that this same data is also available via the Dashboard. To render this data in a single summary document, refer to the [Medical Record Summary](/medical-api/handling-data/medical-record-summary) guide. If you need to access the raw unprocessed Documents, see the [Start Bulk Get Document URL](/medical-api/api-reference/document/download-url-bulk) endpoint. ## 7. Contribute Medical Data To uphold data quality with Metriport's data sources, and improve patient health outcomes, it's required that your organization reciprocates medical data exchange by making net-new patient clinical data available to the networks. Some examples of this include: * Remote patient monitoring observations such as weight and blood pressure; * Clinical progress notes from patient encounters; * Lab results Metriport makes it easy to contribute this data - you can: * Upload FHIR data using our [Create Patient's Consolidated Data](/medical-api/api-reference/fhir/create-patient-consolidated) endpoint. * Upload binary documents using the [Upload Document](/medical-api/api-reference/document/post-upload-url) endpoint. For more details on how to contribute data back, see the [Data Contribution](/medical-api/handling-data/contribution) guide. *** ## 8. Request API access Access to our Medical API will require you to make requests on behalf of a covered entity with an [NPI number](https://www.cms.gov/Regulations-and-Guidance/Administrative-Simplification/NationalProvIdentStand) for a valid [Treatment](https://www.hhs.gov/hipaa/for-professionals/privacy/guidance/disclosures-treatment-payment-health-care-operations/index.html) purpose of use. To start using the Medical API for production workloads, with real patient data, you can take the following steps to request production API access: * In the left hand menu, click `Products & Billing`. * Click `Get Started` on the Medical API product. * Press `Book an Intro Call` and select a time and a date to talk to us. After the call, we will promptly setup your account. ## Wrapping up That's it! 🤘 You're now well equipped to use the Metriport API to access, manage, and exchange your Patients' medical data. As next steps, we'd recommend scoping out our [Medical API Reference](/medical-api/api-reference/organization/create-organization) in further detail to see the other things you can do with Metriport. # Sandbox Mode Source: https://docs.metriport.com/medical-api/getting-started/sandbox Build your application using example clinical data # Overview Metriport offers a Sandbox environment so you can develop your medical applications more easily. This environment allows you to try out the Medical API with some example de-identified clinical data (see section below for more details). After you get access to the Medical API, you can go to the Developers page and toggle the switch under the Sandbox section to activate Sandbox mode. ## Example Clinical Data The Sandbox environment will give you access to comprehensive example clinical data for several test patients - this data will be representative of what you can expect to see in production: * C-CDA documents in XML format. * FHIR resources in JSON format. * Various de-identified unstructured clinical documents in PDF format. * Various de-identified images in formats like TIFF and JPEG. To access this data, you just need to create Patients that match some pre-defined demographics. In Sandbox mode, any Patient you create with a **first name** that matches one of the pre-defined Patients below will be populated with the corresponding test data. When querying for consolidated data in sandbox mode using a `conversionType`, if you pass a patient that is not one of the pre-defined Patients below, we will always return a pre-defined file. You can expect about 6 example documents per Patient, roughly breaking down to: a C-CDA XML (and the resulting FHIR resources), 3 PDFs, and 2 images. The sections below list the pre-defined sandbox personas and their demographics. Use these as the base for requests to the [create Patient endpoint](/medical-api/api-reference/patient/create-patient). The **first name** (e.g. Jane, Chris, Kyla) determines which persona's data is returned; you can use the full JSON below or your own patient details with a matching first name. ### Jane Smith Jane Smith has a history of depression and other mental health conditions. ```json theme={null} { "firstName": "Jane", "lastName": "Smith", "dob": "1996-02-10", "genderAtBirth": "F", "address": [ { "addressLine1": "123 Arsenal St", "city": "Phoenix", "state": "AZ", "zip": "85300", "country": "USA" } ] } ``` ### Chris Smith Chris Smith has chronic kidney disease (CKD). ```json theme={null} { "firstName": "Chris", "lastName": "Smith", "dob": "1995-01-01", "genderAtBirth": "M", "address": [ { "addressLine1": "123 Atlantis Rd", "city": "Chicago", "state": "IL", "zip": "60601", "country": "USA" } ] } ``` ### Ollie Brown Ollie Brown has generalized anxiety disorder (GAD). ```json theme={null} { "firstName": "Ollie", "lastName": "Brown", "dob": "1946-03-18", "genderAtBirth": "M", "address": [ { "addressLine1": "201 Armada St", "city": "Harrisburg", "state": "PA", "zip": "15300", "country": "USA" } ] } ``` ### Andreas Brown Andreas Brown has type 2 diabetes and kidney disease. ```json theme={null} { "firstName": "Andreas", "lastName": "Brown", "dob": "1952-01-01", "genderAtBirth": "M", "address": [ { "addressLine1": "4430 York St", "city": "Jefferson City", "state": "MO", "zip": "64000", "country": "USA" } ] } ``` ### Kyla Fields Kyla Fields has chronic hypertension and diabetes. ```json theme={null} { "firstName": "Kyla", "lastName": "Fields", "dob": "1927-05-23", "genderAtBirth": "F", "address": [ { "addressLine1": "332 16th St", "city": "Portland", "state": "ME", "zip": "04000", "country": "USA" } ] } ``` ## Webhook Testing In sandbox mode, you can test real-time patient notifications by sending sample payloads through the dashboard. ### Patient Notifications Test your webhook integration with realistic patient notification events: * **Patient Admit**: When a patient is admitted to a healthcare facility. * **Patient Transfer**: When a patient is moved between departments/units. * **Patient Discharge**: When a patient is discharged from a facility. ### How to Test In your Metriport dashboard, go to the webhook settings and use the "Test events" section. Select from Patient Admit, Patient Transfer, or Patient Discharge, then click "Send Payload" to test your webhook integration. Dashboard Webhooks Test events UI showing patient notification types and send button The interface allows you to: * **Select notification type** from the dropdown (Patient Admit, Patient Transfer, or Patient Discharge) * **Preview the sample payload** that will be sent to your webhook * **Send the test payload** with one click to verify your webhook handles patient notifications correctly ## SDK To connect to the sandbox using the SDK just provide the `options` parameter with `sandbox = true`: # Implementing Webhooks Source: https://docs.metriport.com/medical-api/getting-started/webhooks Receive data as soon as it becomes available. ## Overview Usually, when an application wants to consume information from another it makes a request to obtain such information. Webhooks turn this around: the producer of information calls the consumer when data is available. This way, the consumer doesn't have to poll the producer regularly to obtain information. Metriport will call your app's webhook endpoint when user data is available - there's no way for your application to request data exposed through webhooks. To enable this integration approach with Metriport: 1. Expose a public endpoint on your app; 2. Set this endpoint URL on the [Developers page](https://dash.metriport.com/developers) in the developer dashboard, or via the [Update Settings endpoint](/medical-api/api-reference/settings/post-settings); 3. This will generate a webhook key that should be used to authenticate requests on your app's endpoint (webhook) - see [authentication](#authentication) and [generating a new webhook key](#generating-a-new-webhook-key) below. General requirements for the endpoint: 1. Public endpoint accessible from the internet; 2. Does not do an HTTP redirect (redirects will not be followed); 3. Accepts a `POST` HTTP request; 4. Verifies requests using the HTTP header `x-metriport-signature` - see [authentication](#authentication) below; 5. Responds `200` in under 4 seconds - we recommend processing the webhook request asynchronously; 6. Accepts and responds to a [`ping` message](#the-ping-message); 7. Be [idempotent](https://en.wikipedia.org/wiki/Idempotence) - it should accept being called more than once with the same payload, with no changes to the end result. Additionally, your endpoint will need to accept and process different messages when they become available - specifically: 1. [Patient data messages](#medical-api-messages). **Testing Webhooks**: In sandbox mode, you can test your webhook integration with realistic patient notification events (Patient Admit, Transfer, Discharge) using the dashboard testing tool. Learn more in the [Webhook Testing section](/medical-api/getting-started/sandbox#webhook-testing) of our sandbox documentation. ## Authentication When Metriport sends a webhook message, it includes an `x-metriport-signature` header - this is an [HMAC](https://en.wikipedia.org/wiki/HMAC) SHA-256 hash computed using your webhook key and the body of the webhook message. At a high level, an HMAC works by taking a secret key (webhook key from the Settings page) and a message, and performing iterative hashes of the two to create a signature. That signature is compared against the signature in the header for equality. If the signatures are equal, you can trust the webhook payload is authentic and has not been tampered with. If they aren't equal, you should throw it away. You can use this header to verify that the webhook messages sent to your endpoint are from Metriport. Avoid parsing the request body before generating the signature - it could result in a slightly different signature that's enough to invalidate it. Here's an example of how you can do this in Node.js - see the full sample code [here](https://github.com/metriport/metriport/blob/develop/samples/typescript-express/src/mock-webhook.ts): The important thing is to make sure you use a trusted cryptography library in whatever language you choose to validate the webhook message in. You can also validate the HMAC in Python - see the full sample code [here](https://github.com/metriport/metriport/blob/develop/samples/python-fast-api/mock-webhook.py): ```python theme={null} import hmac import hashlib import json def verify_webhook_signature(key: str, body: str, signature: str) -> bool: """ Verify the HMAC signature for a given message and key. :param key: your webhook key (string). :param body: the raw body of the webhook request (string). :param signature: the signature obtained from the webhook request header (string). :return: True if signature is verified, False otherwise. """ key_bytes = key.encode('utf-8') body_bytes = body.encode('utf-8') hmac_obj = hmac.new(key_bytes, body_bytes, hashlib.sha256) computed_signature = hmac_obj.hexdigest() if hmac.compare_digest(computed_signature, signature): print('Signature verified') return True else: print('Signature verification failed') return False ``` ### Generating a new webhook key If using the dashboard: simply delete your webhook URL on the [Developers page](https://dash.metriport.com/developers), save, and enter it again. If using the API: set the webhook URL to an empty string via the [Update Settings endpoint](/medical-api/api-reference/settings/post-settings), and then set it to your desired URL making another request to the same endpoint. ## Format Webhook requests contain the relevant information on the body of the HTTP request. There are several types of messages you can expect to receive: * [`ping`](#the-ping-message): validation of the webhook connection between Metriport and your app; * [Medical API messages](#medical-api-messages). Ensure your app responds with an HTTP `200` status code (OK) whenever it successfully receives one of these messages. There's no need to include anything on the response body. ### The `ping` message This is a simple message to validate access to your app's webhook endpoint. Your app should accept a `POST` request with this body... ```json theme={null} { "ping": "", "meta": { "messageId": "", "requestId": "", "when": "", "type": "ping" } } ``` ...and respond to this request by sending back the `` as below: ```json theme={null} { "pong": "" } ``` You can check the [webhook mock server available on our repository](https://github.com/metriport/metriport/blob/master/samples/typescript-express/src/mock-webhook.ts) for a simple implementation of this message. ### Medical API messages When using the Medical API, Metriport will send Webhook messages containing status updates to your app, as soon as the data becomes available. You can see Webhook details specific to the Medical API, including which operations trigger Webhook messages, on [this page](/medical-api/handling-data/webhooks-with-nq). ### Meta data Webhook updates will contain meta information. Example payload: ```json theme={null} { "meta": { "messageId": "", "requestId": "", "when": "", "type": "medical.medical.consolidated-data" }, ... } ``` The format follows: Metadata about the message. The ID for this message from Metriport, useful for debugging purposes only; The ID of the request that initiated the async flow for this webhook. The timestamp when this message was originally sent, formatted as [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) (example: `2022-12-24T00:46:05.413Z`) The type of the webhook message. This can either be `ping` or one of our standard [Webhook event types](/medical-api/handling-data/webhooks-with-nq#webhook-categories). The additional data you passed to the Metriport API when you called the endpoint related to this Webhook message. This does not exist in webhooks for [realtime patient notifications](/medical-api/handling-data/realtime-patient-notifications). See more details [here](/medical-api/handling-data/webhooks-with-nq#passing-metadata). ## Retries Sometimes, due to temporary network disruption (or whatever other reason), a Webhook payload may fail to be delivered to your app. In these cases, Metriport will store the failed requests, and you can then manually retry them - using either the dashboard, or the API. If you do not have the Webhook URL configured, Metriport will not attempt to deliver Webhook messages for the Medical API - in which case retries are not applicable. ### Retry Using the Dashboard On the [Developers page](https://dash.metriport.com/developers) in the dashboard, you're able to see the count of Webhook requests currently processing, and a count of outstanding ones that failed: To retry failed requests, simply click the `Retry` button, and those requests will be sent to your app again. ### Retry Using the API 1. Using the [Get Webhook Status endpoint](/medical-api/api-reference/settings/get-webhook), check to see if there are any failed requests; 2. Then, use the [Retry Webhook requests endpoint](/medical-api/api-reference/settings/retry-webhook), to kick off the retry. Currently, the Metriport API doesn't implement automatic retries - let us know if this is something you need. # AI Summaries Source: https://docs.metriport.com/medical-api/handling-data/ai-summaries Get a brief summary of the most relevant medical history you need to know about your patient