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

# Webhooks

TIS Training offers webhooks as a way to listen for events from your users. When the specified event occurs, we can send notice of the event to an endpoint you specify, along with some data about the event.

### Subscribing to Events

You can add a URL to receive events [here](https://training.tapintosafety.com.au/admin/OrganisationWebhooks), or you add them via the **View Webhooks** button in the organisation config section of the administration panel. To create a webhook:

1. Click **Add Webhook**
2. Choose the type of event you'd like to subscribe to for this webhook.
3. Enter the URL you would like the events to be sent to. This URL must use the HTTPS scheme.
4. Click **Add**

A `POST` will be sent to the URL specified with a `TEST_EVENT` event type. Details about the schema of a webhook event, and the specific event data, can be found in the [Webhook Reference](/webhook-reference.md) section. Your server must return a success response code (`200-299`) for the webhook to be added. All webhook events are sent using the `POST` method.

Once the webhook is added, you will be shown a **validation secret**. Make sure you record this secret for the next section, as it will not be shown again.

### Validating Events

All events will be sent with a header called `TapIntoSafety-Signature`. You can use this header to verify that events have been sent from Tap into Safety. In order to do this, generate a `HMAC-SHA256` signature of the body of the event. The **validation secret** is a base64 representation of the key for the signature. An example in JavaScript is below.

```javascript
const message = '(The JSON payload of the event)';
const signature = "(The content of the TapIntoSafety-Signature header)";
const SECRET = "(Your validation secret)";

const algorithm = { name: "HMAC", hash: "SHA-256" };

const key = await crypto.subtle.importKey(
  "raw",
  Uint8Array.from(atob(SECRET), c => c.charCodeAt(0)),
  algorithm,
  false,
  ["sign", "verify"]
);

await crypto.subtle.verify(
  algorithm.name,
  key,
  Uint8Array.from(atob(signature), c => c.charCodeAt(0)),
  new TextEncoder().encode(message)
);
```

### Failed Events

If your server is unavailable or returns a non-success response code, we'll retry the event a few times before marking it as failed. If you server does not return a successful response after 3 days, we'll automatically disable the webhook and send you an email to let you know. You can reenable the webhook in the [Organisation Webhooks section](https://training.tapintosafety.com.au/admin/OrganisationWebhooks) once your server is up and running again.
