Docs/API

Cron Job Monitoring

Cron job monitors are attached to a monitor in Oh Dear. Each cron job definition gets a unique ping URL that your scheduled tasks call to report their status. This page covers creating, listing, syncing, and snoozing cron job monitors through the API.

You'll need a monitor ID for most of these endpoints.

Example request:

$ OHDEAR_TOKEN="your API token"
$ curl https://ohdear.app/api/monitors/1/cron-checks \
    -H "Authorization: Bearer $OHDEAR_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json'

All endpoints below follow the same authentication pattern.

Cron check response fields #

Every cron job endpoint returns a cron check object with these fields:

{
  "id": 1,
  "uuid": "0d210b09",
  "name": "cronjob number one",
  "type": "simple",
  "description": "a description goes here",
  "frequency_in_minutes": 15,
  "grace_time_in_minutes": 5,
  "cron_expression": null,
  "human_readable_cron_expression": "",
  "server_timezone": "Europe/Brussels",
  "ping_url": "https://ping.ohdear.app/0d210b09",
  "created_at": "2020-07-28 13:27:02",
  "latest_result": "pingFinished",
  "latest_result_label": "ok",
  "latest_result_label_color": "green",
  "latest_ping_at": "2020-11-16 09:19:40",
  "human_readable_latest_ping_at": "5 minutes ago",
  "active_snooze": null
}
  • id: unique identifier for the cron check definition
  • uuid: short UUID used in the ping URL
  • name: name you gave this cron job
  • type: "simple" (frequency-based) or "cron" (crontab expression)
  • description: optional description
  • frequency_in_minutes: for simple type -- how often the job should run
  • grace_time_in_minutes: how long to wait after the expected run time before alerting
  • cron_expression: for cron type -- the crontab expression (e.g., "* * * * *")
  • human_readable_cron_expression: human-readable version of the cron expression
  • server_timezone: timezone for crontab expression evaluation
  • ping_url: the URL your cron job should call to report its status
  • created_at: when this cron check was created (UTC)
  • latest_result: the most recent result (see result types below)
  • latest_result_label: human-readable status label
  • latest_result_label_color: color for the status label
  • latest_ping_at: when we last received a ping (UTC)
  • human_readable_latest_ping_at: relative time since last ping
  • active_snooze: snooze details if active (see checks docs), or null

List cron checks for a monitor #

GET /api/monitors/{monitorId}/cron-checks

Returns all cron job definitions for a monitor. Each item follows the same shape as the cron check object above.

{
  "data": [
    {
      "id": 1,
      "name": "cronjob number one",
      "type": "simple",
      "..."
    },
    {
      "id": 2,
      "name": "cronjob number two",
      "type": "simple",
      "..."
    }
  ]
}

Create a cron check (simple) #

POST /api/monitors/{monitorId}/cron-checks

Creates a new cron job monitor using frequency-based scheduling.

Request body (JSON):

  • name (string, required) -- name for this cron job
  • type (string, required) -- set to "simple" for frequency-based scheduling
  • frequency_in_minutes (integer, required for simple) -- how often the job should run
  • grace_time_in_minutes (integer, required) -- grace period before alerting
  • description (string, optional) -- description for this cron job
{
  "name": "your cron job name",
  "type": "simple",
  "frequency_in_minutes": 10,
  "grace_time_in_minutes": 15,
  "description": "a description goes here"
}

Returns the cron check object including the ping_url you should use in your scripts to report status.

Create a cron check (crontab) #

POST /api/monitors/{monitorId}/cron-checks

Creates a new cron job monitor using a crontab expression.

Request body (JSON):

  • name (string, required) -- name for this cron job
  • type (string, required) -- set to "cron" for crontab expression scheduling
  • cron_expression (string, required for cron) -- the crontab expression (e.g., "* * * * *")
  • grace_time_in_minutes (integer, required) -- grace period before alerting
  • server_timezone (string, required for cron) -- timezone for evaluating the expression (e.g., "UTC")
  • description (string, optional) -- description for this cron job
{
  "name": "your cron job name",
  "type": "cron",
  "cron_expression": "* * * * *",
  "grace_time_in_minutes": 10,
  "description": "a description goes here",
  "server_timezone": "UTC"
}

Returns the cron check object.

Update a cron check #

PUT /api/cron-checks/{cronCheckDefinitionId}

Updates an existing cron job definition. The payload accepts the same fields as creation (name, type, frequency_in_minutes or cron_expression, grace_time_in_minutes, server_timezone, description).

Returns the updated cron check object.

Bulk sync cron checks #

POST /api/monitors/{monitorId}/cron-checks/sync

Synchronizes all cron jobs for a monitor in one call. This is a destructive action -- any cron job not included in the cron_checks array will be removed.

Request body (JSON):

  • cron_checks (array, required) -- array of cron check definitions. Each item uses the same fields as creating a cron check
{
  "cron_checks": [
    {
      "name": "cron job #1",
      "type": "cron",
      "cron_expression": "* * * * *",
      "grace_time_in_minutes": 10,
      "server_timezone": "UTC"
    },
    {
      "name": "cron job #2",
      "type": "cron",
      "cron_expression": "0 * * * *",
      "grace_time_in_minutes": 10,
      "server_timezone": "UTC"
    }
  ]
}

Returns an array of cron check objects.

Snooze a cron check #

POST /api/cron-checks/{cronCheckDefinitionId}/snooze

Temporarily silences notifications for a cron job. See the checks snooze docs for details on snoozing behavior.

Request body (JSON):

  • minutes (integer, required) -- how long to snooze (1 to 144,000)

Returns the cron check object with active_snooze populated.

Unsnooze a cron check #

POST /api/cron-checks/{cronCheckDefinitionId}/unsnooze

Removes the active snooze from a cron check. Returns the cron check object with active_snooze set to null.

Delete a cron check #

DELETE /api/cron-checks/{cronCheckDefinitionId}

Deletes a cron job definition.

Returns 204 No Content on success.

Result types #

The latest_result field can have the following values.

Values your application actively reports via the ping URL:

  • pingStarting: we received the "started" pingback from your application
  • pingFinished: we received the "finished" pingback, indicating no errors occurred
  • pingFailed: we received the "failed" pingback, indicating errors occurred

Values we may detect ourselves:

  • checkRanTooLate: we didn't receive a ping on time, so we marked the task as late
  • pingEndpointDown: Oh Dear's ping endpoint was temporarily unavailable
  • checkFailed: the cron check failed
  • sentCronNotExutedOnTimeNotification: we sent the "did not run on time" notification
  • sentPingFailedNotification: your application reported a failure and we sent a notification
  • cronCheckDefinitionNotRegistered: the cron check definition is not registered
  • cronCheckChanged: the cron check configuration was changed

The only success state is pingFinished -- all other values indicate the job is either pending, failed, or hasn't pinged yet.

Error handling #

If validation fails, you'll get an error response:

{
  "message": "The given data was invalid.",
  "errors": {
    "name": ["There already exist a cron check with this name for this site."]
  }
}
Was this page helpful?

Feel free to reach out via [email protected] or on X via @OhDearApp if you have any other questions. We'd love to help!