Ping from any language

Copy-paste snippets to ping a SteadyCron heartbeat URL on success and failure — Bash, Python, Node.js, PHP, Ruby, Go, PowerShell, Docker, and systemd.

A heartbeat check is just a URL you request when your job runs. Copy a snippet below, replace <your-ping-token>, and you’re monitored. On success, ping the base URL; on failure, ping /fail; optionally ping /start first so stuck runs are detected.

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

curl (one-liner)

curl -fsS -m 10 --retry 3 https://ping.steadycron.com/<your-ping-token>

-f fails on HTTP errors, -s is silent, -m 10 caps the time, --retry 3 survives a brief network blip.

Bash (start / success / fail)

#!/usr/bin/env bash
set -euo pipefail
TOKEN=<your-ping-token>
PING="https://ping.steadycron.com/$TOKEN"

curl -fsS -m 10 "$PING/start"            # job started

if ./run-job.sh; then
  curl -fsS -m 10 "$PING"                # success
else
  curl -fsS -m 10 "$PING/fail"           # explicit failure
fi

Wrap any command

Ping /fail automatically if the command exits non-zero — no edits to the job itself:

TOKEN=<your-ping-token>
PING="https://ping.steadycron.com/$TOKEN"
./run-job.sh && curl -fsS "$PING" || curl -fsS "$PING/fail"

Python

import subprocess
import urllib.request

TOKEN = "<your-ping-token>"
PING = f"https://ping.steadycron.com/{TOKEN}"

def ping(suffix=""):
    try:
        urllib.request.urlopen(PING + suffix, timeout=10)
    except Exception:
        pass  # never let monitoring break the job

ping("/start")
try:
    subprocess.run(["./run-job.sh"], check=True)
    ping()           # success
except subprocess.CalledProcessError:
    ping("/fail")    # failure

Node.js

const TOKEN = "<your-ping-token>";
const PING = `https://ping.steadycron.com/${TOKEN}`;

const ping = (suffix = "") =>
  fetch(PING + suffix, { signal: AbortSignal.timeout(10_000) }).catch(() => {});

await ping("/start");
try {
  await runJob();
  await ping();          // success
} catch {
  await ping("/fail");   // failure
}

PHP

<?php
$token = "<your-ping-token>";
$ping  = "https://ping.steadycron.com/$token";

function ping(string $url): void {
    @file_get_contents($url, false, stream_context_create([
        "http" => ["timeout" => 10, "ignore_errors" => true],
    ]));
}

ping("$ping/start");
$exit = 0;
system("./run-job.sh", $exit);
ping($exit === 0 ? $ping : "$ping/fail");

Ruby

require "net/http"

token = "<your-ping-token>"
ping  = "https://ping.steadycron.com/#{token}"

def hit(url) = Net::HTTP.get_response(URI(url)) rescue nil

hit("#{ping}/start")
if system("./run-job.sh")
  hit(ping)          # success
else
  hit("#{ping}/fail")
end

Go

package main

import (
	"net/http"
	"os/exec"
	"time"
)

const ping = "https://ping.steadycron.com/<your-ping-token>"

func hit(suffix string) {
	c := &http.Client{Timeout: 10 * time.Second}
	if resp, err := c.Get(ping + suffix); err == nil {
		resp.Body.Close()
	}
}

func main() {
	hit("/start")
	if err := exec.Command("./run-job.sh").Run(); err == nil {
		hit("") // success
	} else {
		hit("/fail")
	}
}

PowerShell (Windows / Scheduled Tasks)

$token = "<your-ping-token>"
$ping  = "https://ping.steadycron.com/$token"

function Ping($url) { try { Invoke-WebRequest -UseBasicParsing -TimeoutSec 10 $url | Out-Null } catch {} }

Ping "$ping/start"
& ".\run-job.ps1"
if ($LASTEXITCODE -eq 0) { Ping $ping } else { Ping "$ping/fail" }

Docker healthcheck

HEALTHCHECK --interval=5m --timeout=10s \
  CMD curl -fsS https://ping.steadycron.com/<your-ping-token> || exit 1

systemd timer

Add an ExecStartPost / ExecStopPost to the service your timer runs:

[Service]
Type=oneshot
ExecStart=/usr/local/bin/run-job.sh
ExecStartPost=/usr/bin/curl -fsS https://ping.steadycron.com/<your-ping-token>

Next steps