Pinging
Jobs report to Checkpulse with plain HTTP requests. Pings need no API key: the URL itself is the secret, so keep it out of public logs and repositories, and rotate it if it leaks.
Ping URLs
Every check has two URLs:
| Form | Example |
|---|---|
| Token URL | https://checkpulse.foo/ping/<64-character token> |
| Slug URL | https://checkpulse.foo/ping/<project ping key>/<check slug> |
Slug URLs use one key per project, which makes it easy to template many jobs. Find the ping key under Project settings. Rotating it changes every slug URL in the project; rotating a check's token changes only that check's token URL.
Signals
Append a signal to either URL:
| Path | Meaning |
|---|---|
(none) or /0 | Success. The check is up and the next deadline starts now. |
/start | The run started. If no finish arrives within the grace period, the check goes down. |
/fail | Failure. The check goes down immediately. |
/1 … /255 | Exit status. Non-zero fails the check and is recorded on the incident. |
/log | Records a message without changing the status or the last-ping time. |
A start never hides an existing failure: only a success recovers a check that is down.
Methods and output
Send GET, HEAD, or POST. To attach output, POST it in the body. Checkpulse keeps the first 4 KB and marks longer output as truncated; the ping still counts.
Set a check to POST only to ignore GET and HEAD requests from link previews and email scanners. Those requests receive HTTP 405.
Failure keywords turn a success ping into a failure when its output contains any keyword (case-insensitive), for example ERROR, Traceback.
Run IDs
When runs can overlap, add ?rid=<id> (letters, digits, ., _, :, -; up to 64 characters) to the start and finish pings of the same run. Checkpulse then pairs them to measure each run's duration, and finishing one run does not clear another run's deadline. checkpulse-run does this automatically.
Creating checks on first ping
Add ?create=1 to a slug URL to create the check if it does not exist yet:
curl -fsS -m 10 --retry 3 "https://checkpulse.foo/ping/$PING_KEY/nightly-backup?create=1"
The new check is named after its slug, expects a ping every day with a one-hour grace period, and sends alerts to every channel in the project. Adjust its schedule afterwards in the dashboard, the API, or MCP. Account check limits apply. Without create=1, unknown slugs return 404.
Responses
| Status | Meaning |
|---|---|
| 200 | Recorded. |
| 201 | Recorded, and the check was created by ?create=1. |
| 400 | Unknown signal or invalid run ID. |
| 403 | The account's check limit prevents creating the check. |
| 404 | Unknown URL, or the check is deleted. |
| 405 | The check only accepts POST. |
| 429 | More pings than the check allows per minute (10 on free accounts). Retry after a minute. |
Pausing
Pausing a check stops alerts while pings are still recorded. By default the next ping resumes the check; turn on keep paused until resumed by hand to prevent that. A resumed check waits for its next ping like a new check, so it never reports a recovery that did not happen. For planned maintenance, silences are usually better because they end on their own.
Examples
Shell, with the exit status:
URL="https://checkpulse.foo/ping/<token>"
curl -fsS -m 10 --retry 3 -o /dev/null "$URL/start"
/usr/local/bin/backup.sh > /tmp/backup.log 2>&1
status=$?
curl -fsS -m 10 --retry 3 -o /dev/null --data-binary @/tmp/backup.log "$URL/$status"
If the script uses set -e, capture the status explicitly as above so the failure is still reported.
Python:
import urllib.request
urllib.request.urlopen("https://checkpulse.foo/ping/<token>", data=b"42 rows exported", timeout=10)
PowerShell:
Invoke-RestMethod -Method Post -Uri "https://checkpulse.foo/ping/<token>/$LASTEXITCODE"