Heartbeat (cron jobs)
Overview
Section titled “Overview”A heartbeat monitor (type push) works the other way round from the other checks: OKStatus doesn’t call your service, your job calls OKStatus each time it runs. If no ping arrives in time, the monitor goes down and you’re alerted.
Use it for anything that runs on a schedule and has no URL to probe: cron jobs, backups, queue workers, nightly imports, certificate renewals.
Create one
Section titled “Create one”curl -X POST https://api.okstatus.eu/api/v1/monitors \ -H "Authorization: Bearer $OKSTATUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Nightly backup", "type": "push", "url": "nightly-backup", "interval": 86400, "gracePeriod": 3600 }'urlis only a label for a heartbeat: nothing is fetched.intervalis how often the job runs, in seconds.gracePeriodis the extra time allowed before the monitor goes down. Without it, it equalsinterval.
The response carries the monitor’s pushUrl:
{ "data": { "id": "…", "type": "push", "pushToken": "…", "pushUrl": "https://backend.okstatus.eu/push/…" }}The same pushUrl comes back every time you read the monitor with a Full key. A read-only key, and a member with the viewer role, see the monitor without its token and URL. With Terraform, build the URL from the push_token attribute:
output "backup_ping_url" { value = "https://backend.okstatus.eu/push/${okstatus_monitor.backup.push_token}" sensitive = true}Send a ping
Section titled “Send a ping”Call the URL at the end of each successful run. POST, GET and HEAD all count as an up ping:
curl -fsS -m 10 --retry 3 -X POST https://backend.okstatus.eu/push/<token>A crontab line that pings only when the job succeeds:
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 -X POST https://backend.okstatus.eu/push/<token> > /dev/nullTo report a failure or send a message, use POST with a body (below): a GET is always an up ping. Link previews in chat tools fetch URLs with GET, which is one more reason not to paste the URL in a conversation.
Report a failure or a duration
Section titled “Report a failure or a duration”The body is optional. When present, it’s JSON:
| Field | Type | Description |
|---|---|---|
status | string | up (default) or down: report a failure right away, without waiting |
msg | string | Up to 2,000 characters, kept with the check and shown in the dashboard and alerts |
ping | integer | How long the job took, in milliseconds (0 to 60,000) |
if ! /usr/local/bin/backup.sh; then curl -fsS -m 10 -X POST https://backend.okstatus.eu/push/<token> \ -H "Content-Type: application/json" \ -d '{ "status": "down", "msg": "backup.sh exited with an error" }'fiAn empty body is an up ping. A body that isn’t valid JSON, or whose fields don’t match the table, is refused with 400 and records nothing, so a typo such as "status": "failed" can’t pass for a success.
When the monitor goes down
Section titled “When the monitor goes down”The monitor is down when no ping has arrived for interval + gracePeriod seconds since the last one. OKStatus checks every 30 seconds.
- Before the first ping, the monitor has no state and never goes down: send one ping when you set the job up.
- A ping after a timeout brings the monitor back up and sends the recovery alert.
- Paused: pings are accepted but recorded nowhere and alert nobody. Resuming starts from the last ping received.
- Muted or in a maintenance window: pings are recorded, alerts are held back, as for any monitor.
The ping URL has no region: the majority rule of multi-region checks doesn’t apply to heartbeats.
Responses and limits
Section titled “Responses and limits”| Status | Body | Meaning |
|---|---|---|
200 | { "ok": true } | Ping recorded |
200 | { "ok": true, "paused": true } | The monitor is paused: nothing recorded |
400 | { "error": "INVALID_BODY" } | The body isn’t JSON, or a field is out of range: nothing recorded |
404 | { "error": "NOT_FOUND" } | Unknown token, or the monitor isn’t a heartbeat |
413 | { "error": "PAYLOAD_TOO_LARGE" } | Body over 8 KiB |
429 | { "error": "RATE_LIMIT_EXCEEDED" } | More than 30 pings a minute for this monitor; see Retry-After |
Keep the token secret
Section titled “Keep the token secret”The token in the URL is the only credential: anyone who has it can send pings and hide a failed job. Keep the URL in a secret or an environment variable rather than in a public repository, and don’t paste it in tickets or chats. If it leaks, delete the monitor and create a new one: the token can’t be rotated in place.
Prometheus
Section titled “Prometheus”The Prometheus export has okstatus_push_last_received_timestamp_seconds, the time of the last ping, for each heartbeat monitor.