Home / Events and Notifications

Notifications

Overview

Notification schemas can change over time. When new attributes are added, Highnote will notify you seven days prior to release. When a breaking change occurs, Highnote will notify you 90 days prior to release to ensure ample time for any necessary updates.

To maintain uninterrupted service, we recommend building robust and resilient integrations that can adapt to these changes.

The Highnote platform provides Notification Events that allow you to have strongly-typed events pushed to your system. This means you can react to events in your Highnote integration to do things like complete asynchronous onboarding flows, monitor for changes or alerts, or shuttle data into third-party systems such as a CRM or analytics dashboard.

Highnote provides several ways for you to handle events. You can query, forward, and replay events via the GraphQL API and/or configure webhooks.

Webhooks

Webhooks can be managed via the GraphQL API or dashboard. You can have multiple webhooks (up to 50) and can configure specific events to be delivered to each one.

Notification events are sent as POST requests with JSON bodies. Highnote will send the following headers on each request:

  • user-agentHighnotePlatform/1.0.0
  • highnote-signature – The result of computing an HMAC 256 signature of the request body.
  • highnote-replay – This will be sent in cases where the event is being manually re-delivered
  • content-typeapplication/json

Setup a Webhook

You can add webhooks using the addWebhookNotificationTarget mutation. The requirements for an HTTP webhook are:

  • The endpoint must be served via https
  • Must return a 2XX status code. All other status codes will be considered a delivery failure and the request will be retried.

When the webhook is created, the status will be PENDING_VERIFICATION. Highnote will deliver a test event (NOTIFICATION_ACTIVATION) and upon receiving a 2XX response the status will transition to ACTIVE. If the webhook does not return a 2XX response, the status will remain PENDING_VERIFICATION and you can attempt to activate the webhook using the activateNotificationTarget mutation.

For testing, if you do not have a server, you can use webhook.site, requestbin, or pipedream. Do not use these services for your production webhooks.

Retries and Failures

Upon a failed delivery, Highnote will retry three times at incremental intervals, waiting 10 seconds between each Notification retry attempt. After three failed attempts, the webhook target will be disabled. You will need to manually re-activate it through the API or dashboard.

If your webhook endpoint is down or if you miss any events, you can retrieve them via the GraphQL API.

Verifying Payloads

You can ensure events pushed to your webhook are coming from Highnote by inspecting the signature header or metadata.

Signature header

The signature of the payload will be in the highnote-signature HTTP header. The header contains a comma-separated list of signatures. Usually, the list will only contain one item unless you are rolling your signing key.

To verify the signature with the payload you received, start by signing the payload you receive using your language-specific HMAC signing library and the signing key secret for your notification target. The payload Highnote sends you includes a timestamp so there is no need to concatenate any additional information.

Once you have a local signature, you can extract the value of the highnote-signature and compare the two using a timing safe equals operation.

For example, in node.js:

import { timingSafeEqual, createHmac } from "crypto";

function verifySignature(
  secret: string,
  payload: string,
  remoteSignature: string
): boolean {
  const localSignature = createHmac("sha256", secret)
    .update(payload)
    .digest("hex");

  return timingSafeEqual(
    Buffer.from(remoteSignature),
    Buffer.from(localSignature)
  );
}

If there is equality between the signatures, you can verify the timestamp of the event is within a certain threshold. The signature timestamp can be found in the payload at $.extensions.signatureTimestamp with the value being the number of milliseconds since Unix epoch.

function within15minutes(payload: string): boolean {
  const jsonPayload = JSON.parse(payload);
  const { signatureTimestamp } = jsonPayload.extensions;
  return (Date.now() - signatureTimestamp) <= 15 * 60 * 1000;
}

Viewing Delivery Attempts

When querying Notification Events, you can also see the delivery attempts for that event. If no target was enabled for this event type, the value will be null.

Replaying Events

You can replay events – or manually re-deliver events to your webhook(s) using the GraphQL API. This is useful in cases where your target may have been down or if you have automated workflows that require a delivery to trigger action.

You can use the replayNotificationEvent mutation to deliver events that were created before a webhook was assigned.

Renaming a Target

You can update the name of a Notification Target without affecting the delivery of Events.

Deleting a Target

Notification Targets may be deleted. Deleting a Target will stop delivery of all Events as the Notification Target will no longer exist. This may impact the functionality of your Highnote integration and cannot be reversed.

Expiration of Deactivated Targets

Once a Target is deactivated, any attempts to send notifications to the Target will return an error status.

When a webhook has a DEACTIVATED status for more than 30 days, it is considered to be expired. Such webhooks will be deleted and will no longer be visible.

Provide Feedback

Was this content helpful?