Cron Jobs

Create and manage cron job monitors, and record pings from your scheduled jobs.

Last updated: 2026-09-05

Cron job monitors track scheduled tasks by receiving pings when jobs complete. If a ping is not received within the expected window, the job is marked as late and alerts are triggered.

GET /api/v1/cron-jobs

Returns the cron job monitors for your team. This endpoint is paginated; see Pagination for how to page through the full list.

Required Scope

cron-jobs:read

Query Parameters

ParameterTypeRequiredDescription
perPageintegerNoResults per page, 1-200 (default: 50)
cursorstringNoPage to fetch, taken from a Link header

Example Request

cURL

curl "https://uptime.sergiodxa.com/api/v1/cron-jobs?perPage=25" \
  -H "Authorization: Bearer uptime_your_api_key"

Response

{
	"data": {
		"cronJobs": [
			{
				"id": "cron_abc123",
				"name": "Daily Backup",
				"description": "Runs database backup every night",
				"cronExpression": "0 2 * * *",
				"gracePeriodSeconds": 300,
				"timezone": "America/New_York",
				"status": "healthy",
				"alertOnLate": true,
				"lastPingAt": 1771052412000,
				"nextExpectedAt": 1771138800000,
				"enabledAt": 1768055400000,
				"createdAt": 1768055400000,
				"updatedAt": 1770282900000
			}
		]
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z",
		"pagination": {
			"next": "eyJkIjoiYWZ0ZXIi",
			"prev": null,
			"perPage": 25,
			"total": 34
		}
	}
}

The cursors for this page arrive in meta.pagination:

FieldTypeDescription
meta.pagination.nextstring | nullCursor for the following page, null on the last
meta.pagination.prevstring | nullCursor for the preceding page, null on the first
meta.pagination.perPageintegerResults this page was built with
meta.pagination.totalintegerCron jobs matching, across every page

Possible Errors

StatusCodeDescription
400BAD_REQUESTInvalid or malformed cursor
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key doesn't have cron-jobs:read scope
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORServer error

Response Schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"required": ["data", "meta"],
	"properties": {
		"data": {
			"type": "object",
			"required": ["cronJobs"],
			"properties": {
				"cronJobs": {
					"type": "array",
					"items": { "$ref": "#/$defs/cronJob" }
				}
			}
		},
		"meta": {
			"type": "object",
			"required": ["requestId", "timestamp"],
			"properties": {
				"requestId": { "type": "string", "format": "uuid" },
				"timestamp": { "type": "string", "format": "date-time" },
				"pagination": {
					"type": "object",
					"required": ["next", "prev", "perPage"],
					"properties": {
						"next": { "type": ["string", "null"] },
						"prev": { "type": ["string", "null"] },
						"perPage": { "type": "integer" },
						"total": { "type": "integer" }
					}
				}
			}
		}
	},
	"$defs": {
		"cronJob": {
			"type": "object",
			"required": [
				"id",
				"name",
				"description",
				"cronExpression",
				"gracePeriodSeconds",
				"timezone",
				"status",
				"alertOnLate",
				"lastPingAt",
				"nextExpectedAt",
				"enabledAt",
				"createdAt",
				"updatedAt"
			],
			"properties": {
				"id": { "type": "string", "pattern": "^cron_[a-zA-Z0-9]+$" },
				"name": { "type": "string", "minLength": 1, "maxLength": 100 },
				"description": { "type": ["string", "null"], "maxLength": 500 },
				"cronExpression": { "type": "string" },
				"gracePeriodSeconds": { "type": "integer", "minimum": 60, "maximum": 86400 },
				"timezone": { "type": "string" },
				"status": { "type": "string", "enum": ["healthy", "late", "missed", "new"] },
				"alertOnLate": { "type": "boolean" },
				"lastPingAt": { "type": ["integer", "null"] },
				"nextExpectedAt": { "type": ["integer", "null"] },
				"enabledAt": { "type": ["integer", "null"] },
				"createdAt": { "type": "integer" },
				"updatedAt": { "type": "integer" }
			}
		}
	}
}

POST /api/v1/cron-jobs

Creates a new cron job monitor.

Required Scope

cron-jobs:write

Request Body

