Monitors / Heartbeat
Heartbeat
Your jobs ping a unique URL. Missed pings fail. Hung starts fail too.
How it works
Heartbeats are inbound. Nothing is probed. Cron, backups, and batch jobs GET or POST a unique URL. The scheduler still runs on interval_seconds: if no ping arrived in that window, the monitor is down.
The base URL counts as success (/finish). Append /start when a job begins, /finish when it completes, and /error if it fails. After /start, the job must finish within the interval or the check is “Heartbeat started but not finished.”
Target is only a label (for example backup-job). The token and URLs are generated. Heartbeats do not take conditions, probes, or an IP family.
Target
A label, not a URL. The ping URLs are generated and shown on the monitor.
backup-jobType fields
| Field | What it does |
|---|---|
heartbeat_url | GET or POST to signal success. Same as /finish. Terraform: computed after apply. |
heartbeat_start_url | Mark the job as running. Must be followed by finish or error within the interval. Terraform: computed after apply. |
heartbeat_finish_url | Job succeeded. Resets the running window. Terraform: computed after apply. |
heartbeat_error_url | Job failed. Records a failed check immediately. Terraform: computed after apply. |
GraphQL
type is Heartbeat. Same fields as the admin, camelCase in the input (intervalSeconds, requestBody, probeIds).
mutation {
createMonitor(input: {
name: "Nightly backup"
type: Heartbeat
target: "backup-job"
intervalSeconds: 86400
}) { id heartbeatUrl heartbeatStartUrl heartbeatFinishUrl }
}Terraform
Resource is nominal_monitor from returnearly/nominal. type is Heartbeat. Shared arguments match the shared fields in snake_case (name, target, interval_seconds, probe_ids, channel_ids).
After apply, heartbeat_url, heartbeat_start_url, heartbeat_finish_url, heartbeat_error_url, and heartbeat_token (sensitive) are computed.
resource "nominal_monitor" "backup" {
name = "Nightly backup"
type = "Heartbeat"
target = "backup-job"
interval_seconds = 86400
}