Destinations

What's a Destination

A Destination is used to define the URL where your webhooks should be sent. Generally, this should be labeled after the service or a specific method on your service. For example, "Order Service", "Internal API" or "Update Order".

Each Destination has a webhook URL which is the endpoint Hookdeck will be sending HTTP POST requests. The original request headers and the data are preserved. Additionally, Hookdeck will also append metadata to the request.

HTTP vs CLI destinations

Destinations mode can be toggled between HTTP and CLI ONLY. A CLI ONLY destination will not send any webhook events to an HTTP URL and will instead only be available to connected CLI clients when the webhook is received.

A CLI ONLY destination does not have a URL endpoint and instead allows for a CLI path value used to configure to which path the request will be forwarded to on your local server. Additionally, Throttled Delivery is not available for CLI ONLY destinations.

An HTTP destination requires an HTTP URL for webhooks to be forwarded to. However, an HTTP destination can still be connected to by the CLI, and the CLI Path will be automatically parsed from your HTTP URL. You can disabled access from the CLI by unchecking the "Allow CLI connections" checkbox.

Additionally, any events forwarded to the CLI will not apply to your connection ruleset. This prevents unwanted automatic retry once the CLI is closed and silences any alert.

Throttled delivery using a rate limit

Each destination can be configured to deliver at a specific rate. You can enable and configure the destination rate limit to make sure you do not receive more requests than the configured value. This is especially useful to deal with large increases in the volume of webhooks. There are multiple reasons you could reason many more webhooks than you expect:

  • You perform a bulk update operation in the platform sending the webhook, like bulk updating all your products in Shopify;
  • The webhook provider has an outage and accumulated a backlog of webhooks there will try to deliver at once;
  • You have a sudden burst in usage because of a new customer, a time of the year (Black Friday), etc.

In general, to protect your infrastructure we recommend setting a sensible ceiling for the rate limit. Hookdeck will queue the attempts and deliver them as fast as possible while respecting your configuration.

Setting the rate limit

We allow you to configure the rate limit either by minute or second with a maximum value of 100 req/s or 6000 req/min. You can set the value by creating or editing a destination. Contact us if you need those maximum values to be increased.

Updating the rate limit

The destination rate limit value can be updated at any time and will take anywhere between 1 second and 1 minute to propagate depending on the originally configured value.

Receiving webhook events

To receive your webhook events you will need an HTTP server listing on a given endpoint for HTTP POST request accepting Content-Type: application/json

A simple NodeJS implementation using ExpressJS would be

const express = require('express');
const app = express();
const port = 5050;

// If you expect webhook data as JSON
app.use(express.json());
// If you expect webhooks as plain text
app.use(express.text());
// If you expect webhooks as application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));

const processRoute = (req, res) => {
  console.log('query', req.query); // {test: 1} if a query string ?test=1 is set
  console.log('path', req.path);   // /webhooks/path/to/forward if request URL is https://events.hookdeck.com/e/src_xxxxxxxxxxxxxxxxxxxxxxxx/path/to/forward
  console.log('body', req.body);   // {key: "value"} if raw json body is {"key": "value"}

  res.send('Server received a webhook!');
}

app.post('/webhooks/*', processRoute);
app.post('/webhooks', processRoute);

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

Request headers

Hookdeck preserves the original HTTP headers.

However, we remove "noisy" headers created by our own infrastructure as well as append the following headers:

X-Hookdeck-EventID:        Hookdeck event id
X-Hookdeck-Attempt-Count:  Event attempt count
X-Hookdeck-Event-URL:      URL to the Hookdeck Dashboard for that event
X-Hookdeck-Signature:      Hookdeck HMAC signature (sha256, base64 encoed)

Resquest body

Hookdeck preserves the original HTTP request body. However, since Javascript doesn't have support for 64-bit integers, very large numbers (58 bits +) will be converted to a string to preserve their original values.

Query string

Hookdeck preserves and forwards the original query string, unless you specify a query string in your destination's URL. In other words, if the request that you send to Hookdeck includes a query string

?key1=value1

And the URL that you set as your destination is:

https://www.myendpoint.com/webhooks?somekey=somevalue

the query string that your destination will receive is

?somekey=somevalue

Path

Hookdeck preserves and forwards the path by default. You can choose to disable path forwarding (see below, Create a Destination). We will append the path that you specify after the source url to the URL configured as a destination.

For example, if your source URL is

https://events.hookdeck.com/e/src_xxxxxxxxxxxxxxxxxxxxxxxx/path/to/forward

and your destination URL is

https://www.myendpoint.com/webhooks

you will receive the request on the URL

https://www.myendpoint.com/webhooks/path/to/forward.

Note that it is possible to combine query strings and path.

Responding to the event

When using Hookdeck, it's recommended to respond to a webhook event request with a status code that reflects the actual state of your system. When an operation is processed, you should respond with a 2XX response code (200, 201) for successes or a 4XX - 5XX for errors. We recommend you return the most relevant status code to help you with troubleshooting.

Contrary to what you might have been doing in the past, when using Hookdeck you should not simply return an HTTP 200 (success) right away and queue the event. You should take action immediately and report the result back to Hookdeck. This is what enables Hookdeck to know what events to retry as well as providing you with the tools to recover from errors.

Another common practice is to abstract errors into a generic 500 fatal error. While this is done to not leak stack traces or other important information, when using Hookdeck over HTTPS (SSL) the more specific the error you return, the more helpful Hookdeck will be to solve your errors.

Using our previous NodeJS example

app.post('/webhooks', (req, res) => {
  try {
    const result = doSomething(req.body);
    // Webhook handled successfully, let Hookdeck know.
    res.status(200).json(result);
  } catch (e) {
    // Oh no something went wrong, provide Hookdeck with the error.
    res.status(500).json(e);
  }
});

Timeouts

When Hookdeck delivers an event to your destination, it will wait for up to 30 seconds for a response before timing out. Attempts that timeout will be shown as ERR in the dashboard with the status code TIMEOUT. They are considered as failed and eligible for retry.

If you run into problems with the 30 seconds timeout, please reach out to us, we can increase it!

Create a Destinaton

To create a Destination follow these two steps.

  • In the upper right corner of the dahsboard, choose Destination, then click Create Create a destination menu

  • Fill in the details in the Create Destination form Create a destination

Edit a Destination

You can edit a Destination by selecting the edit button from the destination card options menu:

Edit a destination

Archive a Destination

You have the option to archive a Destination you do not use anymore.

Hookdeck_Archive_A_Destination

You can unarchive a Destination if you decide to want to use it again.

Hookdeck_Unarchive_A_Destination