HOW TO SCHEDULE WEBHOOKS WITH CRON: A DEVELOPER'S GUIDE

How to schedule webhooks with cron: a developer's guide

Turn any HTTP endpoint into a cron-driven job. Create schedules via API, attach event payloads, and let a managed scheduler deliver signed webhooks on time, every time.

A webhook is how your system learns that something happened. A cron job is how an event happens on a schedule. Put them together — a scheduled webhook — and you get the most useful primitive in backend architecture: a managed trigger that POSTs to your endpoint on any cron expression, carrying a payload you defined, with no scheduler of your own to operate.

Recurrence Cloud is built around exactly this primitive. This guide walks through going from zero to a working scheduled webhook in a few minutes.

The pattern in one picture

Instead of running cron inside a server that must never sleep, your architecture becomes:

Recurrence Cloud (scheduler)      Your service (receiver)
────────────────────────────      ─────────────────────────
  cron expr ──► event payload ──► POST /webhooks/<you>
                     │                  │
                     └── signed JWT ────┘──► verify + process

The scheduler lives outside your process. Your service can deploy, scale to zero, or be rewritten in a different language next week — the schedule doesn’t care.

Step 1: Create an app and token

Sign in, create an application, and generate the app’s API token. That token is both your credentials for the Recurrence Cloud API and the HMAC secret used to sign the webhooks delivered to you — one secret, two jobs, no configuration drift.

Step 2: Register your webhook URL

Register the HTTPS endpoint that will receive scheduled deliveries:

curl -X POST https://api.recurrence.cloud/v1/webhooks \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://api.yourcompany.dev/jobs" }'

Step 3: Create the schedule

Any standard cron expression works, plus a timezone so “9am” means your 9am:

curl -X POST https://api.recurrence.cloud/v1/schedules \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nightly-sync",
    "cron": "0 3 * * *",
    "timezone": "Europe/Berlin",
    "webhookUrl": "https://api.yourcompany.dev/jobs"
  }'

Need a one-off fire instead of recurrence? The same surface accepts a single run time — useful for reminders and follow-ups.

Step 4: Attach the event payload

The event is what arrives in the body of the webhook. Attach it to the schedule:

curl -X POST https://api.recurrence.cloud/v1/schedules/nightly-sync/events \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "data.sync",
    "subject": "payments",
    "payload": { "source": "ledger", "target": "warehouse" }
  }'

Step 5: Receive and verify

Every delivery is a signed JWT — signed with your API token as the HMAC secret. Verify it, then do the work:

import { verify } from "hono/jwt";

app.post("/jobs", async (c) => {
  const token = c.req.header("Authorization")?.replace("Bearer ", "");
  const claims = await verify(token!, [
    new TextEncoder().encode(process.env.API_TOKEN!),
  ]);

  // claims.event === { type, subject, payload }
  await sync(claims.event.payload);
  return c.json({ ok: true });
});

Step 6: Watch it run

Every call lands in the activity trail: timestamp, status code, response body, duration, and retry status. When the 3am sync misbehaves, the evidence is already collected for you — no SSH, no log grepping.


That’s the whole story. For the syntax details see our cron cheat sheet, for failure handling see monitoring and reliability, and for the security model see verifying signed webhooks.