FieldTypeRequiredDescription
namestringYesDisplay name (1-100 characters)
cronExpressionstringYesValid cron expression (e.g., 0 * * * *)
descriptionstringNoOptional description (max 500 characters)
gracePeriodSecondsintegerNoSeconds to wait before marking late (60-86400, default 300)
timezonestringNoIANA timezone, or UTC (default UTC). Any other value is rejected with VALIDATION_ERROR.
alertOnLatebooleanNoSend alerts when job is late (default false)
enabledbooleanNoWhether the monitor is active (default true)

Example Request

cURL

curl -X POST https://uptime.sergiodxa.com/api/v1/cron-jobs \
  -H "Authorization: Bearer uptime_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Daily Backup",
    "cronExpression": "0 2 * * *",
    "description": "Runs database backup every night",
    "gracePeriodSeconds": 600,
    "timezone": "America/New_York",
    "alertOnLate": true
  }'

Response

{
	"data": {
		"id": "cron_abc123",
		"name": "Daily Backup",
		"description": "Runs database backup every night",
		"cronExpression": "0 2 * * *",
		"gracePeriodSeconds": 600,
		"timezone": "America/New_York",
		"status": "unknown",
		"alertOnLate": true,
		"lastPingAt": null,
		"nextExpectedAt": "2026-02-15T07:00:00Z",
		"enabledAt": "2026-02-14T15:30:00Z",
		"createdAt": "2026-02-14T15:30:00Z",
		"updatedAt": "2026-02-14T15:30:00Z"
	}
}

Possible Errors

StatusCodeDescription
400VALIDATION_ERRORInvalid request body or cron expression
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key doesn't have cron-jobs:write scope
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORServer error

Request Body Schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"required": ["name", "cronExpression"],
	"properties": {
		"name": { "type": "string", "minLength": 1, "maxLength": 100 },
		"cronExpression": { "type": "string" },
		"description": { "type": "string", "maxLength": 500 },
		"gracePeriodSeconds": { "type": "integer", "minimum": 60, "maximum": 86400, "default": 300 },
		"timezone": { "type": "string", "default": "UTC" },
		"alertOnLate": { "type": "boolean", "default": false },
		"enabled": { "type": "boolean", "default": true }
	}
}

Response Schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"required": ["data"],
	"properties": {
		"data": { "$ref": "#/$defs/cronJob" }
	},
	"$defs": {
		"cronJob": {
			"type": "object",
			"required": [
				"id",
				"name",
				"description",
				"cronExpression",
				"gracePeriodSeconds",
				"timezone",
				"status",
				"alertOnLate",
				"lastPingAt",
				"nextExpectedAt",
				"enabledAt",
				"createdAt",
				"updatedAt"
			],
			"properties": {
				"id": { "type": "string", "pattern": "^cron_[a-zA-Z0-9]+$" },
				"name": { "type": "string", "minLength": 1, "maxLength": 100 },
				"description": { "type": ["string", "null"], "maxLength": 500 },
				"cronExpression": { "type": "string" },
				"gracePeriodSeconds": { "type": "integer", "minimum": 60, "maximum": 86400 },
				"timezone": { "type": "string" },
				"status": { "type": "string", "enum": ["healthy", "late", "missed", "new"] },
				"alertOnLate": { "type": "boolean" },
				"lastPingAt": { "type": ["string", "null"], "format": "date-time" },
				"nextExpectedAt": { "type": ["string", "null"], "format": "date-time" },
				"enabledAt": { "type": ["string", "null"], "format": "date-time" },
				"createdAt": { "type": "string", "format": "date-time" },
				"updatedAt": { "type": "string", "format": "date-time" }
			}
		}
	}
}

GET /api/v1/cron-jobs/:id

Returns a single cron job monitor by ID.

Required Scope

cron-jobs:read

Example Request

cURL

curl https://uptime.sergiodxa.com/api/v1/cron-jobs/cron_abc123 \
  -H "Authorization: Bearer uptime_your_api_key"

Response

{
	"data": {
		"id": "cron_abc123",
		"name": "Daily Backup",
		"description": "Runs database backup every night",
		"cronExpression": "0 2 * * *",
		"gracePeriodSeconds": 600,
		"timezone": "America/New_York",
		"status": "healthy",
		"alertOnLate": true,
		"lastPingAt": "2026-02-14T07:00:12Z",
		"nextExpectedAt": "2026-02-15T07:00:00Z",
		"enabledAt": "2026-01-10T14:30:00Z",
		"createdAt": "2026-01-10T14:30:00Z",
		"updatedAt": "2026-02-01T09:15:00Z"
	}
}

