title: "Alerts & notifications" description: "How BoxWatch decides when to alert you and where to send it." last_updated: "2026-05-24"

Alerts & notifications

BoxWatch alerts you when something goes wrong. Email is on by default. Slack, Discord, and generic webhooks route the same events to wherever your team actually pays attention.

Where alerts come from

Every monitoring surface in BoxWatch produces alerts on the same pipeline. The dispatcher doesn't care whether the trigger was a missed heartbeat or an expired cert — it picks the same set of channels.

Server metrics

Threshold-based rules on CPU, memory, and disk. Configure them at Dashboard → Alerts. See server monitoring for the underlying metrics. Available alert types: server_offline, cpu_high, memory_high, disk_high.

Cron heartbeats

Missed, failing, stuck, and running-long alerts for cron checks. One alert per state transition — not one per cycle.

Processes

process_down, process_restarted, process_cpu_high, process_memory_high. Tracked by the agent on each server. See process monitoring.

Synthetic uptime checks

uptime_down, uptime_recovery, uptime_cert_expiring. HTTP, TCP, ICMP, and TLS probes from BoxWatch's checker nodes. See uptime checks.

Channels

Every account starts with email enabled for the registration address. Add channels at Dashboard → Account → Notifications.

  • Email — Recipient list per account. On by default.
  • Slack — One incoming webhook URL per account.
  • Discord — One webhook URL per account.
  • Generic webhooks — Any number of HTTPS endpoints with custom headers and per-channel alert-type filtering. Use this for PagerDuty, Opsgenie, internal routers, or anything else.

When an alert fires, BoxWatch fans it out to every configured channel in parallel. A failure on one channel doesn't block the others.

Routing rules

Routing is account-wide today. Slack and Discord URLs live on the user record — one of each. Email goes to the account email. Generic webhook endpoints support per-endpoint alert-type filters, so you can have one webhook receive only cron_missed and another receive only uptime_down.

Per-server and per-group overrides aren't shipped yet. If you need different routing per environment, create separate generic webhook endpoints and filter by alert_type.

Severity & state

BoxWatch doesn't tag alerts with a generic info / warning / critical field. Severity is implied by the alert type:

  • Critical: server_offline, process_down, uptime_down, cron_missed, cron_failing, cron_stuck
  • Warning: cpu_high, memory_high, disk_high, process_cpu_high, process_memory_high, cron_running_long, uptime_cert_expiring
  • Info / recovery: uptime_recovery, process_restarted

The Slack and Discord renderers color the message based on type — red for down, amber for warnings, green for recoveries.

Anti-storm: state-transition deduplication

Alerts fire on state change, not on every poll. The first time a server flips up → down, you get one alert. The check stays down until a recovery brings it back, and only then can it fire again. This is enforced in the monitor loop via stored alerted_state columns on each entity.

There's also a per-tick safety cap. If more than 50 checks transition into bad states in a single 60-second tick — typically because BoxWatch itself was offline and just came back — the rest get rolled into the digest and a single "alert storm suppressed" line is logged.

Maintenance windows

Open a maintenance window on a server and BoxWatch silences alerts for everything linked to it: server metrics, processes, and any cron checks pointing at that server. State still transitions in the dashboard so you can see what's happening, but no notifications go out. See maintenance windows.

For ad-hoc pauses on a single check or process, use the per-entity pause toggle instead.

Digest mode

If you don't want immediate alerts, set alert_mode to digest at Dashboard → Account → Preferences. Alerts collect in a digest and ship on the cadence you pick (weekly, monthly, or both). Useful for hobby servers where you'd rather see a Monday-morning summary than a 3 AM page.

immediate is the default.

Alert history

Every dispatched alert is recorded. Browse the history at Dashboard → Alerts → History or via the API:

GET/alerts/history
Auth: bearer

Each row has the trigger type, the affected entity, the channels notified, and the timestamp. Useful for post-mortems and for confirming that alerts actually reached you.

Plan caps

Alert rules (threshold-based server metric alerts) are capped per plan:

PlanAlert rules
Hobby1
Pro5
Team20
Scale50

Heartbeat, process, and uptime alerts aren't counted against this — they're attributes of their parent entity. The cap exists for explicit alert_rules rows (CPU/memory/disk thresholds).

See also

Was this page helpful?