Ping recipes for every scheduler

Wire a heartbeat ping into crontab, systemd timers, Docker, Kubernetes CronJob, and Windows Task Scheduler — plus when to reach for the Python/.NET SDK instead.

Once you’ve created a heartbeat monitor and have a ping URL, the only thing left is telling whatever runs the job to call that URL when it finishes. This page is a recipe per scheduler/runtime; for the ping call itself in a specific language, see Ping from any language.

Your ping URL looks like https://ping.steadycron.com/<your-ping-token> — find it on the check’s page after creating the monitor.

crontab

Append the ping to the end of the existing cron line — no separate script needed:

*/15 * * * *  /usr/local/bin/your-script.sh && curl -fsS https://ping.steadycron.com/<your-ping-token>

If the script’s own exit code matters (rather than “it ran”), ping /fail on the non-zero branch instead:

*/15 * * * *  /usr/local/bin/your-script.sh && curl -fsS https://ping.steadycron.com/<your-ping-token> || curl -fsS https://ping.steadycron.com/<your-ping-token>/fail

systemd timer

Add ExecStartPost= to the service unit the timer runs — it only fires when ExecStart itself succeeds:

# /etc/systemd/system/your-job.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/your-script.sh
ExecStartPost=/usr/bin/curl -fsS https://ping.steadycron.com/<your-ping-token>

Pair it with a .timer unit as usual (OnCalendar=, WantedBy=timers.target).

Docker

Wrap the container’s entrypoint so the ping only fires on a clean exit:

CMD ["/bin/sh", "-c", "/app/run-job.sh && curl -fsS https://ping.steadycron.com/<your-ping-token>"]

Or, if you’re already scheduling the container itself (e.g. docker run from cron, or a one-shot ECS/Cloud Run task), keep the ping in the surrounding shell script rather than the image so the token isn’t baked into the image.

Kubernetes CronJob

Add the ping as a second command in the same container, chained with && so a failing job never reports success:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: your-job
spec:
  schedule: "*/15 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
            - name: your-job
              image: your-image:latest
              command:
                - /bin/sh
                - -c
                - >
                  /app/run-job.sh &&
                  curl -fsS https://ping.steadycron.com/<your-ping-token>

For stuck-run detection, ping /start in an initContainer and the success URL in the main container — see heartbeat monitoring for what /start unlocks.

Windows Task Scheduler / PowerShell

Chain the ping onto the scheduled script with if ($?), which is true only when the previous command succeeded:

your-script.ps1; if ($?) { curl.exe -fsS https://ping.steadycron.com/<your-ping-token> }

Point the scheduled task’s action at a .ps1 wrapper containing that line (Task Scheduler doesn’t evaluate shell conditionals directly in its “Program/arguments” fields).

Prefer code to shell snippets?

If the job is application code you can import into (not a shell script or someone else’s binary), the Python SDK and .NET SDK wrap the ping calls for you — @steadycron.job("key") or TrackAsync(...) handle start/success/fail automatically, including stuck-run detection, without any curl calls to maintain.

Next steps