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

# Signature verification

> Verify that a webhook delivery came from CollabOS.

CollabOS signs the **exact raw JSON request body** with HMAC-SHA256.

Each delivery includes:

| Header | Purpose |
| - | - |
| `X-CollabOS-Event` | Event type |
| `X-Collabos-Delivery` | Delivery identifier |
| `X-Collabos-Timestamp` | Unix timestamp used in the signature |
| `X-Collabos-Signature` | Signature in the form `v1=<hex>` |

The signed value is:

```text theme={null}
{timestamp}.{rawBody}
```

Expected signature:

```text theme={null}
v1=HMAC_SHA256(endpoint_secret, "{timestamp}.{rawBody}")
```

## Node.js example

```js theme={null}
import crypto from 'node:crypto';

export function verifyCollabOSWebhook({ rawBody, timestamp, signature, secret }) {
  const expected = `v1=${crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')}`;

  const expectedBytes = Buffer.from(expected);
  const signatureBytes = Buffer.from(signature ?? '');

  return (
    expectedBytes.length === signatureBytes.length &&
    crypto.timingSafeEqual(expectedBytes, signatureBytes)
  );
}
```

<Warning>
  Verify against the raw request body, not a parsed-and-reserialized JSON object. Re-serialization can change bytes and invalidate the signature.
</Warning>

For additional replay protection, reject timestamps that are too old for your application and deduplicate deliveries using `X-Collabos-Delivery`.


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