Run monitors
Proof your scheduled jobs and agents ran, and signed proof when they did not
Last updated
TL;DR: Rightshold run monitors give every reported run of a scheduled job or agent a tamper-evident receipt, and when an expected run does not report within its grace period, Rightshold writes the missed-run receipt itself and alerts your endpoints. Cron expressions with time zones, intervals, timeouts and signed statements.
Agents increasingly do work for you over time: nightly, hourly, after N days. A run monitor gives every reported run a tamper-evident receipt, and when an expected run does not report in time, Rightshold writes the missed-run receipt itself: dated, hash-chained and committed to the public ledger, ready to show a client or an auditor.
1. Describe the schedule
In the operations console, open Monitors and add one per job or agent: a cron expression in its time zone (or every N seconds), a grace period, and optionally a maximum runtime. You get a secret ping URL, shown once.
2. Report each run
The job calls the ping URL when it starts and when it finishes, or once at the end. Pass the scheduler's run id as ?rid= and a redelivered call is recorded once. Every report becomes a hash-chained receipt committed to the public ledger.
3. Rightshold watches the clock
When an expected run's grace period closes with no report, Rightshold writes the missed-run receipt itself. A run that starts and never finishes within its maximum runtime gets a timed-out receipt. Both are Rightshold's own observation, not a claim by the job, and both alert your endpoints with a signed delivery.
4. Show anyone
Every signed statement counts each monitor's expected runs: on time, late, missed, failed and timed out. Share a statement with a client, an auditor or an insurer through a reviewer link that re-verifies on every open.
Report a run
Any cron job
curl -fsS -m 10 --retry 3 <ping URL>/start && ./nightly-export.sh && curl -fsS -m 10 --retry 3 <ping URL> || curl -fsS -m 10 --retry 3 <ping URL>/failVercel Schedules (or any handler)
import { handleSchedule } from "@vercel/schedules";
import { monitored } from "./rightshold-runs.mjs"; // https://www.rightshold.com/sdks/rightshold-runs.mjs
export const POST = handleSchedule(monitored(process.env.MONITOR_URL, async (metadata) => {
await exportRecords();
}));An agent that works on its own schedule
// At the end of each unattended task:
await fetch(process.env.MONITOR_URL + "?rid=" + encodeURIComponent(taskId), { method: "POST" });An agent connected over MCP
Connect to https://www.rightshold.com/mcp?toolset=operations with your account key as a Bearer token, then call
report_scheduled_run {"workspace_id": "...", "monitor_id": "...", "status": "succeeded", "execution_id": "<task id>"}The API, with an account key
POST https://www.rightshold.com/v1/operations/workspaces/{workspace_id}/monitors/{monitor_id}/runs
Authorization: Bearer <api key>
{"status": "succeeded", "execution_id": "run-2026-11-06", "duration_ms": 8200}
The wrapper: rightshold-runs.mjs, plain JavaScript with no dependencies (SHA-256 4e452fd9e0eea606ab4d47cdef6780acf12c68be39d3614b02bbf6daa0c19660). It never throws and never changes what your handler returns.
Ping URL reference
<ping URL>/start | The run started. |
|---|---|
<ping URL> | The run succeeded. |
<ping URL>/fail | The run failed. |
<ping URL>/<exit code> | 0 means success; 1 to 255 mean failure, and the code is kept. |
?rid=<run id> | The scheduler's execution or run id. A repeated call with the same id is recorded once, and a finish matches its start. |
&scheduled_at=<ISO time> | Which expected run this is, when the scheduler says so. Without it, a report belongs to the latest expected run at or before it. |
Answers are plain text: OK, or a sentence saying why nothing was recorded.
The secret
The ping URL carries a secret. Rightshold stores only its SHA-256, takes it out of the request path before anything is logged or counted, ignores any request body, and lets you rotate it at any time.
What a receipt does not prove
- A run receipt proves what the job reported and when, and that the record has not changed since. It does not prove what the job did.
- A missed-run receipt proves that no report reached Rightshold within the grace period. It cannot tell a job that did not run from one that could not reach Rightshold.
- Expected runs are at least five minutes apart, and while a monitor stays down its missed runs are receipted and alerted once an hour, in one receipt covering the gap.
- Nothing is expected before a monitor is created or while it is paused. A local time that does not exist on a daylight saving change day is not expected; one that occurs twice is expected once.
Add a monitor in the console · Guard your MCP servers too · Markdown
Frequently asked questions
How is this different from a cron monitor?
A cron monitor alerts you. A run monitor also leaves a record a client or an auditor can check: each run and each missed run is a hash-chained receipt committed to a public ledger, and a private link shows the last 30 days to anyone you choose.
How do I report a run?
Call the monitor's secret ping URL: /start when the run begins, the URL itself on success, /fail or an exit code on failure, adding ?rid= with the scheduler's run id so a repeat is recorded once.
Does a missed-run receipt prove the job did not run?
No. It proves no report reached Rightshold within the grace period. It cannot tell a job that did not run from one that could not reach Rightshold.
