Heartbeat pings
A heartbeat expects a ping at least once per period. If none arrives within the period it goes late; once the grace has passed as well it goes down, and your channels hear about it. The URL is the credential: anyone with it can ping, so keep it out of public logs.
Endpoints
Every endpoint accepts GET and POST, needs no authentication, and never redirects.
| Request | Meaning |
|---|---|
/p/<key> |
The run succeeded. |
/p/<key>/start |
A run started. A later success or failure ends it and records its duration. |
/p/<key>/fail |
The run failed: the heartbeat goes down at once. |
/p/<key>/<code> |
The run ended with this exit code, 0 to 255. 0 is a success; anything else is a failure. |
Add ?rid=<run id> to tie a start to its end when runs overlap. A run id is 1 to 64 of A-Z a-z 0-9 . _ : -.
A POST body is kept with the ping: the first 10 KB of up to 100 KB, shown on the heartbeat’s page. Send the tail of your job’s log and you will know why it failed without logging in to the server.
Responses
Plain text, never cached:
| Status | Body | Meaning |
|---|---|---|
200 |
OK |
Recorded. |
400 |
an explanation | The run id is malformed. |
404 |
not found |
No heartbeat has this key, or the path is not a ping URL. |
413 |
too large |
The body is over 100 KB. |
429 |
rate limited |
Too many pings for this key; Retry-After says when to try again. |
Examples
curl
# At the end of a script
curl -fsS -m 10 --retry 3 https://<your ping host>/p/<key> > /dev/null
crontab
A crontab entry is one line, run by /bin/sh. Put the job and its report in a small script:
#!/bin/sh
# /usr/local/bin/backup-and-report.sh: report the exit code, with the end of the log as the body
/usr/local/bin/backup.sh > /tmp/backup.log 2>&1
code=$?
tail -c 10000 /tmp/backup.log | curl -fsS -m 10 --retry 3 --data-binary @- "https://<your ping host>/p/<key>/$code" > /dev/null
0 3 * * * /usr/local/bin/backup-and-report.sh
Start and finish
RID=$(date +%s)
curl -fsS -m 10 "https://<your ping host>/p/<key>/start?rid=$RID"
./long-job.sh
code=$?
curl -fsS -m 10 "https://<your ping host>/p/<key>/$code?rid=$RID"
GitHub Actions
jobs:
nightly:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./scripts/nightly.sh
- name: Report to Pingwell
if: always()
run: |
if [ "${{ job.status }}" = "success" ]; then path=""; else path="/fail"; fi
curl -fsS -m 10 --retry 3 "https://<your ping host>/p/${{ secrets.PINGWELL_PING_KEY }}$path"