> For the complete documentation index, see [llms.txt](https://docs.loyaltysurf.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.loyaltysurf.io/developer-tools/webhooks/securing-your-webhooks.md).

# Securing Your Webhooks (optional)

This is an optional step. For security purposes, you can add a webhook secret to limit requests sent to your webhook endpoint to those only coming from LoyaltySurf.

## Adding a secret

1. Go to the *Options* step in the *Program Editor*.
2. In the Webhooks integration, click *Show advanced webhook settings* and enter the secret (it can be any string of text).
3. Publish/save your changes.

<figure><img src="https://3285719719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTwFF4MDnpq2eL5eyOdtK%2Fuploads%2FdZF2wWkgscWhC4YgHPNZ%2FScreen%20Shot%202023-01-12%20at%203.29.17%20PM.png?alt=media&amp;token=081d6684-9076-438a-9853-c1614ec9ac8f" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Once your program has a webhook secret, a signature`LoyaltySurf-Signature` will be included in the header of all outgoing requests to your webhook endpoint.
{% endhint %}

## Validating payloads

When your secret token has been set, LoyaltySurf uses it to create a hash signature to include in the header of each event notification payload.\
\
The signature hash is passed along with each request in the header as `LoyaltySurf-Signature`. You will need to compute a hash once the payload is received and compare it against the`LoyaltySurf-Signature` value provided by LoyaltySurf within the header. Those steps are outlined below.

{% hint style="info" %}
The`LoyaltySurf-Signature` header contains a timestamp and a signature hash value. The timestamp is prefixed by `ts=`, and the signature value is prefixed by `v=`.
{% endhint %}

### **Step 1: Extract the timestamp and signature from the header**

Split the header using the `,` character as the separator to get a list of elements. Then split each element using the `=` character as the separator to get a key/value pair.\
\
The value for key/prefix `ts` corresponds to the timestamp and the `v` key/prefix corresponds to the signature you will use to compare your generated hash against.

{% hint style="info" %}
NOTE: `ts` is a Unix timestamp in milliseconds
{% endhint %}

### **Step 2: Prepare the signed payload string for comparison**

Achieve this by concatenating:

* The timestamp (as a string). AKA the value of `ts`
* The character `.`
* The actual JSON payload within the request body

### **Step 3: Determine the expected signature**

Compute an *HMAC* with a `SHA256` hash function. Use the endpoint's signing secret token as the key (which you added in the *Options* step in the *Program Editor*), and use the signed payload string from **Step 2** as the message.

### **Step 4: Compare signatures**

Compare the LoyaltySurf provided signature within the header to the expected signature. If they match then compute the difference between a current timestamp and the received timestamp `ts`. Then decide if the difference is within your tolerance.

{% hint style="info" %}
**Tip:** The timestamp comparison is completely optional but it will help to protect against timing attacks.
{% endhint %}

## View an example

[View an example here](/developer-tools/webhooks/examples.md#example-1-webhooks-with-secret)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.loyaltysurf.io/developer-tools/webhooks/securing-your-webhooks.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
