Monitor a Vercel cron job and get told on WhatsApp when it stops
Vercel Cron triggers a route on a schedule. If that route throws, Vercel records a failed invocation and moves on — there is no retry and no notification unless you have wired one up.
So the job can fail every night for a fortnight while the deployment stays green. The fix is for the job to report its own success, and for something outside Vercel to notice when that report stops arriving.
app/api/cron/digest/route.ts
export const dynamic = "force-dynamic";
export async function GET(request: Request) {
// Vercel signs cron invocations. Without this the route is a public endpoint
// anyone can trigger as often as they like.
if (request.headers.get("authorization") !== \`Bearer \${process.env.CRON_SECRET}\`) {
return new Response("unauthorized", { status: 401 });
}
try {
await sendDailyDigest();
await fetch("https://hb.alertkite.com/p/YOUR_TOKEN", { method: "POST" });
return Response.json({ ok: true });
} catch (error) {
// Report the failure explicitly rather than going quiet — /fail pages now
// instead of waiting for the grace period to lapse.
await fetch("https://hb.alertkite.com/p/YOUR_TOKEN/fail", {
method: "POST",
body: String(error),
});
throw error;
}
}Setting it up
- Add the schedule to vercel.json under `crons`.
- Set CRON_SECRET in your project's environment variables and check it in the route.
- Create a heartbeat monitor with a period matching the schedule, plus grace.
- Ping on success, and call /fail in the catch so a broken run pages immediately.
Await the ping before returning
A serverless function can be frozen the moment it returns a response. A fetch that has not resolved by then may never be sent, which produces a false outage at 3am. Await it.
Hobby plans run once a day, and not at a promised minute
Cron timing on Vercel is best-effort, and Hobby is limited to daily. Set the heartbeat period generously — an hour of grace on a daily job — or you will be paging yourself over ordinary scheduling drift.
This works the same on Netlify, Render and Railway
Nothing here is Vercel-specific beyond the signature header. Any scheduler that can run a function can call a URL on success, and the monitoring side is identical.