Notifications and Audit
Inbox, email, Slack, Telegram and webhook alerts, and the audit trail of every action.
Notifications
The bell in the dashboard collects deployment results and alert changes for every admin. Notifications are kept for 90 days.
Each admin chooses their own email settings in Settings → Notifications. Email is delivered through Resend; see Configuration.
Alert channels
Channels send alerts and deployment results to your team's chat or your own endpoint, shared by every admin. Add them in Settings → Notifications → Alert channels, pick the events each one receives (alert fired, alert resolved, deployment failed, deployment succeeded) and use Send test to check it.
Destinations are stored encrypted. Channels can't point at the control plane's own host or link-local addresses, and redirects aren't followed; private network addresses are fine. Each channel shows when it last delivered, or why it failed.
Verifying webhook signatures
Each request carries X-VPSPilot-Event and X-VPSPilot-Signature: sha256=…, the HMAC-SHA256 of the raw body with the channel's secret:
import hashlib, hmacdef verified(body: bytes, header: str, secret: str) -> bool: expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, header){ "event": "alert.firing", "sent_at": "2026-10-14T09:00:42+00:00", "title": "Memory pressure: web-1", "detail": "Memory averaged 92% over 10 min (limit 90%)", "severity": "warning", "url": "https://pilot.example.com/dashboard/monitoring"}Audit log
Every change made through VPSPilot is recorded with:
- Who: the user, or the system for automated actions such as push deploys and scheduled backups.
- What: an action such as
app.deployordatabase.credentials.view, its target and its result. - Where from: the client IP address.
- Correlation: an id that ties the entry to the job it started.
The log is append-only from the API. Read it in the dashboard or page through it with the API:
curl "https://pilot.example.com/api/v1/audit-logs?limit=50&action=server.revoke" \ -H "Authorization: Bearer $TOKEN"