What it is
A heartbeat monitor watches a cron job, backup script, queue worker, or any other process that runs on its own schedule rather than serving requests. Your job requests a unique RealUptime URL each time it runs. If those pings stop arriving for longer than the monitor's configured interval plus its grace period, the monitor is marked down and the normal alert fan-out fires, the same incidents, Slack, email, PagerDuty, and webhook channels every other monitor on RealUptime uses. Recovery is simply the next ping arriving.
No probe regions are involved in either direction. Unlike an HTTP monitor, RealUptime never reaches out to your infrastructure for a heartbeat; it only listens for the ping you send it.
The ping contract
Send a GET or POST request to https://ingest.realuptime.io/api/ping/<token>. Both verbs are accepted, since the caller is typically curl, wget, or a scheduler's "call a webhook" step, and forcing a particular verb on a crontab line is a pointless integration failure.
The token is generated once when the monitor is created, or re-generated from the dashboard, which invalidates the old one. The token is the credential: treat the ping URL as a secret, the same way you would treat an API key.
A successful ping returns a tiny 200 plain-text body and nothing else, no JSON, no customer data. An unknown or malformed token returns a bare 404, deliberately indistinguishable from each other, so the endpoint can never be used to confirm whether a guessed token exists.
Pings are rate limited to 120 requests per minute per token, generous headroom for retries and clock skew on a correctly configured job, while still stopping a tight-loop misconfiguration from becoming unbounded traffic. The /start and /fail endpoints below share that one allowance, so a run that sends both a start and a success uses two.
Arming
A heartbeat that has never received a ping is awaiting first ping, not down. Monitoring only arms on the very first ping the token receives, matching how other tools in this space behave. A monitor you just created but have not wired up yet will never page anyone.
Interval and grace period
Heartbeats share the same 60 second floor and 24 hour ceiling as every other monitor type on RealUptime, set at monitor creation. The grace period is extra slack past the interval before a late ping counts as down, useful for a job whose runtime varies, so a normal few extra seconds or minutes doesn't trigger a false alert.
Setup
Create a heartbeat monitor from the dashboard's Add monitor flow, choosing Heartbeat, then copy the ping URL it gives you. A simple manual check:
curl https://ingest.realuptime.io/api/ping/YOUR_PING_TOKENThe usual case is a crontab entry that pings after the job runs, discarding the response:
*/5 * * * * curl -fsS https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN > /dev/null 2>&1If you lose or need to rotate the token, regenerate it from the monitor's own detail page. Regenerating invalidates the old URL immediately.
Runs: start, success and fail
The ping above means "the job succeeded". Two more endpoints let RealUptime see each run, not just its end: /api/ping/<token>/start when the job begins and /api/ping/<token>/fail when it fails. With both, the monitor page shows every run with its start time, duration and outcome, and how long your job takes over time. Both are optional: a monitor that only ever sends the plain ping works exactly as described above.
A crontab line that reports the start, then success or failure:
0 3 * * * curl -fsS https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN/start > /dev/null; /usr/local/bin/backup.sh && curl -fsS https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN > /dev/null || curl -fsS https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN/fail > /dev/nullOr a wrapper script, which also sends the exit code. The body of a /fail POST is optional: a bare number is recorded as the exit code, any other text as a short message (up to 500 characters), and it appears in the run history and in the alert.
#!/bin/sh
curl -fsS -m 10 --retry 3 "https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN/start" > /dev/null
if output=$(/usr/local/bin/backup.sh 2>&1); then
curl -fsS -m 10 --retry 3 "https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN" > /dev/null
else
code=$?
# A bare number is recorded as the exit code; any other text as a short message.
curl -fsS -m 10 --retry 3 --data-raw "$code" "https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN/fail" > /dev/null
fiA failed run marks the monitor down immediately and alerts with its own wording, "run failed", distinct from a missed ping. The next successful run marks it operational again.
/start never counts as a check-in. The interval is measured between successes, so a job that starts and then dies part way still goes down as missed once its interval and grace run out.
Run ids, for overlapping runs
Without a run id, a success or fail closes the most recent run that has started, and a new start replaces an earlier one that never finished. If runs of the same job can overlap, add the same rid query parameter to all three requests of a run, up to 64 letters, digits, dots, colons, hyphens or underscores, so each finish pairs with its own start:
RID=$(date +%s)-$$
curl -fsS "https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN/start?rid=$RID" > /dev/null
/usr/local/bin/sync-shard.sh && curl -fsS "https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN?rid=$RID" > /dev/null || curl -fsS "https://ingest.realuptime.io/api/ping/YOUR_PING_TOKEN/fail?rid=$RID" > /dev/nullMaximum runtime (stuck runs)
Set a maximum runtime on the monitor's page to catch a job that started but never finished, hung on a lock or a slow dependency. A run that has not sent its success or fail within that time is marked stuck: the monitor goes down once, with "run stuck" wording that names the limit, and recovers on the next successful run. It is off by default, needs the /start ping, and can be from 1 second to 24 hours.
Repeated failures
A job that fails and then succeeds on every run, behind a retry wrapper for example, would otherwise go down and recover every few minutes, with an alert each way. Instead, once a monitor has failed (or got stuck) and recovered three times in 24 hours, the next failure holds it down: the alert says so, further successes are still recorded but do not clear it, and it recovers on its own after one full interval plus grace with no failed or stuck run. A failure inside that interval starts it again. Pausing the monitor clears the hold. A missed ping never counts toward it, so a monitor that only sends the plain ping is never held down.
Availability and pricing
Heartbeat monitors are available on every plan, free included, and count against the same monitor-slot limit as HTTP monitors. There is no separate heartbeat allowance and no extra cost. See pricing for what each plan includes.