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.

Be as descriptive as possible; it will help you keep track of your webhook events!

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.

Read our CLI and HTTP View tutorial

The destination mode can be toggled at any time. CLI ONLY is particularly useful when working on new endpoints that haven't yet been deployed.

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 scenarios you could receive more webhooks than expected:

  • 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 has accumulated a backlog of webhooks that they will try to deliver at once;
  • You have a sudden burst in usage because of a new customer, or during a specific period of the year (Black Friday), etc.

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.

destination rate limit

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.

TIP: You can update the rate limit value using the Admin API. That allows you to edit the value based on your current infrastructure capacity dynamically.

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
// If you expect webhooks as plain 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
  console.log('body', req.body); // {key: "value"} if raw json body is {"key": "value"}

  res.send('Server received a webhook!');
};'/webhooks/*', processRoute);'/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-Source-Alias:   Alias of the source that received the webhook
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 encoded)
X-Hookdeck-Verified:       Boolean representing if Hookdeck verified the original request

Request body

Hookdeck preserves the original HTTP request body.

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


And the URL that you set as your destination is:

the query string that your destination will receive is



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 you specify after the Source URL to the URL configured as a Destination.

For example, if your Source URL is

and your Destination URL is

you will receive the request on the URL

It is possible to combine query strings and path.

Responding to the event

When using Hookdeck, it is 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'/webhooks', (req, res) => {
  try {
    const result = doSomething(req.body);
    // Webhook handled successfully, let Hookdeck know.
  } catch (e) {
    // Oh no something went wrong, provide Hookdeck with the error.


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 error 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.

Click Create on the top of the page or + connection under Source.

Create a destination menu

Select New and 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

After editing a Destination URL, all the pending and new webhook events will now be sent to that URL.

Archive a Destination

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

You can only archive Destination that is not linked with any webhook connections.


Unarchive a Destination

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