On this page

Job monitoring

Alerts when a scheduled job did not run, failed or ran too long: pg_cron jobs, background jobs, and cron jobs anywhere else that call a ping URL.

LimitFreeProScaleEnterprise
Job monitors per project5502001,000
Job monitoring run history7 days30 days90 days90 days

Job monitoring tells you when a job that should run on a schedule did not: a nightly backup, an export, a billing run, a sync. Each monitor knows when the next run is expected; when none comes in time, or a run fails or takes too long, you get an alert by e-mail, webhook or Telegram, and a notice when it works again. The checks run every 30 seconds on your project’s own server, and every run is kept in a history with its duration and message.

#Set it up

  1. Open Studio › Job monitoring and click Turn on job monitoring.
  2. Click Add monitor and choose what to watch (below), when it should run and how late it may be (the grace period, 5 minutes by default).
  3. A monitor sends nothing before its first run, so adding one for a job that is not running yet is safe.

#What a monitor can watch

  • pg_cron job: one of your project’s named cron jobs. Nothing to change in the job: its runs, results and error messages are read from pg_cron within a minute, and the monitor follows the job’s own schedule (in UTC), also when you change it.
  • Background job: a background job by its name. Finished runs count; a failed run (after its retries) is a failure. Set the schedule you start it on.
  • Ping URL: anything else: a crontab line on your server, a GitHub Actions schedule, a worker, a script on a laptop. The job calls the monitor’s secret URL when it runs.

#The ping URL

Every ping monitor has its own URL. It needs no API key: the URL is the secret, so keep it out of public code, and make a new one in Studio if it leaks (the old one stops working at once).

Text
https://<project-ref>.p.stitchdb.com/heartbeat/v1/hb_…          it ran and worked
https://<project-ref>.p.stitchdb.com/heartbeat/v1/hb_…/start    it started (optional)
https://<project-ref>.p.stitchdb.com/heartbeat/v1/hb_…/fail     it failed
https://<project-ref>.p.stitchdb.com/heartbeat/v1/hb_…/<code>   the exit code: 0 worked, anything else failed

GET, POST and HEAD all work. The body of a POST (up to 2 KB, for example the last lines of the job’s log) is kept as the run’s message and shown in the alert; passwords, tokens and e-mail addresses in it are removed first. Call /start when the job starts to see how long each run takes and to get an alert when a run takes longer than the longest run you set. At most 30 calls a minute per monitor.

# run the backup at 03:00 and report its exit code
0 3 * * * /usr/local/bin/backup.sh; curl -fsS -m 10 --retry 3 https://<project-ref>.p.stitchdb.com/heartbeat/v1/hb_…/$?

#Schedules and grace periods

A monitor expects a run either on a cron schedule (five fields, in the time zone you choose, for example 0 3 * * * in Europe/Berlin; @daily and @hourly work too) or every so many minutes, hours or days. The next run is expected at the next scheduled time after the last run started; a run up to 30 seconds early counts for its own slot. If no run has come by then plus the grace period, the run is missed.

#Alerts

  • Missed: no run came in time. One alert when the monitor goes down; while it stays down, each further expected run is added to the history as missed, without more alerts.
  • Failed: a run reported a failure (/fail, a non-zero exit code, a failed pg_cron run or background job). One alert until a run works again.
  • Running too long: a run that started has not ended after the longest run you set. Once per run.
  • Back to normal: the first run that works after a miss or a failure (turn these off in the settings if you do not want them).

Alerts go by e-mail to the project owner, to the project’s webhooks (events monitor.down, monitor.failed, monitor.long and monitor.recovered) and, if you add a bot, to a Telegram chat. At most 30 alerts per project an hour; Send a test alert checks the setup. Pause a monitor during maintenance: paused monitors are not checked, and when you resume, the next run is expected from then on.

JSON
{
  "type": "monitor.failed",
  "record": {
    "monitor_id": 3, "name": "Nightly backup", "kind": "ping", "alert": "failed", "state": "failed",
    "last_run_at": "2026-10-26T03:00:12Z", "last_message": "pg_dump: connection refused",
    "url": "https://stitchdb.com/dashboard/project/<project-ref>/monitors/3"
  }
}

#Read monitors from code

With the service key, list the monitors with their state, or one monitor with its runs, for your own dashboards or an AI agent that checks production:

bash
curl https://<project-ref>.p.stitchdb.com/heartbeat/v1/monitors \
  -H "apikey: $STITCHDB_SERVICE_KEY" -H "Authorization: Bearer $STITCHDB_SERVICE_KEY"

curl "https://<project-ref>.p.stitchdb.com/heartbeat/v1/monitors/3?limit=50" \
  -H "apikey: $STITCHDB_SERVICE_KEY" -H "Authorization: Bearer $STITCHDB_SERVICE_KEY"

Monitors and runs are stored in your project’s database (schema _stitch_heartbeat); the history is kept for your plan’s number of days. Turning job monitoring off stops the checks and makes the ping URLs answer 404; monitors and history are kept until you turn it on again.