Render cron job failed notifications on your phone.

Get a High-priority push notification when a Render cron job run or one-off job fails, and optionally a quiet one when it succeeds.

How it works

Three steps to your first push

STEP 01

Install the recipe

One click in Studio gives you a personal webhook URL.

STEP 02

Paste your URL into Render

Add it as a webhook for Cron Job Run Ended.

STEP 03

Get a push on your phone

With the text, sound and buttons from the recipe.

Setup

How to set up the Render cron job run ended webhook

  1. Click Install in Studio and sign in. The recipe is added to your account and you get a personal webhook URL.
  2. In the Render Dashboard, open your workspace's Integrations > Webhooks and click + Create Webhook (Pro plan or higher, workspace admins only).
  3. Give it a name and paste your webhook URL as the URL.https://••••••••/•••••••• your personal URL, shown after install
  4. Select the Cron Job Run Ended event and click Create Webhook.
  5. In the Render Dashboard, open **Integrations → Webhooks → + Create Webhook** (Pro plan or higher) with the URL above, and select **Cron Job Run Ended**. Add **Job Run Ended** too if you use one-off jobs.
  6. Only failed runs push by default. Add `?all=1` to the URL to also get a quiet push when a run succeeds or is canceled:
  7. ```
  8. your webhook URL?all=1
  9. ```
  10. On a **Pro** workspace you get a single webhook URL, so one integration receives every event you select; the recipe ignores the events it doesn't handle. Scale and Enterprise workspaces can add a webhook per recipe.
  11. Render signs deliveries with Standard Webhooks headers (`webhook-signature`), but JustPush doesn't check that signature yet, so keep your endpoint URL private.
The code

What runs when the webhook arrives

Studio calls handleRequest(request) with the incoming webhook and sends the message it returns. It's yours after install; change anything.

transform.js
1// Render → cron job run ended (and one-off job run ended)
2// Fires when a Render workspace webhook sends cron_job_run_ended or job_run_ended.
3// Only failed runs push, unless the webhook URL has ?all=1.
4// Docs: https://render.com/docs/webhooks
5
6// The two event types and how to name what ran.
7const KINDS = {
8 cron_job_run_ended: "cron job",
9 job_run_ended: "job",
10}
11
12// Run statuses, their labels and how loud to be.
13const STATUSES = {
14 // A failed run means the work didn't happen; it needs you soon.
15 failed: { emoji: "❌", verb: "failed", priority: 1 },
16 // Only with ?all=1: routine news.
17 succeeded: { emoji: "✅", verb: "succeeded", priority: -1 },
18 canceled: { emoji: "⏹️", verb: "was canceled", priority: -1 },
19}
20
21// Look a key up in one of the tables above, ignoring inherited names like "toString".
22function pick(table, key, fallback) {
23 return Object.prototype.hasOwnProperty.call(table, key) ? table[key] : fallback
24}
25
26// Only link to real http(s) URLs.
27function link(url, cta) {
28 return typeof url === "string" && /^https?:\/\//.test(url) ? [{ cta, url }] : []
29}
30
31function handleRequest(request) {
32 const body = request.body && typeof request.body === "object" ? request.body : {}
33 const data = body.data && typeof body.data === "object" ? body.data : {}
34 const kind = pick(KINDS, body.type, null)
35 const status = pick(STATUSES, data.status, null)
36
37 // Guard: only finished job runs with a known status.
38 if (!kind || !status) {
39 console.log(`Ignoring Render "${body.type ?? "unknown"}" event (status "${data.status ?? "none"}")`)
40 return null
41 }
42
43 // ?all=1 on the webhook URL also sends quiet pushes for succeeded and canceled runs.
44 const all = ["1", "true", "yes"].includes(String(request.query?.all ?? "").toLowerCase())
45 if (data.status !== "failed" && !all) {
46 console.log(`Skipping ${kind} run that ${data.status} (add ?all=1 to get these)`)
47 return null
48 }
49
50 const name = typeof data.serviceName === "string" && data.serviceName ? data.serviceName : "Your"
51
52 return {
53 title: `${status.emoji} ${name} ${kind} ${status.verb}`,
54 message: data.status === "failed" ? "Check the run's logs in Render" : `The ${kind} run ${data.status === "canceled" ? "was canceled" : "finished"}`,
55 topic: "Render",
56 priority: status.priority,
57 buttons: link("https://dashboard.render.com", "Open Render"),
58 }
59}
Payload

The Render cron_job_run_ended webhook

This is what Render sends to your URL for cron job run ended. It is a sample, trimmed to the fields recipes use.

cron_job_run_ended · sample.json
1{
2 "data": {
3 "id": "evt-d3ka1qf015js70180m20",
4 "status": "failed",
5 "serviceId": "crn-d2kp0ahtq21c73e9t4b0",
6 "serviceName": "nightly-report"
7 },
8 "type": "cron_job_run_ended",
9 "timestamp": "2026-09-29T02:00:41.503Z"
10}
FAQ

Render cron job failed notifications: questions

Does this work on iPhone and Android?

Yes. Install the JustPush app from the App Store or Google Play and sign in. Every phone signed in to your account gets the notification.

Do I need to write code?

No. Install the recipe in Studio, paste your webhook URL into Render and you are done. The code is there if you want to change the text, the sound or the buttons.

Can I change what the notification says?

Yes. After install the recipe's code is yours. Edit it in Studio and test it against the sample payload before you save.

What does it cost?

JustPush is free for 30 days. After that it's $19.99 a year, or $39.99 once. There is no extra charge for recipes.

Ready when you are

Render on your phone in two minutes.

Install the recipe, paste one URL, done. Free for 30 days, no credit card required.