One ping says "I am alive". Three signals tell you when the job started, how it ended and how long it took.
| Address | Meaning | Status after |
|---|---|---|
/<uuid> | success | up |
/<uuid>/start | the job started | unchanged |
/<uuid>/fail | explicit failure | down immediately |
/<uuid>/<code> | exit status 0–255 | 0 is up, anything else is down |
/<uuid>/log | journal entry | unchanged |
A POST body (up to 100 KB) is stored in the ping log — a handy place for the tail of a log, so an incident can be triaged without logging into the server.
The execution duration chart on the check page is built
only from pairs: /start,
then a success or an exit code. The gap between them is the
runtime.
The consequence worth knowing. If you only send the
success ping and never /start,
the check works perfectly well — statuses, alerts and uptime
are all there — but the duration chart stays empty: there is
nothing to subtract. Milliseconds only exist for runs that
had a start.
# no duration: the service knows it ran, not how long it took /usr/local/bin/backup.sh && curl -fsS -m 10 "$PING" # with duration curl -fsS -m 10 "$PING/start" /usr/local/bin/backup.sh curl -fsS -m 10 "$PING/$?"
Pairs are matched in arrival order. If the job can run in several instances at once, durations blend together — such cases deserve separate checks.
The usual route to down is silence: deadline, then grace, then the alert. An explicit failure signal skips all of it — the check drops the moment the ping lands.
/fail — "the job reported an error";/<code> — the exit status: 0 counts as success, anything else drops the check. The alert reason reads "non-zero exit status".
The second form is friendlier in a shell: the exit code of
the last command already sits in $?,
no branching required. In systemd the same role is played by
$EXIT_STATUS inside
ExecStopPost — see the
snippets.
signal() { curl -fsS -m 10 --retry 3 -o /dev/null "$PING$1" || true; }
signal /start
/usr/local/bin/backup.sh
signal "/$?" /log writes a line into the
journal without touching the status or the deadline. Useful
for milestones inside a long run: "exported 10,000 rows",
"switched to the fallback source".
Creating checks by hand is optional. Ping by slug — a
readable name instead of a UUID — with
?create=1, and the check appears
on first contact. Handy when jobs are rolled out by a deploy
and you do not know up front how many there will be.
https://ping.cronalive.com/<ping-key>/<slug>?create=1
ping-key is the project key
(Projects → Ping key in the dashboard), shared by all
of its checks; slug is the job
name in lower case, for example
etl-run. The schedule of the new
check comes from the query parameters:
| Parameter | Value |
|---|---|
period | period in seconds, 60–31536000 |
grace | grace in seconds, 0–2592000 |
cron | a cron expression instead of a period |
tz | time zone for cron, UTC by default |
# a plain period curl "https://ping.cronalive.com/<ping-key>/etl-run?create=1&period=3600&grace=300" # a cron expression with a time zone (plus signs instead of spaces) curl "https://ping.cronalive.com/<ping-key>/backup?create=1&cron=30+3+*+*+*&tz=Europe/Moscow"
Rules worth knowing in advance:
create=1 and the schedule parameters are ignored — the ping simply counts. Change the schedule in the dashboard or through the API;/<ping-key>/etl-run/start?create=1;