Skip to main content
Scheduled monitor checks work the opposite way from HTTP or TCP monitors: instead of Overwatch probing your infrastructure, your cron job or scheduled task pings Overwatch to say it ran. If Overwatch doesn’t hear from your job within the expected window, it marks the monitor as havent_heard and fires your configured alerts. This lets you detect silent failures — jobs that stop running without throwing any visible errors.

How it works

1

Create a scheduled monitor

Send a POST request to /api/v1/monitors with type: "SCHEDULED". The response includes a checkinUrl unique to that monitor.
2

Add the check-in URL to your job

At the end of your cron job or scheduled task, make an HTTP request to the checkinUrl. A successful request tells Overwatch the job ran.
3

Signal failures when needed

If your job detects an error, append ?status=fail to the check-in URL. Overwatch records the run as failed and fires alerts immediately.

Status values

StatusMeaning
okThe job checked in successfully within the expected window.
failedThe job checked in with ?status=fail, indicating the run encountered an error.
havent_heardThe expected check-in window has passed with no ping received.

Creating a scheduled monitor

curl -X POST https://overwatchapp.dev/api/v1/monitors \
  -H "Authorization: Bearer ow_live_sk_<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nightly report job",
    "type": "SCHEDULED"
  }'
The response includes a checkinUrl field. Save this URL — you’ll call it from your job.
{
  "data": {
    "id": "mon_01hx...",
    "name": "Nightly report job",
    "type": "SCHEDULED",
    "config": {
      "interval": 300
    },
    "status": "unknown",
    "enabled": true,
    "lastCheckIn": null,
    "lastCheckInStatus": null,
    "checkinUrl": "https://overwatchapp.dev/api/v1/monitors/mon_01hx.../checkin",
    "createdAt": "2026-04-15T10:00:00.000Z",
    "updatedAt": "2026-04-15T10:00:00.000Z"
  }
}
The interval for SCHEDULED monitors is always set to 300 seconds (5 minutes). This is the grace window: if Overwatch doesn’t receive a check-in within 5 minutes of the expected time, it marks the monitor as havent_heard. You cannot configure a different interval for this monitor type.

Calling the check-in URL

The check-in endpoint accepts both GET and POST requests and requires no authentication. Call it at the end of your job to record a successful run.
# Record a successful run
curl https://overwatchapp.dev/api/v1/monitors/<id>/checkin

# Record a failed run
curl "https://overwatchapp.dev/api/v1/monitors/<id>/checkin?status=fail"
The endpoint responds with a short confirmation:
{ "recorded": "ok", "monitor": "mon_01hx..." }
Or, for a failure check-in:
{ "recorded": "failure", "monitor": "mon_01hx..." }

Code examples

#!/bin/bash
# Run your job logic here
python /app/scripts/nightly_report.py

# Check in on success
curl -s "https://overwatchapp.dev/api/v1/monitors/mon_01hx.../checkin" > /dev/null

# Example crontab entry (runs at 02:00 every day):
# 0 2 * * * /path/to/run_report.sh
Always call the check-in URL as the very last step in your job, after all work has completed. If your job script exits early due to an error, use a trap (bash) or try/except (Python) to fire a ?status=fail check-in so Overwatch knows the run failed rather than going silent.
The check-in endpoint only accepts requests for monitors that are enabled. If you pause a scheduled monitor, check-in requests return 404 until you re-enable it.