🚧

Beta

This API is in a stage of development that may be subject to change or deprecation and may not yet be feature complete or perform consistently. ZusHooks can be configured on your behalf when you submit a support ticket to us here.

As a value- and/or risk-based care delivery provider, you strive to manage a patient’s continuum of care, within and outside of your organization. This involves timely interventions to events of interest, such as:

  • When a patient is admitted, discharged, or transferred (ADT) from an inpatient encounter
  • When the patient is prescribed a medication or picks up a medication
  • When a patient has a new lab result

Rather than requiring you to make API calls against the Zus FHIR Store to discover whether a data-generating event occurred, Zus can securely send a message to your URL.

What is a webhook?

A webhook is a user-defined HTTPS callback. When you build your application using Zus APIs, you may want to receive inbound HTTPS requests from Zus. These request payloads contain information about data creation and update activity in the Zus FHIR Store - for instance, when a patient picks up a prescription for a new medication.

To react to data and develop your own trigger-action workflow automations, you will need to tell Zus what URL to securely send these requests to and acknowledge that the request was received by your application with a standard HTTP 200 OK response.

πŸ‘

If you would like to configure a ZusHook for your account, please submit a support ticket to us here.

Getting Started with ZusHooks

To set up a ZusHook, you specify the filter and the authentication.

A filter must contain:

  • Resource type. All FHIR resource types are supported.

Optionally, a filter can include a targeted field value. For example, you may want to only receive requests for completed QuestionnaireResponses. Therefore, a filter can contain:

  • Field. At this time, only first-level elements for FHIR resources are supported. First-level elements are scalars in the root of the resource. For the QuestionnaireResponse resource type, status and authored are first-level elements.
  • Field comparator. The following field comparators are supported:
    • EQUALS
    • DOES NOT EQUAL
    • CONTAINS
    • DOES NOT CONTAIN
  • Field target value.

An authentication must contain:

  • Authentication type. Basic (username/password) and OAuth client credentials are supported.
  • URL of your webhook.

πŸ“˜

Zus sends the full FHIR resource as part of the message for FHIR resources smaller than 1 MB.

For resources larger than 1MB, Builders can query the Zus FHIR store with the delivered resourceID.

The message payload also includes:

  • Message ID. There is no guarantee that a message will only be sent once.
  • Source. Supported sources are "com.zushealth.ods-fhir-subscriptions"
  • Time of message creation.
  • Resource ID.
  • Owner ID of the resource.
  • resourceIncluded. This will be set to false if the resource size is greater than 1 MB.

Testing ZusHooks on your local development environment

ZusHooks require a publicly accessible URL. To approach this, you can deploy your application to a development or test server that is reachable from the public internet or use an HTTP tunneling tool like ngrok to set up a public URL for your application that maps to an application server running locally on your computer.

For convenience to quickly demonstrate proof of life, we will test with no authentication using webhook.site, which instantly provides a unique, random URL that allows us to receive webhooks without needing an internet-facing web server.

❗️

This test should only be conducted on synthetic data.

We will create a ZusHook for your sandbox Builder to receive completed QuestionnaireResponses.

Zus configures your filter and URL

First, go to webhook.site, and copy the unique URL. Zus will put that URL into the auth in the request payload below.

PUT https://api.sandbox.zusapi.com/subscriptions

{
   "filter": {
       "builderId": "{{builderID}}",
       "filterName": "sandbox-test-completed-qr-webhook.site",
       "resource": "QuestionnaireResponse",
       "field": "status",
       "fieldComparator": "EQUALS",
       "fieldTarget": "completed",
   },
   "auth": "{\"authType\":\"none\",\"webhookUrl\":\"{{uniqueURL}}\"}"
}

should respond with a standard HTTP 200 OK response.

Zus confirms your configuration

Zus will now confirm that the configuration was successful.

GET https://api.sandbox.zusapi.com/subscriptions

{
    "builderId": "{{builderID}}",
    "filterName": "sandbox-test-completed-qr-webhook.site"
}

should respond with

[
  {
    "builderId":"{{builderID}}",
    "filterName":"sandbox-test-completed-qr-webhook.site",
    "resource":"QuestionnaireResponse",
    "field":"status",
    "fieldComparator":"EQUALS",
    "fieldTarget":"completed",
    "webhookSecret":"{{secretName}}"
  }
]

Validate that webhook requests are coming from Zus

To send a request to the configured URL, you will need to create or update data that fits the filter criteria.

POST htttps://api.sandbox.zusapi.com/fhir/QuestionnaireResponse

{
   "resourceType": "QuestionnaireResponse",
   "status": "completed",
   "authored": "2022-05-02T15:31:24-04:00",
   "item": [
       {
           "linkId": "timeTest",
           "answer": [
               {
                   "valueString": "test at {{$timestamp}}"
               }
           ]
       }
   ]
}

That newly created QuestionnaireResponse resource should now show up on the webhook.site page within a few seconds.

{
  "message_id": "6e0e0db7-32ae-4558-9af6-91da6b2a9234",
  "source": "com.zushealth.ods-fhir-subscriptions",
  "time": "2022-12-20T19:41:24Z",
  "resourceId": "QuestionnaireResponse/eeb8fcac-7dc6-48b8-aa40-38ca8719554f",
  "ownerId": "builder/{{builderID}}",
  "resourceIncluded": true,
  "resource": {
    "authored": "2022-05-02T15:31:24-04:00",
    "id": "eeb8fcac-7dc6-48b8-aa40-38ca8719554f",
    "item": [
      {
        "answer": [
          {
            "valueString": "test at 1671565285"
          }
        ],
        "linkId": "testTime"
      }
    ],
    "meta": {
      "extension": [
        {
          "url": "https://zusapi.com/created-at",
          "valueInstant": "2022-12-20T19:41:24.651+00:00"
        }
      ],
      "lastUpdated": "2022-12-20T19:41:24.654+00:00",
      "tag": [
        {
          "code": "builder/{{builderID}}",
          "display": "{{builderName}}",
          "system": "https://zusapi.com/accesscontrol/owner"
        }
      ],
      "versionId": "1"
    },
    "resourceType": "QuestionnaireResponse",
    "status": "completed"
  }
}

If you have not yet seen the resource after a minute, you should refresh the webhook.site page.

Zus deletes your configuration

Zus will clean up the proof of life test.

DELETE https://api.sandbox.zusapi.com/subscriptions

{
   "builderId": "{{builderID}}",
   "filterName": "sandbox-test-completed-qr-webhook.site",
}