Possible Errors

StatusCodeDescription
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key doesn't have cron-jobs:read scope
404NOT_FOUNDCron job not found
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORServer error

Response Schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"required": ["data"],
	"properties": {
		"data": { "$ref": "#/$defs/cronJob" }
	},
	"$defs": {
		"cronJob": {
			"type": "object",
			"required": [
				"id",
				"name",
				"description",
				"cronExpression",
				"gracePeriodSeconds",
				"timezone",
				"status",
				"alertOnLate",
				"lastPingAt",
				"nextExpectedAt",
				"enabledAt",
				"createdAt",
				"updatedAt"
			],
			"properties": {
				"id": { "type": "string", "pattern": "^cron_[a-zA-Z0-9]+$" },
				"name": { "type": "string", "minLength": 1, "maxLength": 100 },
				"description": { "type": ["string", "null"], "maxLength": 500 },
				"cronExpression": { "type": "string" },
				"gracePeriodSeconds": { "type": "integer", "minimum": 60, "maximum": 86400 },
				"timezone": { "type": "string" },
				"status": { "type": "string", "enum": ["healthy", "late", "missed", "new"] },
				"alertOnLate": { "type": "boolean" },
				"lastPingAt": { "type": ["string", "null"], "format": "date-time" },
				"nextExpectedAt": { "type": ["string", "null"], "format": "date-time" },
				"enabledAt": { "type": ["string", "null"], "format": "date-time" },
				"createdAt": { "type": "string", "format": "date-time" },
				"updatedAt": { "type": "string", "format": "date-time" }
			}
		}
	}
}

PUT /api/v1/cron-jobs/:id

Updates an existing cron job monitor.

Required Scope

cron-jobs:write

Request Body

All fields are optional. Only provided fields will be updated.

FieldTypeDescription
namestringDisplay name (1-100 characters)
cronExpressionstringValid cron expression
descriptionstringOptional description (max 500 characters)
gracePeriodSecondsintegerSeconds to wait before marking late (60-86400)
timezonestringIANA timezone, or UTC. Any other value is rejected with VALIDATION_ERROR.
alertOnLatebooleanSend alerts when job is late
enabledbooleanWhether the monitor is active

Example Request

cURL

curl -X PUT https://uptime.sergiodxa.com/api/v1/cron-jobs/cron_abc123 \
  -H "Authorization: Bearer uptime_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "gracePeriodSeconds": 900,
    "alertOnLate": false
  }'

Response

{
	"data": {
		"id": "cron_abc123",
		"name": "Daily Backup",
		"description": "Runs database backup every night",
		"cronExpression": "0 2 * * *",
		"gracePeriodSeconds": 900,
		"timezone": "America/New_York",
		"status": "healthy",
		"alertOnLate": false,
		"lastPingAt": "2026-02-14T07:00:12Z",
		"nextExpectedAt": "2026-02-15T07:00:00Z",
		"enabledAt": "2026-01-10T14:30:00Z",
		"createdAt": "2026-01-10T14:30:00Z",
		"updatedAt": "2026-02-14T16:45:00Z"
	}
}

Possible Errors

StatusCodeDescription
400VALIDATION_ERRORInvalid request body or cron expression
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key doesn't have cron-jobs:write scope
404NOT_FOUNDCron job not found
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORServer error

Request Body Schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"name": { "type": "string", "minLength": 1, "maxLength": 100 },
		"cronExpression": { "type": "string" },
		"description": { "type": "string", "maxLength": 500 },
		"gracePeriodSeconds": { "type": "integer", "minimum": 60, "maximum": 86400 },
		"timezone": { "type": "string" },
		"alertOnLate": { "type": "boolean" },
		"enabled": { "type": "boolean" }
	}
}

