Alert channels
A channel is a destination for alerts. cronpad supports email and webhooks; webhook channels can format their body for Slack or Discord incoming webhooks, or send a generic signed JSON payload for your own systems. Every channel has a Send test button (POST /api/v1/alert-channels/{id}/test).
{"kind": "email", "name": "On-call", "config": {"to": ["oncall@example.com"]}}
- Verification links expire after 24 hours. Use Resend verification (
POST /api/v1/alert-channels/{id}/verify) if a link expires. Changing the recipient list requires every address to verify again. - Every address must be verified: cronpad emails a confirmation link, and the channel only sends after it’s clicked. This prevents cronpad from being used to email people who didn’t ask for it.
- Remote SMTP servers must support STARTTLS; loopback SMTP relays may use plaintext.
- Self-hosted servers need SMTP settings in
[alerts.email].
Slack and Discord
Create an incoming webhook in Slack or Discord, then:
{"kind": "webhook", "name": "#ops", "config": {"url": "https://hooks.slack.com/services/T000/B000/XXXX", "format": "slack"}}
Use "format": "discord" for Discord webhook URLs. Messages include the event, job name, run time, attempts, last error and a link to the run in the dashboard.
Generic webhook
{"kind": "webhook", "name": "PagerDuty bridge", "config": {"url": "https://alerts.example.com/cronpad", "format": "generic"}}
cronpad sends a POST with this body:
{
"event": "run.failed",
"occurred_at": "2026-11-10T03:31:12Z",
"workspace_id": "ws_01J9X…",
"job": {"id": "job_01J9ZK3Q…", "name": "nightly-report", "tags": ["reports"]},
"run": {
"id": "run_01J9ZM1A…",
"scheduled_at": "2026-11-10T03:30:00Z",
"status": "failed",
"attempts": 3,
"last_error": "HTTP 503: upstream unavailable"
},
"suppressed_count": 0,
"url": "https://app.cronpad.com/runs/run_01J9ZM1A…"
}
Requests are signed exactly like job webhooks (Standard Webhooks headers), with a per-channel signing secret shown when you create the channel. See Verify signatures.
Delivery
- Deliveries use a stable
webhook-idacross retries. Receivers should deduplicate this ID: a restart after delivery but before recording success can repeat a request. - Alerts are sent from a durable outbox and retried with backoff up to 8 times if the channel is down.
suppressed_counttells you how many identical alerts were held back by the rule’s cooldown since the last one was sent.