# Verification Steps

Each webhook call includes three headers with additional information that are used for verification:

<figure><img src="https://1312452151-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD4BjsPWqmImyNxa9scb3%2Fuploads%2FBh8SKi2cXWQnUmN1lfUQ%2Fcdl.png?alt=media&#x26;token=3064de52-b55d-48fb-a948-b2507b374bd1" alt=""><figcaption><p>Lenda webhook capture</p></figcaption></figure>

* `svix-id`: the unique message identifier for the webhook message. This identifier is unique across all messages, but will be the same when the same webhook is being resent (e.g. due to a previous failure)
* `svix-timestamp`: timestamp in [seconds since epoch](https://en.wikipedia.org/wiki/Unix_time).
* `svix-signature`: the [Base64](https://en.wikipedia.org/wiki/Base64) encoded list of signatures (space delimited).

## Constructing the signed content <a href="#constructing-the-signed-content" id="constructing-the-signed-content"></a>

The content to sign is composed by concatenating the id, timestamp and payload, separated by the full-stop character (`.`). In code, it will look something like:

```csharp
signedContent = $"{svix_id}.{svix_timestamp}.{body}"
```

Where `body` is the raw body of the request. The signature is sensitive to any changes, so even a small change in the body will cause the signature to be completely different. This means that you should *not* change the body in any way before verifying.

## Determining the expected signature <a href="#determining-the-expected-signature" id="determining-the-expected-signature"></a>

Lenda uses an [HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) with [SHA-256](https://en.wikipedia.org/wiki/SHA-2) to sign its webhooks.

So to calculate the expected signature, you should HMAC the `signed_content` from above using the base64 portion of your signing secret (this is the part after the `whsec_` prefix) as the key. For example, given the secret `whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw` you will want to use `MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw`.

For example, this is how you can calculate the signature in:

```javascript
// Some code

const crypto = require('crypto');

signedContent = `${svix_id}.${svix_timestamp}.${body}`
const secret = "whsec_5WbX5kEWLlfzsGNjH64I8lOOqUB6e8FH";

// Need to base64 decode the secret
const secretBytes = new Buffer(secret.split('_')[1], "base64");
const signature = crypto
  .createHmac('sha256', secretBytes)
  .update(signedContent)
  .digest('base64');
console.log(signature);
```

Make sure to remove the version prefix and delimiter (e.g. `v1,`) before verifying the signature.

Please note that to compare the signatures it's recommended to use a constant-time string comparison method in order to prevent timing attacks.

## Verify timestamp <a href="#verify-timestamp" id="verify-timestamp"></a>

As mentioned above, Lenda also sends the timestamp of the attempt in the `svix-timestamp` header. You should compare this timestamp against your system timestamp and make sure it's within your tolerance in order to prevent timestamp attacks.
