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

# Signature Verification

> Verify that webhook events came from Ledger.

## Header format

Every webhook delivery includes a signature header:

```
X-Ledger-Signature: t=<unix_seconds>,v1=<hex_hmac_sha256>
```

## Verification steps

<Steps>
  <Step title="Extract the timestamp and signature">
    Parse the `t` (timestamp) and `v1` (signature) values from the header.
  </Step>

  <Step title="Compute the expected signature">
    ```javascript theme={null}
    const crypto = require('crypto');

    const payload = `${timestamp}.${rawBody}`;
    const expected = crypto
      .createHmac('sha256', signingSecret)
      .update(payload)
      .digest('hex');
    ```
  </Step>

  <Step title="Compare signatures">
    Use a constant-time comparison to check that your computed signature matches `v1`.

    ```javascript theme={null}
    const isValid = crypto.timingSafeEqual(
      Buffer.from(expected, 'hex'),
      Buffer.from(v1, 'hex')
    );
    ```
  </Step>
</Steps>

## Replay protection

Optionally check that `t` is within an acceptable window (e.g. 5 minutes) to prevent replay attacks.
