Docs / Monitoring

Alerts and webhooks

What raises an alert, how alerts are grouped, and how to send them to email, Telegram, Slack or Teams and signed webhooks, with the payload and signature check.

XiroLink tells you when something needs attention: a maker down or silent, a symbol without prices, a taker that will not start, blocked IPs and failed sign-ins. Alerts appear in the dashboard and can go to email, Telegram, Slack or Teams, and your own systems by webhook.

In the dashboard

The Alerts page lists every alert with its severity, type and when it was last seen, under Open, Critical, Unread and All. Acknowledge all clears them for everyone. The bell opens the latest, warnings and critical alerts also pop up, and you can turn on desktop notifications per browser.

What raises an alert

Alert Severity
A maker disconnected, after 30 seconds down Critical
A maker is connected but silent Warning
An LP rejected some symbols Warning
No prices for a symbol Critical
A symbol moved to a backup maker Warning
Back on the main maker, prices back, maker recovered Info
A taker could not start Critical
An IP was blocked automatically Warning
Repeated failed sign-ins Warning

Under Settings → Alerts you can also turn on checks for taker disconnects, high price latency and buffer overflow, with their thresholds, how often to check and a cooldown.

Fewer, better alerts

  • A repeat of the same alert within a short window updates the existing one, with a count, instead of sending again.
  • One silent LP raises one alert, not one per symbol. Stale symbols are grouped into one alert that names them.
  • Closed markets raise no stale or silent alerts.
  • Nothing is sent in the first 90 seconds after the bridge starts.

Channels

Set channels up under Settings → Notifications. Each channel has its own switch, a minimum severity (Info and above, Warning and above or Critical only) and Send test.

Channel Set up
Email Alerts go to the Admin address under Settings → Email
Telegram A Bot token and Chat ID. Create a bot with @BotFather, add it to your group, then use the group's chat ID.
Slack / Teams An Incoming webhook URL that accepts a text message: Slack, Mattermost, Discord's Slack URL or a Teams workflow
Webhook An Endpoint URL and an optional Signing secret, for your own systems

Channel secrets are stored encrypted, and changes to channels are recorded in the audit log.

Webhooks

Each alert is sent as a POST with a JSON body:

json
{
  "instance": "My Bridge",
  "sent_at": 1762156800,
  "notification": {
    "id": 42,
    "kind": "maker_down",
    "severity": "critical",
    "title": "Maker LP1 disconnected",
    "body": "Down for over 30s (error). The bridge will keep reconnecting.",
    "entity_type": "maker",
    "entity_id": "3",
    "count": 1,
    "created_at": "2026-11-03T08:00:00",
    "updated_at": "2026-11-03T08:00:00",
    "acknowledged_at": null,
    "acknowledged_by": null
  }
}
Field Contents
instance Your bridge's name
sent_at When it was sent, Unix seconds
kind, severity What happened, and info, warning or critical
title, body The alert as shown in the dashboard
entity_type, entity_id What it is about, such as a maker
count How many times it has happened in its window
created_at, updated_at UTC times

Send test sends a notification with "kind": "test".

Verify the signature

With a Signing secret set, every request carries:

text
X-Bridge-Signature: sha256=<hex digest>

The digest is HMAC-SHA256 of the raw request body with your secret. Compute it over the exact bytes you received and compare in constant time:

python
import hashlib, hmac

def is_valid(body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)

Use sent_at to reject old requests. Answer with a 2xx status within 8 seconds. Failed deliveries are not retried, so the Alerts page stays the record of everything that happened.

Something unclear or out of date? Email [email protected].