Sthora
Monitoring

Notification channels

Getting alerts out by email or signed webhook, what a channel can subscribe to, and how to verify a webhook signature.

A channel is where alerts go. Two kinds: EMAIL and WEBHOOK.

Field
name1–64 characters.
kindEMAIL or WEBHOOK.
targetAn address, or an http:///https:// URL up to 512 characters.
kindsWhich alert kinds to receive. Empty means every kind.
isEnabled
hasSecretWhether a signing secret is set. The secret itself is never returned.
lastDeliveredAt, lastErrorThe receiver's own message, shown on the channel's page.

Why the URL scheme is restricted

An outbound webhook is a fetch this platform makes on an operator's behalf. Allowing any scheme would hand something like file: to whatever the delivery client is willing to open, so the set of things it may fetch belongs in the contract.

Webhook signatures

POST /notification-channels returns a signing secret once. No other response can carry it.

Each delivery is signed HMAC-SHA-256 over <timestamp>.<body>. Verify it by recomputing the digest over the timestamp and the raw body — not the parsed one, since re-serialising JSON changes the bytes.

import { createHmac, timingSafeEqual } from 'node:crypto'

function verify(secret, timestamp, rawBody, signature) {
  const expected = createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')

  const a = Buffer.from(expected)
  const b = Buffer.from(signature)
  return a.length === b.length && timingSafeEqual(a, b)
}

Reject a timestamp far from now, or a replayed delivery is indistinguishable from a real one.

Email

Email needs a transport. Set EMAIL_TRANSPORT=smtp and the SMTP settings in configuration.

With no transport configured, email is skipped entirely and says so in the API log rather than failing. Alerts still open and still go out on webhooks. That is deliberate — a platform that refuses to boot because nobody configured a mail relay is worse than one that tells you.

Send only from a domain you control and have authenticated with SPF, DKIM, and DMARC. The domain in EMAIL_FROM_ADDRESS must align with the DKIM signing domain, or DMARC fails even when both records exist.

When nothing arrives

Check the portal. If the alert is not there, the condition was never noticed and the delivery side is not the problem.

Check the channel's lastError. It is the receiver's own message, verbatim.

Check Redis. Delivery runs through the notify queue. If Redis is down, alerts are raised and stored but nothing is sent.

On this page