Skip to content

Ping (heartbeat) API

The ping (or heartbeat) is what your job sends to say “I ran”. It is an HTTP request to the check’s ping URL, which looks like:

https://app.silencewatch.com/p/<ping-key>

The URL is its own credential: there is no further authentication, so treat it as a secret. If it leaks, rotate it from the check’s page (Rotate ping URL): the old one stops working immediately.

Pings are not part of the /api: they live under /p/ and accept GET and POST, because curl in a crontab is the most common client.

Route Meaning
GET or POST /p/<key> The run succeeded
GET or POST /p/<key>/start The run started (enables duration measurement)
GET or POST /p/<key>/fail The run failed: the check goes down immediately
GET or POST /p/<key>/<code> Exit code: 0 succeeds, anything else fails

A plain success:

Terminal window
curl -fsS -m 10 --retry 3 https://app.silencewatch.com/p/<ping-key>

Start, then result, to measure the duration:

Terminal window
URL=https://app.silencewatch.com/p/<ping-key>
curl -fsS -m 10 --retry 3 "$URL/start"
/usr/local/bin/backup.sh
curl -fsS -m 10 --retry 3 "$URL/$?" # 0 → success, otherwise failure

Duration measured by the client (in milliseconds):

Terminal window
curl -fsS -m 10 --retry 3 "$URL?duration_ms=1234"

Attach the tail of the job’s output (the request body is stored with the ping, truncated if too long, never rejected):

Terminal window
tail -n 20 /var/log/backup.log | curl -fsS -m 10 --retry 3 --data-binary @- "$URL"

Responses are plain text, minimal:

Response Code Meaning
OK 200 Ping recorded
PAUSED 200 The check is paused: the ping is ignored, it is not recorded
NOT FOUND 404 Unknown key
BAD REQUEST 400 Invalid request
RATE LIMITED 429 Too many calls; the Retry-After header says when to retry
UNAVAILABLE 503 Service momentarily unavailable

A mistyped key stays a 404 on purpose: it must never look like success to the script calling it.

Two rate limits apply, both answering 429 with Retry-After. One is per key and bounds a runaway job (120 calls a minute by default). The other is per source address and is spent only by keys that do not exist: a legitimate client never reaches it.