A first check in three steps
- Create a free account by entering your email and using the single-use sign-in link, which expires in 20 minutes. This verifies your account email for alerts. Your private access link is an optional backup.
- Create a check. Choose an interval or cron expression, grace period and alert channels.
- Set PING_URL to the private URL from your check and use this shell wrapper. Replace the backup command.
#!/bin/sh
# PING_URL is the private URL copied from your check.
: "${PING_URL:?Set PING_URL first}"
rid="$(date +%s)-$$"
report() { curl -fsS -m 10 --retry 3 "$PING_URL/$1?rid=$rid" >/dev/null 2>&1 || :; }
trap 'code=$?; report "$code"; exit "$code"' EXIT
report start
sleep 1
/usr/local/bin/backup.sh
The example waits one second after start so a short job’s completion is not swallowed by the per-check rate guard. For a minimal completion-only integration, use:
your-command
code=$?
curl -fsS -m 10 --retry 3 "$PING_URL/$code" || :
exit "$code"Ping API
GET, POST and HEAD work. Each accepted ping responds 200 with text OK (HEAD has no body). Unknown keys return 404. CORS permits all origins. Ping URLs are secrets: anyone holding one can update the check.
/p/KEY: success; arms the next deadline./p/KEY/start: records a start; does not arm or extend the completion deadline./p/KEY/fail: immediate failure./p/KEY/0through/p/KEY/255: exit code, 0 succeeds and every other value fails./p/KEY/log: logs without changing status.?rid=RUN_ID: use the same run ID for start and completion to record duration. Only one in-flight start is tracked per check.
Deadlines and rate guard
New checks stay unarmed until the first success. Period checks expect another success at completion time + period. Cron checks expect the next calendar match after completion. Grace is added to that deadline. The single minute sweep marks overdue checks down. State changes and delivery jobs are recorded together. Each invocation delivers at most five queued channel messages; unusually large bursts can take longer than the usual 1–2 minutes. Failed pings mark down immediately; recovery sends once.
Only one ping per second per check is accepted; additional pings return OK with no log or state update. Leave at least one second between start and finish, or use completion-only pings for quick tasks. Paused checks still log but never arm or alert. Resume starts a fresh deadline if the check previously succeeded.
Cron and time zones
Five fields: minute, hour, day-of-month, month, day-of-week. Lists, ascending ranges, steps, JAN–DEC and SUN–SAT names are supported. Sunday is 0 or 7; ? means *. Macros: @yearly, @annually, @monthly, @weekly, @daily, @midnight, @hourly. L, W, # and seconds fields are rejected.
When day-of-month and day-of-week are both restricted they match with OR (Vixie semantics). IANA time zones use Intl: skipped local times fire at the next valid minute and repeated wall times fire once. Other schedulers may differ; use UTC when consistency matters. No matching date in eight years is rejected. Preview an expression.
Alerts, retries and retention
Link channels to each check explicitly. Slack, Discord, Telegram and public HTTPS webhooks use a five-second delivery timeout. Failed deliveries get two retries (three attempts total). A once-minute trigger also drives retries; failures and results appear in check history. Email alerts go only to your own verified account email. Verify it by signing in once through an emailed link. Chat channels and webhooks can send to other destinations.
Free keeps the last 100 pings per check; Pro and Team keep 1,000. Only paid plans capture the first 1 KB of POST bodies. Never send secrets. Logs are entry-count limited, not time based. Alerts are capped to the most recent 100 in the dashboard.
Account API
The dashboard API uses a signed-in session cookie. A separate infrastructure API key is not available. Browser mutations must have the same Origin.
GET, POST /api/checks
GET, PATCH, DELETE /api/checks/ID
POST /api/checks/ID/pause
POST /api/checks/ID/resume
GET /api/checks/ID/pings
GET, POST /api/channels
DELETE /api/channels/ID
POST /api/channels/ID/test
GET /api/usage
GET /api/account/export
DELETE /api/account{
"name": "Backup",
"kind": "cron",
"cron_expr": "0 2 * * *",
"tz": "Europe/Dublin",
"grace_sec": 600,
"channels": []
}PATCH accepts name, kind, period_sec (60–31536000), cron_expr, tz, grace_sec (0–604800), tags, desc and channels (up to 50 owned channel IDs). Check and channel IDs are UUIDs. Plan limits return 409; invalid input 400; missing/other-account resources 404; signed-out requests 401.