Ping API Reference

The ping API is how your cron jobs communicate with SiteVitals. Every monitor gets a unique URL based on an 8-character alphanumeric slug. No authentication headers, cookies or API keys are needed — the slug is the credential.

All ping endpoints are served without middleware (no sessions, no CSRF) to keep latency as low as possible.

Base URL

https://www.sitevitals.co.uk/ping/{slug}

The {slug} is an 8-character alphanumeric string, generated automatically when you create a monitor. You can regenerate it at any time from the monitor dashboard — the old slug stops working immediately.

GET|POST /ping/{slug} — Success

Report that the job completed successfully. This is the primary endpoint you'll use.

What happens

  • Monitor status moves to up
  • last_ping_at is updated to now
  • If a /start was sent beforehand, the runtime is calculated automatically
  • next_expected_at is recalculated based on the schedule
  • If the monitor was previously down, a recovery alert is dispatched
Response: 200 OK
GET|POST /ping/{slug}/start — Start

Signal that the job has begun running. Optional but recommended — it enables automatic runtime calculation and stuck-job detection.

What happens

  • last_started_at is updated to now
  • No status change occurs

If the job subsequently sends a success or failure ping, SiteVitals calculates the duration between start and finish. If neither arrives within the grace period, the monitor can detect the job is stuck.

Response: 200 OK
GET|POST /ping/{slug}/fail — Failure

Report that the job failed. Triggers an alert immediately without waiting for a missed schedule.

What happens

  • Monitor status moves to down
  • last_ping_at is updated to now
  • If a /start was sent beforehand, the runtime is calculated
  • An alert is dispatched (unless the monitor was already down)
Response: 200 OK
POST /ping/{slug}/log — Log

Send a log entry without changing the monitor's status. Useful for appending diagnostic output or intermediate progress from a long-running job.

What happens

  • A log-type ping record is created with the POST body stored as the log content
  • No status change occurs
Response: 200 OK

Optional parameters

You can send metadata with any ping as query parameters (GET) or form fields (POST). All are optional.

Parameter Type Description
runtime float Job execution time in seconds, e.g. 12.345. If omitted and a /start was sent, SiteVitals calculates this automatically.
memory integer Peak memory usage in bytes, e.g. 52428800 for 50 MB.
exit_code integer Process exit code, e.g. 0 for success, 1 for failure.
failure_message string A failure description (up to 100 KB). Compatible with the Oh Dear format.

POST body as log output

If you send a POST request without the runtime, memory or exit_code fields, the raw request body is captured as log output (up to 100 KB, must be valid UTF-8). This is ideal for piping script output directly:

my-script.sh 2>&1 | curl -fsS --data-binary @- https://www.sitevitals.co.uk/ping/{slug}

If any of the structured fields (runtime, memory, exit_code) are present, the body is not captured — use the /log endpoint instead if you need to send both structured data and log output.

Examples

Minimal success ping

curl -fsS --retry 3 https://www.sitevitals.co.uk/ping/aBcDeFgH

Full lifecycle with start, success and metadata

# Signal start
curl -fsS --retry 3 https://www.sitevitals.co.uk/ping/aBcDeFgH/start
# Run the job
/usr/local/bin/my-job.sh
# Signal success with runtime and exit code
curl -fsS --retry 3 "https://www.sitevitals.co.uk/ping/aBcDeFgH?runtime=45.2&exit_code=0&memory=104857600"

Report failure with a message

curl -fsS --retry 3 -d "failure_message=Database connection timed out" \
https://www.sitevitals.co.uk/ping/aBcDeFgH/fail

Pipe script output as log

/usr/local/bin/my-job.sh 2>&1 | curl -fsS --retry 3 --data-binary @- \
https://www.sitevitals.co.uk/ping/aBcDeFgH/log

Python

import
import requests
PING_URL = "https://www.sitevitals.co.uk/ping/aBcDeFgH"
# Signal start
requests.get(f"{'{'}PING_URL{'}'}/start", timeout=5)
try:
result = run_my_job()
requests.get(PING_URL, params={"runtime": result.duration}, timeout=5)
except Exception as e:
requests.post(f"{'{'}PING_URL{'}'}/fail", data={"failure_message": str(e)}, timeout=5)

PHP (Laravel scheduled command)

$this->command('backup:run');
Http::timeout(5)->retry(3)->get("https://www.sitevitals.co.uk/ping/aBcDeFgH");

Error responses

Status Meaning
200 OK Ping recorded successfully.
404 Not Found The slug does not match any enabled monitor. Either the slug is wrong, the monitor has been deleted, or it is paused.

The ping endpoints are intentionally simple — they return plain text, not JSON, and carry no cookies or headers beyond the basics.