slew docs/deploy/scheduled-jobs

Scheduled jobs

Cron for a project: the platform requests a path on your site on a schedule. Built for server runtimes — a due job wakes a scaled-to-zero instance, runs your handler, and records the outcome.

How a run works

When a job is due, the platform sends a request to https://<project>.slew.cloud<path> using the job's method (GET or POST), with two headers:

Header Value
X-Slew-Cron 1
X-Slew-Cron-Secret the job's secret
  • The request times out after 60 seconds.
  • A run wakes a scaled-to-zero instance — the job doesn't need the server to already be running.
  • No retries. A failed or timed-out run is recorded, and the next attempt is simply the next scheduled time.
  • lastRunAt and lastStatus on the job record the outcome (slew cron list shows them).

The path is a normal URL on your site, reachable by anyone — verify the secret in the handler. The secret is in the cron object (slew cron list); put it in a runtime env var and compare:

app.post('/tasks/daily-digest', (req, res) => {
  if (req.get('x-slew-cron-secret') !== process.env.CRON_SECRET) {
    return res.sendStatus(401)
  }
  // do the work
  res.sendStatus(204)
})

Schedules

Standard 5-field cron expressions (minute hour day-of-month month day-of-week), evaluated in UTC, minute granularity:

Expression Runs
*/15 * * * * Every 15 minutes
0 3 * * * Daily at 03:00 UTC
0 9 * * 1 Mondays at 09:00 UTC

A project holds at most 5 jobs.

Console

The console's Runtime tab has a Scheduled jobs section: the project's jobs with their schedule, path, method, paused state and last run's outcome, a reveal-on-demand secret per job, pause/resume/delete, and a form to add one.

CLI

slew cron add "0 3 * * *" /tasks/daily-digest --method POST
Command Effect
slew cron list The project's jobs: schedule, path, method, state, last run
slew cron add "<schedule>" <path> [--method POST] Create a job; the method defaults to GET
slew cron rm <id> Delete a job
slew cron enable <id> / slew cron disable <id> Turn a job on or off without deleting it

HTTP API

Bearer auth, like everything else:

Method Path Description
GET /projects/:name/crons List the project's jobs
POST /projects/:name/crons Create a job — { "schedule", "path", "method"? } (GET or POST, default GET)
PATCH /projects/:name/crons/:id Update a job — enable/disable is { "enabled": true | false }
DELETE /projects/:name/crons/:id Delete a job

A cron object:

Field Meaning
id Job id
schedule The 5-field cron expression (UTC)
path Request path on the project's site
method GET or POST
secret Sent with every run as X-Slew-Cron-Secret — verify it in your handler
enabled A disabled job stays configured but never runs
lastRunAt, lastStatus When the job last ran and how it went
createdAt When the job was created

Errors:

Code Meaning
invalid_schedule Not a valid 5-field cron expression
invalid_path Not a valid request path
cron_limit_reached The project already has 5 jobs