Tallyworks Heartbeat

Your job ran. Did it do the work?

Most monitors only ask whether a cron job checked in. Heartbeat also asks how much it did. Add one curl with a count to the end of a job: if it goes quiet, or its numbers look wrong, Slack, Discord or any webhook hears about it.

# nightly backup, expected every 24h
0 3 * * * /usr/local/bin/backup.sh && curl -fsS https://HOST/ping/<token>?n=$(wc -l < /var/log/backup.list)

Open the dashboard → or use the API:

Get started in a minute

# 1. get an API key (free, no email needed; keep it safe, it is your only login)
curl -X POST https://HOST/api/signup

# 2. create a check: expect a ping every hour, alert to Slack
curl -X POST https://HOST/api/checks \
  -H "Authorization: Bearer tw_..." \
  -d '{"name":"hourly-import","period_s":3600,"alert_webhook":"https://hooks.slack.com/..."}'

# 3. ping it from your job (the response contains ping_url)
curl -fsS https://HOST/ping/<token>          # success
curl -fsS https://HOST/ping/<token>/fail     # explicit failure, alert now
curl -fsS https://HOST/ping/<token>?n=1234   # success + tally

Catch jobs that ran but did the wrong amount

The worst failures exit with status 0: the backup with zero files, the import that fetched 40 rows instead of 4,000, the sync that ran twice and sent everything again. Send ?n= with each ping and pick a rule:

Set "min_count": 1 on a check and a run that reports ?n=0 alerts just like a missed one. The backup that "succeeded" with zero files won't go unnoticed.

Set "max_drop_pct": 50 and a run that processes less than half of what the previous run did alerts too: the import that quietly fetched 40 rows instead of 4,000.

Pro: set "detect_anomalies": true and there's nothing to tune. After 8 runs Heartbeat learns what's normal for that job and alerts when a run is far outside it, too low or too high.

API

RequestDoes
GET /api/checksList checks and their status
GET /api/checks/:id/pingsLast 100 pings with counts
POST /api/checks/:id/pause / resumeSilence a check during maintenance
PATCH /api/checks/:idChange name, schedule, webhook or count rules (same fields as create; null clears one). The ping URL stays the same
DELETE /api/checks/:idRemove a check

Plans

Free10 checks, every 5 min or slower, webhook alerts, count rules, last 100 runs
Pro · €6/month100 checks, every minute, anomaly detection on counts. Coming soon; the free plan stays.

How it runs