> ## Documentation Index
> Fetch the complete documentation index at: https://onset.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

Onset provides webhooks which allow you to receive HTTP push notifications whenever data is created, updated or removed. This allows you to build integrations that respond to changes in real time, such as triggering CI builds, updating external systems, or sending messages based on release activity.

## Payload

The webhook HTTP payload will include information both in its HTTP headers and its request body.

### Header

**Onset-Signaturex** `string`

HMAC signature of the webhook payload.

**Onset-Event** `string`

Event which triggered this webhook request.

**Onset-Workspace** `string`

Onset workspace Id.

### Body

**event** `string`

Event which triggered this webhook request.

**actor** `string`

The actor who triggered the action. Could be a User, Visitor, or API.

**workspaceId** `string`

Workspace ID

**webhookId** `string`

Webhook ID

**webhookTimestamp** `string`

UNIX timestamp when the webhook was sent.

**data** `string`

Payload of the entity

## Securing Webhooks

You should ensure that webhooks you received were sent by Onset. You can do this by verifying the webhook request signature and timestamp.

Onset sends a `Onset-Signature` HTTP header with every webhook request. This header contains a hex-encoded HMAC-SHA256 signature of the raw body contents, signed using the webhook's signing secret. You can find the signing secret on the webhook's detail page.

The parsed JSON body has a `webhookTimestamp` field with a UNIX timestamp, in milliseconds, indicating the time when the webhook was sent. We recommend that you verify it's within a minute of the time your system sees it to guard against replay attacks.

To verify the webhook, you need to compute the signature of the request body using the webhook's signing secret and compare it against the `Onset-Signature` header. It's strongly recommended to use raw request body rather than restringifying a parsed JSON body, otherwise the signature may differ. Once the signature has been validated, check to ensure that the webhook timestamp is reasonably current before processing the request:

```javascript theme={null}
// Express example:
const crypto = require('node:crypto');
const express = require('express');

const ONSET_WEBHOOK_SECRET = process.env.ONSET_WEBHOOK_SECRET;

function verifySignature(headerSignatureString, rawBody) {
  if (typeof headerSignatureString !== 'string') {
    return false;
  }
  const headerSignature = Buffer.from(headerSignatureString, 'hex');
  const computedSignature = crypto
    .createHmac('sha256', ONSET_WEBHOOK_SECRET)
    .update(rawBody)
    .digest();

  return crypto.timingSafeEqual(computedSignature, headerSignature);
}

const app = express();

app.post(
  '/webhook',
  express.json({
    verify: (req, _res, buf) => {
      // Capture the raw body for signature verification.
      req.rawBody = buf;
    },
  }),
  (req, res) => {
    if (!verifySignature(req.get('onset-signature'), req.rawBody)) {
      return res.sendStatus(401);
    }

    if (Math.abs(Date.now() - req.body.webhookTimestamp) > 60 * 1000) {
      // Reject any webhooks not within 60 seconds of the current time to prevent replay attacks.
      return res.sendStatus(401);
    }

    try {
      // ... Handle verified webhook ...
      return res.sendStatus(200);
    } catch (err) {
      // Indicate to Onset that there was a server error so the webhook is retried later.
      return res.sendStatus(500);
    }
  },
);

app.listen(8080, () => console.log('Serving on port 8080'));
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.