Skip to main content

Heartbeats

A heartbeat monitor is passive. Instead of kamustatus probing your service, your job calls a ping URL each time it runs. When no ping arrives within the expected period plus grace, the monitor is down and its alert rules fire. Use it for cron jobs, queue workers and anything without public ingress.

Create one​

Dashboard: Monitor → project → New monitor, type Heartbeat. Set Expected period (s) (how often the job runs) and Grace (s) (how late it may be). CLI:

kamu status monitors add <project-id> --name "Nightly backup" --type heartbeat \
--interval 86400 --grace 3600
kamu status monitors show <monitor-id> # prints the ping URL
FieldDefault
Expected period (--interval)300 s
Grace (--grace)0 s

The ping URL is shown on the monitor page and in kamu status monitors show:

https://api.kamustatus.com/ping/<token>

The token is the only credential. Anyone holding the URL can ping it, which is harmless, so it can live in fly.toml [env].

Sending pings​

Any method works. A plain GET is enough:

curl -fsS https://api.kamustatus.com/ping/<token>

Crontab, pinging only when the job succeeded:

0 3 * * * /usr/local/bin/backup.sh && curl -fsS https://api.kamustatus.com/ping/<token>

Responses:

StatusBodyMeaning
200{"ok": true}Ping recorded.
200{"ok": true, "status": "disabled"}Monitor is paused; nothing recorded.
404{"error": "Unknown heartbeat token"}Wrong or deleted token.
413{"error": "Body too large (max 1024 bytes)"}See metrics below.
400{"error": "Too many metric keys (max 20)"}See metrics below.
429{"error": "Rate limited. Next ping in Ns", "retryAfter": N}Pinged too soon.

Rate limit. One ping per expected period, with a floor of 10 seconds. A monitor with the default 300 s period accepts one ping every 5 minutes; extra pings get 429 and are not recorded. Ping once per run, not in a tight loop. If the job runs more often than the period, lower the period.

When it goes down​

The worker checks heartbeats every minute. A monitor is down when the last ping is older than expected period + grace. A new monitor that has never been pinged can go down at the next check, so send a first ping right after creating it. The alert says "No heartbeat received" or "No heartbeat within interval".

Heartbeat alerts ignore the rule's consecutive-failure count. While down, each rule notifies again every 10 minutes; the first ping after that sends an UP. Maintenance windows do not suppress heartbeat alerts.

Metrics in the ping body​

A POST can carry a flat JSON object of numbers and strings:

curl -fsS -X POST https://api.kamustatus.com/ping/<token> \
-H "Content-Type: application/json" \
-d '{"duration_ms": 1234, "rows": 500, "result": "ok"}'
  • Body at most 1024 bytes, at most 20 top-level keys.
  • Only string and number values are kept. Nested objects, arrays and booleans are dropped.
  • A body that is not a JSON object is stored as-is and the ping still counts.
  • Only POST bodies are read; there is no query-string form.

Stored metrics are kept for 30 days. Read them back with GET /api/status/monitors/<id>/heartbeat-metrics?hours=24 through the front door (an access key with status.read).

Metric threshold rules​

A metric rule compares one numeric key of each incoming ping against a threshold.

FieldValues
metricKeyA key from your ping body, e.g. duration_ms.
operatorgt, lt, gte, lte, eq, neq
thresholdNumber.
consecutiveTriggersBreaching pings in a row before it fires (default 1).
channelIdOptional.
curl -X POST https://app.kamuhub.com/api/status/monitors/<monitor-id>/metric-alerts \
-H "Authorization: Bearer $KAMU_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{"metricKey": "duration_ms", "operator": "gt", "threshold": 600000}'

GET on the same path lists rules; DELETE /api/status/metric-alerts/<id> removes one. Pings without the key, or with a string value for it, are skipped.

Current limits, so set expectations accordingly:

  • A firing rule is not delivered to any channel. It is returned in the ping response ("alerts": ["duration_ms gt 600000 (value: 734000)"]) and, when the rule has a channel, written to the monitor's alert history as metric_threshold. If you need to be paged, have the job check the value itself and skip the ping, so the heartbeat goes down.
  • The dashboard's Metric alerts section only offers the keys response_time_ms and uptime_percent, which are not heartbeat metrics. Create rules for your own keys through the API. The kamu CLI has no metric rule commands.