Heartbeat

Heartbeats are inbound — your job pings us, and if we don't hear from it within the grace window, we alert. Perfect for cron jobs, scheduled workflows, and background workers.

Send heartbeat

POST /heartbeat/{slug}

Public endpoint, no auth header required. The slug acts as the secret.

bash
curl -fsS -X POST https://happyuptime.com/api/heartbeat/nightly-backup

Response: 200 OK (empty body) on success.

With status payload

For richer reporting, send a JSON body:

statusstringbody

success (default) or fail. fail immediately opens an incident.

messagestringbody

Free-form message attached to the check (max 500 chars).

duration_msintegerbody

How long the job ran. Tracked for alerting on duration regressions.

bash
curl -X POST https://happyuptime.com/api/heartbeat/nightly-backup \ -H "Content-Type: application/json" \ -d '{ "status": "fail", "message": "Backup script exited with code 1", "duration_ms": 14821 }'

Start/finish pattern

For long-running jobs, ping at start and finish to detect hangs:

bash
# At startcurl -X POST https://happyuptime.com/api/heartbeat/{slug}/start# At finishcurl -X POST https://happyuptime.com/api/heartbeat/{slug}/finish?duration_ms=14821

If a start ping arrives without a matching finish within expected_duration + grace, an incident opens.

Grace and intervals

Configured per monitor:

FieldDescription
interval_secondsHow often you expect to ping (e.g. 3600 for hourly)
grace_secondsHow late before alerting (e.g. 300 = 5 minutes)

Skipped pings during planned downtime: ?ignore_for_seconds=3600 extends the grace for one window.

Rate limits

50 pings/minute per slug. Ping more frequently and you'll get a 429 Too Many Requests.

Slugs

Slugs are lowercase, alphanumeric + hyphens. Generated automatically when you create a heartbeat monitor; rename via Monitor → Settings → Slug.

Example slug: nightly-backup-prod. Full URL: https://happyuptime.com/api/heartbeat/nightly-backup-prod.

Ask a question... ⌘I