Skip to main content

Heartbeat Monitoring

Heartbeat monitors invert the usual monitoring model — instead of AlertifyPro probing your service, your service calls AlertifyPro. If we don't hear from it within the expected window, we alert you.

How it works

  1. You create a heartbeat monitor in AlertifyPro → it gets a unique key
  2. Your job/script calls POST /api/v1/heartbeat/{unique_key} after completing successfully
  3. AlertifyPro records the ping and marks the monitor healthy
  4. If no ping arrives within schedule + grace_period, an alert fires

Creating a heartbeat monitor

POST /api/v1/heartbeats
Authorization: Bearer <token>
Content-Type: application/json

{
"name": "Nightly DB Backup",
"schedule": "every 24h",
"grace_period_seconds": 300
}

Fields:

FieldTypeDefaultDescription
namestringrequiredDisplay name
schedulestring"every 1h"Expected frequency (e.g. "every 6h", "every 24h")
grace_period_secondsint300 (5 min)Extra time before alerting after the window passes

Response (201 Created):

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Nightly DB Backup",
"schedule": "every 24h",
"grace_period_seconds": 300,
"unique_key": "nightly-db-backup-a1b2c3d4",
"status": "healthy"
}

The unique_key is generated as {name-slug}-{8-char-hex} — e.g. nightly-db-backup-a1b2c3d4.


Sending a ping

Your job calls this public endpoint after completing successfully. No authentication required.

POST /api/v1/heartbeat/{unique_key}

A 200 OK response confirms the ping was recorded:

{
"status": "ok",
"monitor": "Nightly DB Backup",
"pinged_at": "2026-03-02T02:01:33Z"
}

Integration examples

Shell / Cron

#!/bin/bash
# /etc/cron.daily/db-backup

# Run your backup
pg_dump mydb > /backups/mydb-$(date +%Y%m%d).sql.gz

# Ping AlertifyPro on success only
if [ $? -eq 0 ]; then
curl -s -X POST http://localhost:3001/api/v1/heartbeat/nightly-db-backup-a1b2c3d4
fi

Node.js

import axios from 'axios';

async function runDailyJob() {
try {
await doWork(); // your job logic
// Ping on success
await axios.post(
'http://localhost:3001/api/v1/heartbeat/nightly-db-backup-a1b2c3d4'
);
} catch (err) {
console.error('Job failed:', err);
// No ping sent → alert fires after grace period
}
}

Python

import requests

def run_job():
try:
do_work() # your job logic
requests.post(
"http://localhost:3001/api/v1/heartbeat/nightly-db-backup-a1b2c3d4",
timeout=5
)
except Exception as e:
print(f"Job failed: {e}")
# No ping = alert fires after grace period

GitHub Actions

- name: Run sync job
run: python sync.py

- name: Ping AlertifyPro
if: success()
run: curl -s -X POST ${{ secrets.WK_HEARTBEAT_URL }}

Manage heartbeat monitors

# List all heartbeat monitors for your org
GET /api/v1/heartbeats

# Delete a heartbeat monitor
DELETE /api/v1/heartbeats/{id}

What the ping records

AlertifyPro stores:

  • The user_agent of the pinging process
  • pinged_at timestamp
  • The HTTP metadata sent with the ping

Arbitrary metadata is accepted in the request body — it's recorded alongside the ping for debugging context.