Webhooks

See main page about choosing event integration and to learn about general concepts: https://himsanoah.atlassian.net/wiki/spaces/AD/pages/3574104065

Set up of webhook

1: Create a webhook endpoint

To receive events your app must provide an endpoint that meet following requirements:

  • The endpoint must use HTTPS and, therefore, a valid SSL/TLS certificate.

  • The endpoint can receive a HTTP POST request containing data in response to the event in Noah. Read the 'Receiving Events' chapter for further details.

  • The endpoint must process the HTTP POST request in a timely manner and respond within 5 seconds. You should always do your work asynchronously using a queue to prevent timeouts and retransmission of the event.

  • The endpoint must be able to respond to a verification request that is made when setting up the event subscription. This verification is an HTTP GET request with a query parameter called “challenge”.
    Example: https://www.example.com/noahevents?challenge=[OurChallenge]
    Your app needs to respond by echoing back that challenge parameter. In order to avoid introducing a reflected XSS vulnerability, set the following headers in your response to the verification request:

    'Content-Type: text/plain' 'X-Content-Type-Options: nosniff'

    The purpose of this verification request is to demonstrate that your app really does want to receive notifications at that URI. If you accidentally entered the wrong URI (or if someone maliciously entered your server as their webhook), your app would fail to respond correctly to the challenge request, and Noah would not send any notifications to that URI.
    If your application endpoint responds correctly to the challenge request, Noah will start sending notifications to your webhook URI every time data is added, changed or removed.
    If your app fails to respond correctly, you'll see an error message telling you about the problem.

Important!:
The URI for your webhook endpoint needs to be publicly accessible over the internet. For example, 127.0.0.1 and localhost URIs will not work, since Noah will not be able to contact your local computer.

Important!:
We do not follow HTTP redirects.

If you need to expose a 127.0.0.1 or localhost URI so it is publicly accessible for development and test, tools like https://ngrok.com can be used. (HIMSA does not endorse the tool, this is just a development tip).

2: Create an event subscription

To set up a new webhook the app itself will need to call the Noah ES API to create an event subscription. To create a webhook event subscription you need to specify the following in the request:

  • eventNotificationEndpointUrl Add the full URI for your webhook (e.g. https://www.example.com/noahevents)

  • eventNotificationSecret A shared secret used to compute a HMAC-SHA256 signature of the request body. The secret can’t be retrieved from the Noah ES API, so it’s up to the app to manage and store the secret so it can be used to verify the authenticity and integrity of the data.

  • eventSubscriptions For each event type specify if it should be sent via webhook by setting eventApi to true for the event type.

Example request:

{ "name": "Subscription name", "eventNotificationEndpointUrl": "https://myservice.com/noahevents", "eventNotificationSecret": "mysharedsecret", "eventSubscriptions": [ { "type": "ActionCreated", "eventApi": true, "rtmApi": false }, { "type": "ActionUpdated", "eventApi": true, "rtmApi": false } ] }

Once you make a HTTP POST/PUT request for an event subscription, an initial "verification request" will be made to the specified eventNotificationEndpointUrl that the endpoint must successfully respond to.

Receiving Events

Your webhook endpoint will receive a request for each event matching your subscriptions. One request, one event.

Message Body

When an event in your subscription occurs, we'll send an HTTP POST request to your web hook URL. The event will be in the Content-Type: application/json format:

{ "TenantId": "5b04ef2e-5885-4d95-a1e3-852a2ba9cef1", "NotificationEventId": "be72d402-d99e-49f2-a49c-c468025bb69f", "CorrelationId": "762fe18a-488f-4c43-9813-0c549aace3f6", "NotificationEventSubscriptionId": "e6b6ecfd-e170-4bec-8657-2d9f20661af7", "TransmissionDate": "2024-02-15T08:33:45.5642258Z", "EventType": "PatientCreated", "Event": { "ResourceId": "be92eeb4-5e3f-4a79-a13d-3658db31e1f1", "EventDate": "2024-02-15T08:33:45.5599285Z", "References": [ { "Rel": "selfLegacyId", "ResourceId": "1", "Href": null }, { "Rel": "self", "ResourceId": "be92eeb4-5e3f-4a79-a13d-3658db31e1f1", "Href": "https://localhost:52599/5b04ef2e-5885-4d95-a1e3-852a2ba9cef1/api/Patients/be92eeb4-5e3f-4a79-a13d-3658db31e1f1" } ] } }

Note that the payload of the notification request does not include the actual data e.g. the updated patient data, It only informs your application of which patient have changes. You will then want to call the referenced resource to get the actual updated data.

Message Headers

Every notification request will include the following headers:

  • X-Hub-Signature: An HMAC-SHA256 signature of the request body that is base64 encoded, using the shared secret specified when setting up the event subscription.
    This lets your application verify that the notification really came from Noah. We highly recommend that you check the validity of the signature before processing the notification.

  • X-Hub-Origin: The origin header contains a the origin of the event message - it will be “https://api.*.noah-es.com“. It can be used by the receiver to check if the event is from an origin that is accepted or for internal routing in the receiver.

  • X-Hub-TransmissionAttempt: The TransmissionAttempt header contains the number of times the sender has tied to send the specific notification, so if it is the first time the notification is transmitted the TransmissionAttempt header value will be “1”. If the two first requests failed the “TransmissionAttempt” value will be “3” for the third transmission.

  • X-Message-ID: Unique ID for the webhook payload (same as NotificationEventId in the event message). Use this ID to avoid processing a web hook event multiple times.

Error handling

When Noah ES sends notification requests to your request URL, we ask that you return a HTTP 200 OK for each event you successfully receive.

Failure conditions

We consider any of these scenarios a single failure condition:

  • we are unable to negotiate or validate your server's TLS certificate

  • we wait longer than 5 seconds to receive a valid response from your server

  • we encounter HTTP redirects to follow

  • we receive any other response than a HTTP 200-series response

  • we just couldn't seem to connect to your server. Maybe we couldn't find it in DNS or maybe your host is unreachable.

Retry policy

To deal with transient network errors every notification request will be retried 3 times with exponential backoff starting with a delay of 2 sec.

If event message can't be delivered then delivery of event message will be retried 9 times with exponential backoff starting with a delay of 2 min.

If event message can't be delivered after 9 retries (after 17 hours) then a mail notification will be sent to the email address used in the app registration and delivery of event message will be retried every 12 hours.

If the event subscription is updated then the retry wait time is short circuited and delivery of event message is retried immediately.

Retention period

Event messages will be kept for 7 days. If the event messages can't be delivered within that period then event messages will start to be lost.

Best practices

  • Tolerate minor changes in event type structures. Expect additional fields you haven't encountered before and fields that are only conditionally present.

  • De-couple your ingestion of events from processing and reacting to them. Especially when working with large workspaces, many workspaces, or subscribing to a large number of events. Quickly respond to events with HTTP 200 and add them to a queue before doing amazing things with them.