> For the complete documentation index, see [llms.txt](https://doc.sec3.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.sec3.dev/sec3-watchtower/handle-alert-via-webhook.md).

# Handle Alert via Webhook

## Alert Object <a href="#alert-object" id="alert-object"></a>

WatchTower will send each alert as a JSON object to the configured webhook URL via a POST request.

{% code title="Alert Object Example" %}

```json
{
    "id": "634cf5d77b42a046f68f5a5d",
    "botId": "634cf5d77b42a046f68f5a5e",
    "botName": "MyToken 500+",
    "projectId": "634cf5d77b42a046f68f5a5a",
    "projectName": "My Token",
    "userId": "634cf5d77b42a046f68f5a5f",
    "username": "John Doe",
    "template": "AbnormalTransferToken",
    "severity": "critical",
    "tx": ["6CfQwX7YwvA2bFRT8wfzZEtVEUbbrjUeMzBa9AbtThioHC6xfrfxSC3nCQWB5Y3BLV9cqadf69n9ApeBYhvwzNF1"],
    "detail": "The smart contract is involved in a transaction transferring 923750.55 Unknown Token. The token mint is 9Mu1Kaxbe2fehdDoeTJ5oD7XFQmEiZxzspEd3TZGkavx",
    "target": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    "args": {"threshold": "500"},
    "isArchived": false,
    "created_at": "2022-12-06T17:10:21.672Z",
    "link": "https://pro.sec3.dev/alert/634cf5d77b42a046f68f5a5d"
}
```

{% endcode %}

## Sample webhook handler code <a href="#sample-webhook-handler-code" id="sample-webhook-handler-code"></a>

{% tabs %}
{% tab title="Go" %}

```go
package main

import (
	"log"
	"net/http"
	"encoding/json"
	"fmt"
	"time"
)

// Define the Sec3 WatchTower secret
// In the actual server, the secret should be put in the environmental variables
const SEC3_WATCHTOWER_SECRET = "your_secret"

type Alert struct {
	ID          string            `json:"id"`
	BotId       string            `json:"botId"`
	UserId      string            `json:"userId"`
	ProjectId   string            `json:"projectId"`
	Username    string            `json:"username"`
	ProjectName string            `json:"projectName"`
	BotName     string            `json:"botName"`
	Template    string            `json:"template"`
	Severity    string            `json:"severity"`
	Tx          []string          `json:"tx"`
	Detail      string            `json:"detail"`
	Targets     []string          `json:"targets"`
	Args        map[string]string `json:"args"`
	IsArchived  bool              `json:"isArchived"`
	CreatedAt   time.Time         `json:"created_at"`
	Link        string            `json:"link"`
}

func sec3WebhookHandler(w http.ResponseWriter, r *http.Request) {
	// Verify the incoming request. If the secret is empty or does not match
	// with the one you set, return 401 status code
	incomingSecret := r.Header.Get("X-Sec3-Watchtower-Secret")
	if incomingSecret == "" || incomingSecret != SEC3_WATCHTOWER_SECRET {
		http.Error(w, "unauthorized", http.StatusUnauthorized)
		return
	}
	
	// Declare a new Alert struct.
	var alert Alert

	// Try to decode the request body into the struct. If there is an error,
	// respond to the client with the error message and a 400 status code.
	err = json.NewDecoder(r.Body).Decode(&alert)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Do something with the alert...
	fmt.Printf("Alert:\n %+v\n", alert)
}

func main() {
	http.HandleFunc("/sec3_webhook", sec3WebhookHandler)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal(err)
	}
}
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
// This example uses express.js framework. See https://expressjs.com
const express = require('express');
const app = express();
const port = 3000;

// Define the sec3 WatchTower secret
// In the actual server, the secret should be put in the environmental variables
const SEC3_WATCHTOWER_SECRET = "your_secret";

// Verify the incoming request. If the secret is empty or does not match
// with the one you set, return 401 status code
app.use((req, res, next) => {
  const incomingSecret = req.header("X-Sec3-Watchtower-Secret");
  if (incomingSecret != SEC3_WATCHTOWER_SECRET) {
    res.sendStatus(401);
    return;
  }
  next();
})

app.use(express.json());

app.post('/sec3_webhook', (req, res) => {
  const alert = req.body;

  // Do something with the alert...
  console.log(alert);
  res.sendStatus(200);
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
```

{% endtab %}
{% endtabs %}


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://doc.sec3.dev/sec3-watchtower/handle-alert-via-webhook.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
