Heartbeats
A heartbeat catches the failures a send URL cannot: the backup that never started, the worker that hung, the host that went offline. Your service calls its heartbeat URL on a schedule. Calling it never creates an alert. When the calls stop for longer than you allow, the channel gets one alert, and when they resume the alert is resolved.
Create a heartbeat
Section titled “Create a heartbeat”In the app, open a channel’s Send URLs and find Heartbeats below the send URLs. Choose Create heartbeat, then set:
- Name: what the alert will call the job, for example
Nightly backup. - Expected every: how often the job reports in.
- Under More options: the grace period (extra time before alerting), the alert’s title, body, level, and acknowledgement, and whether to send a notice when the job recovers.
After you create it, copy the heartbeat URL. It looks like this:
https://<api-host>/v1/heartbeat/<token>The URL can only report heartbeats; it cannot send alerts. Keep it private anyway, because anyone with it can keep the heartbeat green.
Heartbeats are not available on channels that require end-to-end encryption, because the server writes the alert and cannot encrypt it.
Report a heartbeat
Section titled “Report a heartbeat”Any GET, POST, or HEAD request counts. The body is ignored. Reporting more often than you need is harmless.
curl -fsS -m 10 --retry 3 "$HEARTBEAT_URL"Call it only after the job succeeds, so a failing job also stops the heartbeats:
30 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 "$(cat /etc/gregor-heartbeat-url)" >/dev/nullWith the command-line tool, gregor run -heartbeat "$HEARTBEAT_URL" -- backup.sh also sends an alert as soon as the job fails.
When the alert is sent
Section titled “When the alert is sent”A heartbeat is due one expected interval after the previous one, and the alert is sent once the grace period has also passed. For a nightly job with a 1-hour grace period, the alert arrives about 25 hours after the last successful run.
| State | Meaning |
|---|---|
| Waiting | Created, no heartbeat yet. The timer starts when you create the heartbeat, so a job that never reports still raises an alert. |
| Up | The last heartbeat arrived in time. |
| Late | The expected interval has passed; the grace period has not. No alert yet. |
| Down | The grace period has passed. One alert was sent. |
| Paused | No alerts until you resume it, for example during maintenance. |
An outage produces exactly one alert. An urgent heartbeat alert repeats at the reminder interval you chose until someone acknowledges it or the job recovers. The first heartbeat after an outage resolves the alert and, unless you turned it off, sends a short recovery notice.
Where to see the status
Section titled “Where to see the status”Every device that receives the channel can see its heartbeats, including subscribers who cannot change them:
- Channels: a channel with heartbeats shows how many it has and the most urgent state, for example “5 heartbeats · 1 down”. Tap it to see each heartbeat. Channel managers can create and edit heartbeats there or from the channel’s actions menu.
- Alerts: turn on Show status on Alerts page for a heartbeat, and every device that receives the channel shows it at the top of the Alerts page, with down heartbeats first.
Alert text
Section titled “Alert text”Only the title and body are templates. Insert values with the variable buttons in the app:
| Variable | Example |
|---|---|
{{monitor.name}} |
Nightly backup |
{{channel.name}} |
Servers |
{{period}} |
1d |
{{last_heartbeat_ago}} |
1d 1h |
{{last_heartbeat_at}} |
2026-10-26 02:31 +08 |
{{down_since}} |
2026-10-27 03:31 +08 |
{{outage_duration}} |
42m (recovery notice only) |
Times use the time zone of the device that created the heartbeat. The title and body follow the send limits, counted with the longest value each variable can have, so a heartbeat alert always fits.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 404 | invalid_heartbeat_url |
The URL is wrong, was regenerated or deleted, or its channel was disabled. |
| 429 | rate_limited |
Too many requests from your address. |