Skip to content

Scheduled triggers wiring

Scheduled flow triggers need one thing wired up: an external timer that pings FlowRunner's tick endpoint once a minute. This is the only piece of infrastructure the platform operator connects — everything else is self-contained.

How it works

Each minute, the timer calls POST /api/cron/tick (a GET works too) carrying a shared secret. The endpoint checks the secret, then runs every enabled schedule whose cron expression matches the current minute, recording each run in run history.

Step 1 — set the secret

Set CRON_SECRET in the environment. Generate one with:

bash
openssl rand -hex 32

WARNING

The tick endpoint is fail-closed. If CRON_SECRET is not set, every request is rejected with 401 and no schedule ever fires. Setting the secret is what turns the scheduler on. Its comparison is timing-safe, so the secret can't be guessed by measuring response times.

Step 2 — point a timer at the tick endpoint

Pick whichever timer your platform gives you. Both approaches below send the secret as a bearer token; the endpoint also accepts it in an x-cron-secret header.

Vercel Cron

Add a crons entry to vercel.json. Vercel automatically attaches Authorization: Bearer $CRON_SECRET from your project's environment:

json
{
  "crons": [
    { "path": "/api/cron/tick", "schedule": "* * * * *" }
  ]
}

The * * * * * schedule fires every minute — the resolution the scheduler is designed for.

Any external timer (curl)

A GitHub Action, an uptime pinger, or a system cron job works just as well. Send a bearer token:

bash
curl -sS -X POST \
  -H "Authorization: Bearer $CRON_SECRET" \
  https://<your-host>/api/cron/tick

TIP

Run the tick every minute regardless of how many schedules you have. The endpoint is cheap when nothing is due — it just queries for matching schedules and returns. Per-flow cron expressions (not the tick interval) decide when each flow actually runs.

What a tick returns

On success the endpoint returns 200 with a summary of what it did that minute, for example:

json
{ "ok": true, "at": "2026-07-18T09:15:00.000Z", "ran": 2, "failed": 0 }

A 401 means the secret was missing or wrong. If an individual flow errors, its failure is recorded in run history against that project — the tick itself still completes.

Defining the schedules

Wiring the tick is the operator's job; creating the schedules is done in the app. You attach a cron expression to a flow under its trigger settings — see Schedule triggers. Each result, success or failure, lands in Run history with method CRON.

See also

FlowRunner — the no-code platform for small businesses.