Webhooks

Webhooks are a way to get notified about updates and events when they happen. You can use webhooks to integrate Anzu with other services, or to build your own integrations.

Creating a webhook

  • In the sidebar, go to Webhooks, then click Create in the top right corner
  • Enter a name, and select the events you want to receive
  • Fill out the endpoint URL. This must be a valid HTTPS endpoint.

Events

Webhooks inform you about events that occur in your environment, such as user signups, authentication attempts, and more. You can select the events you want to receive when creating a webhook.

Webhook Deliveries

Every time an event occurs, the system determines relevant webhooks to be notified, and creates a webhook delivery. This delivery is set to pending initially and gets updated when the request to the endpoint is made.

Webhook deliveries are stored for 30 days, and can be viewed on the Webhook details page in your environment.

In case a webhook delivery fails, you can retry it by clicking Retry in the delivery logs. After multiple subsequent failures, the webhook will be disabled, and you will have to enable it again.

Webhook Payload

The body of a webhook request has the following shape

{
  "webhookId": "2EFrzyyl6g0WnF5PxEhs3MwKu5t",
  "createdAt": "2022-09-03T10:53:59.673Z",
  "id": "2EFs01hFaPjPpEbiBaQr3Y7VnQs",
  "version": "2022.8",
  "kind": "ping",
  "scope": {
    "projectId": "2Di3esGvc8wqtLrZqG62PXRv2nC",
    "teamId": "23JxVZ7JwRDIhSmJixh6DjvbRxn",
    "environmentId": "2Di3hnldgONMkCwbPXbIMkUeeNp"
  },
  "payload": {}
}
json

As you can see, we include a version tag in the payload. This is to make sure you can handle breaking changes in the future.

In addition, we include a kind field, which is the event that triggered the webhook. This is useful to handle different events in the same endpoint.

Idempotency

Anzu does not guarantee webhook requests to be in order or to be delivered exactly once. For this reason, we include timestamps and an idempotency key for every request. The Idempotency-Key header, which contains the event ID, should be used to make sure you don't process the same event twice in case of a failure or retry.

Validating Webhooks

Anzu signs all webhook requests with a secret key. You can find this secret in the webhook details page. To validate a webhook request, you can use the following code snippet:

const { createHmac } = require('crypto')

/**
 * Validates signature with request body and secret
 *
 * Uses timestamp and sig from signature value
 *
 * @param signature full signature header including ts, alg, and sig
 * @param requestBody
 * @param secret
 */
export function validateSignature(signature: string, requestBody: string, secret: string) {
  const params = new URLSearchParams(signature);

  const ts = params.get('ts');
  const alg = params.get('alg');
  const sig = params.get('sig');

  if (!ts || !alg || !sig) {
    throw new Error('Invalid signature');
  }

  const expectedSig = getHmac(secret, ts, requestBody);

  if (sig !== expectedSig) {
    throw new Error('Invalid signature');
  }
}

function getHmac(secret: string, ts: string, requestBody: string) {
  const hmac = createHmac('sha256', secret);

  const signedPayload = `${ts}.${requestBody}`;
  hmac.update(signedPayload);

  return hmac.digest('hex');
}
typescript

Limits

Currently, responses to webhook requests may not be larger than 8KB, and requests must complete within 5 seconds.