KnockDocs

Outbound Webhooks

Use outbound webhooks to be notified of events happening within your Knock environment, and respond to those events in realtime in your product.

An overview of webhooks

Knock can send a JSON payload to your backend with data about events that occur within Knock, like a message's status changing from sent to delivered. You can configure an endpoint and select which events you'd like it to listen to. When that event happens you'll get a POST request to the endpoint you've provided and then can use that data to trigger side-effects in your app.

Quickstart

  1. Create an endpoint in your app to receive webhook requests and respond to requests with a 200 or 204 status code
  2. Create a webhook in the Knock dashboard pointing to your endpoint
  3. Start receiving webhook events!

Events that can trigger a Knock webhook

Currently, we support webhooks for status changes on messages. A message represents a notification sent from a workflow, so keep in mind that one workflow with several channel steps can result in many messages and therefore a high number of status changes, or message events.

This is the list of events that Knock can use to trigger a webhook:

EventDescription
message.sentoccurs when a message is successfully sent to a chanel provider.
message.deliveredoccurs when a message is marked as delivered to the user by the provider. This is only available on email providers with delivery tracking enabled.
message.undeliveredoccurs when a message failed to be delivered.
message.seenoccurs when a message is seen by its recipient.
message.unseenoccurs when a message is marked unseen by the recipient.
message.readoccurs when a message is marked as read by its recipient.
message.unreadoccurs when a message is marked unread by the recipient.
message.archivedoccurs when a message is archived by its recipient.
message.unarchivedoccurs when a message is unarchived by its recipient.

Webhook payload & header

A webhook payload for the message events will always include the message sent and the type of event that triggered the payload. This is an example of what will be sent to your webhook endpoint:

You'll notice if you've explored the get messages endpoint that the "data" key contains all of the same fields as a message retrieved from there.

The request header will also contain the following:

  • x-knock-event: the field and the value found in the "type" key of the payload
  • x-knock-environment-id: the environment the webhook belongs to
  • x-knock-signature: the encoded result of a timestamp, payload, and shared secret key so you can verify that the contents of the webhook are from Knock and not a result of a Man in the middle attack. Learn more about verifying signatures below.
🌠
Webhooks are single-environment. When you create a webhook, it will be for the environment you're currently in. If you'd like to add that webhook to another environment, you'll have to create it again there. What this means is that when you create a webhook in a development environment, it will only be triggered by notifications from workflows in development.

How to create a webhook

1. Create an endpoint to receive the webhook payload

In your app, create an endpoint specifically to receive incoming requests from a webhook you'll set up in Knock. This must be an HTTP or HTTPS endpoint on your server with a URL. This is where Knock will send a request with data about events you'll select in the next step. Keep in mind that you can use one webhook endpoint per event type, or you can send multiple types of events to the same endpoint.

Retries

Knock webhooks have built-in retries for 3xx, 4xx, and 5xx responses from your endpoint. Make sure to send a 2xx (i.e. 200) response from your endpoint once you've received the webhook request before operating on the data to avoid a timeout, which will result in the webhook being retried. It will attempt to send the webhook 8 times before it discards the message. You can track the webhooks sent in the webhook delivery logs, as detailed in the managing webhooks section below.

2. Create the Knock webhook

You can create a new webhook by navigating to Webhooks in the Knock dashboard. You can find this in the sidebar under Developers.

When you click "Create webhook" you'll be prompted to add the endpoint from the previous step, an optional description, and then select the events you want to be notified of from the list.

Once you create the webhook, it will be activated and you will begin receiving requests to your endpoint. To stop receiving requests, you can delete the webhook.

Recieving a webhook payload

Verifying the signature

We recommend that upon receiving the webhook request you verify the signature before using the contents of the payload. We follow the Stripe specification to add a layer of security to our webhook requests.

The signature is generated with a HMAC using the SHA256 algorithm and, prior to being encoded, is comprised of the timestamp and the stringified JSON payload of the request. We encode "timestamp in numerical form"."stringified payload" as the signature of the request.

The x-knock-signature header is a string comprised of the timestamp used in the encoding and the encoded value above. It will look like this: t=timestamp,s=encoded-signature

To test that the payload sent has not been compromised, you can recreate the signature using the shared secret key found on the Webhook page and compare to the one sent in the header.

  1. Split the x-knock-signature on the comma (",") and extract the values of timestamp and signature.

  2. Construct the value of the signature by concatenating:

    • The timestamp (as a string)
    • The character .
    • The stringified JSON payload
  3. Generate the signature with an HMAC and SHA256 algorithm using the secret key from your webhook's dashboard

  4. Compare your generated signature with the one extracted in step one; they should match exactly. If the timestamp is more than five minutes old compared to the current time, you may decide you want to reject the payload for additional security.

Here's an example to follow:

Using the data

Once you receive a webhook request and return a 2xx status code, you can make additional requests to the Knock API to gather more information about the message event. For example, if you'd like to log the message's content when an event type comes through as message.undelivered, you can use the message ID to send a request to get message content when that condition is met.

Managing webhooks

Reading webhook delivery logs

When you visit a webhook's page, if it has begun to send data to your endpoint you'll see a log for every POST request. This will give you the following information:

  • Status code: your server's response to the webhook request
  • Event type: the type of event it was reporting on
  • Timestamp: when the event was sent to your endpoint

You'll see details about each log as well. When you select a log, you'll be able to see the full request payload sent to your endpoint.

You'll also see if your endpoint has stopped working as it will display a 4xx or 5xx status code for undelivered webhooks.

Disabling a webhook

When you create a webhook it will automatically be set to enabled. You can disable it by going to the webhook's page, and toggling the status to disabled. This means that it will not trigger any webhook requests when an event it is configured to listen to is fired. When you're ready to start receiving requests again, toggle the status back to enabled.

Deleting a webhook

To stop receiving data to your endpoint, you can delete the webhook from its page. From /webhooks, click on the webhook you'd like to delete and you'll see a three-dot menu to the right of the header. Click there and you'll see the delete prompt. Keep in mind that if you delete a webhook, you'll have to recreate it to start receiving data to that endpoint again.

Try it out

Before implementing an endpoint in your app, you can get a sense of how it works by creating a Knock webhook that points to an example endpoint, such as those provided by https://webhook.site/.