Response Schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"required": ["data"],
	"properties": {
		"data": { "$ref": "#/$defs/cronJob" }
	},
	"$defs": {
		"cronJob": {
			"type": "object",
			"required": [
				"id",
				"name",
				"description",
				"cronExpression",
				"gracePeriodSeconds",
				"timezone",
				"status",
				"alertOnLate",
				"lastPingAt",
				"nextExpectedAt",
				"enabledAt",
				"createdAt",
				"updatedAt"
			],
			"properties": {
				"id": { "type": "string", "pattern": "^cron_[a-zA-Z0-9]+$" },
				"name": { "type": "string", "minLength": 1, "maxLength": 100 },
				"description": { "type": ["string", "null"], "maxLength": 500 },
				"cronExpression": { "type": "string" },
				"gracePeriodSeconds": { "type": "integer", "minimum": 60, "maximum": 86400 },
				"timezone": { "type": "string" },
				"status": { "type": "string", "enum": ["healthy", "late", "missed", "new"] },
				"alertOnLate": { "type": "boolean" },
				"lastPingAt": { "type": ["string", "null"], "format": "date-time" },
				"nextExpectedAt": { "type": ["string", "null"], "format": "date-time" },
				"enabledAt": { "type": ["string", "null"], "format": "date-time" },
				"createdAt": { "type": "string", "format": "date-time" },
				"updatedAt": { "type": "string", "format": "date-time" }
			}
		}
	}
}

DELETE /api/v1/cron-jobs/:id

Deletes a cron job monitor. This action cannot be undone.

Required Scope

cron-jobs:write

Example Request

cURL

curl -X DELETE https://uptime.sergiodxa.com/api/v1/cron-jobs/cron_abc123 \
  -H "Authorization: Bearer uptime_your_api_key"

Response

Returns 204 No Content on success with an empty response body.

Possible Errors

StatusCodeDescription
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key doesn't have cron-jobs:write scope
404NOT_FOUNDCron job not found
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORServer error

Response Schema

Returns 204 No Content with an empty response body on success.

POST /api/v1/cron-jobs/:id/ping

Records a ping for a cron job monitor. Call this endpoint when your scheduled task completes successfully.

Like every other endpoint on this page, it requires an API key: send it as Authorization: Bearer <key>. A key reaches only the monitors of the team that owns it—pinging another team's monitor returns 404, exactly as an id that doesn't exist does, so the endpoint can't be used to discover which ids are real.

Because this URL lives in crontabs and deploy scripts, it also accepts the monitor's plain UUID in place of its cron_ id, so an address saved before the id got its prefix keeps working. Both forms name the same monitor and share the same rate limit. Use the cron_ id shown by List Cron Jobs for anything new.

Rate Limit: This endpoint is rate limited to 1 request per minute per cron job. Additional requests within the same minute will be rejected with a 429 error. A separate abuse limit caps how many requests one caller may send for one monitor per minute, whether or not they are accepted; exceeding it also returns 429, and it applies before the key is checked.

Required Scope

cron-jobs:ping

Example Request

cURL

curl -X POST https://uptime.sergiodxa.com/api/v1/cron-jobs/cron_abc123/ping \
  -H "Authorization: Bearer uptime_your_api_key"

Response

{
	"wasOnTime": true
}

Unlike the rest of /api/v1, this endpoint answers with the bare object above rather than the { data, meta } envelope, so a shell script can read the result without unwrapping it.

Possible Errors

StatusCodeDescription
401UNAUTHORIZEDMissing, invalid, or expired API key
403FORBIDDENAPI key doesn't have cron-jobs:ping scope
404NOT_FOUNDCron job not found, or owned by another team
409CONFLICTCron job is disabled
429RATE_LIMITEDMore than 1 ping per minute for this job, or caller budget spent
500INTERNAL_ERRORServer error

Response Schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"required": ["wasOnTime"],
	"properties": {
		"wasOnTime": { "type": "boolean" }
	}
}

wasOnTime is true when the ping arrived within the job's grace period, and false when it arrived after it — a late ping is still recorded and still answers 201.

Response Fields

All cron job responses include these fields:

FieldTypeDescription
idstringUnique identifier (prefixed with cron_)
namestringDisplay name
descriptionstring | nullOptional description
cronExpressionstringCron schedule expression
gracePeriodSecondsintegerSeconds to wait before marking late
timezonestringIANA timezone for the schedule
statusstringCurrent status: healthy, late, missed, or new
alertOnLatebooleanWhether alerts are sent when the job is late
lastPingAtinteger | nullUnix timestamp in milliseconds of the last ping, or null if never
nextExpectedAtinteger | nullUnix timestamp in milliseconds of the next expected ping
enabledAtinteger | nullUnix timestamp in milliseconds when enabled, or null if disabled
createdAtintegerUnix timestamp in milliseconds when created
updatedAtintegerUnix timestamp in milliseconds when last updated