Skip to content

Heartbeat monitor

Heartbeat monitors flip the usual model. Instead of PathWatch calling your service, your service calls PathWatch on a schedule. If the ping doesn’t arrive within the expected window, the monitor flips to down and your normal alerting fires.

Use it for things PathWatch can’t reach from outside: cron jobs, batch workers, scheduled Lambdas, queue consumers, backup scripts.

How it works

  1. Create a heartbeat monitor in the WebUI. PathWatch issues a unique URL: https://api.pathwatch.app/heartbeat/<token>.
  2. Add a curl (or any HTTP client) to the end of your job pointing at that URL.
  3. The monitor expects a ping every N seconds. If `now - last_ping

    expected_interval + grace_period, the monitor is down` and alerts fire through whatever rules you’ve attached.

The token is monitor-scoped — exposing it lets anyone ping that specific monitor (a minor inconvenience, not a security issue). Tokens can be rotated from the monitor settings.

Configuration

FieldTypeDefaultNotes
Expected intervalsecondsHow often you intend to ping. Minimum 60 s. Required.
Grace periodseconds0Tolerance on top of the interval before going down. Set this to your job’s worst-case duration.
Failure statusenumdownWhat status the monitor reports when a ping is missed. degraded if a missed cron isn’t a full outage.
Payload rulesarray[]Optional. Inspect the JSON body of each ping and alert on the contents (see below). Max 20 rules.

Pinging the endpoint

Any HTTP method works. GET is the simplest:

Terminal window
curl -fsS https://api.pathwatch.app/heartbeat/<token>

For richer signals, POST JSON with metrics or state:

Terminal window
curl -fsS -X POST \
-H 'Content-Type: application/json' \
-d '{"records_processed": 1247, "duration_ms": 31200, "status": "ok"}' \
https://api.pathwatch.app/heartbeat/<token>

Form-encoded bodies and query parameters on GET are also accepted. Per-token rate limit: 1 ping per 5 seconds. Body cap: 16 KB.

Payload rules

If you POST JSON, you can have PathWatch assert on the contents. Each rule targets a field (dot-notation for nested values) and runs one operator against it. If any rule fails, the check is down (or degraded if the rule’s status is set that way).

OperatorCompares against
equals / not_equalsA single string, number, or boolean
greater_than / less_thanA number
between / not_betweenTwo numbers — inclusive range
one_of / not_one_ofAn array of strings or numbers

Example: alert if a worker’s queue depth crosses a threshold:

{
"field": "queue_depth",
"operator": "less_than",
"value": 10000,
"label": "Queue depth under 10k",
"status": "degraded"
}

A failed rule’s label (or the field name if no label) appears in the alert message so the responder knows which assertion fired.

Status mapping

OutcomeStatus
Ping arrives inside expected_interval + grace_period, all payload rules passup
Ping arrives but a payload rule with status: "degraded" failsdegraded
Ping arrives but a payload rule with status: "down" failsdown
No ping arrives within the windowdown (or degraded if failure_status: "degraded")

Common patterns

Cron jobscurl at the end of the script. Set the interval to your cron cadence and the grace period to your worst-case job runtime.

Long-running jobs that report mid-flight — POST progress metrics periodically. Use payload rules to alert on stalls (progress_percent not advancing, error_count > 0).

Backups — POST {"bytes_written": N, "duration_ms": M} so both the “did it run” and “did it finish what we expect” questions are covered by a single monitor.

Worker queues — set expected_interval to the worker’s poll interval. If the worker dies, the monitor goes down within one interval + grace.