Docs / Scheduled tasks / Cron syntax
Cron syntax
CloudyBot scheduled work uses either every N minutes (interval mode) or a five-field cron string (calendar mode). The dashboard Schedule picker builds cron from your wall-clock time plus an IANA timezone (for example America/New_York). Default timezone is UTC if you do not change it. Hub: scheduled tasks.
Two ways to schedule
- Interval (
every_minutes) — default for chatadd_taskand many Schedule-tab tasks. Internally becomes*/N * * * *with N between 1 and 59. Good for “check every hour” style jobs. - Five-field cron (
cronExpr) — required for Specialist duties and calendar patterns (weekdays at 9:00, monthly on the 1st). Paste or edit the expression directly when you outgrow presets. - One-shot follow-ups —
schedule_followupuses delay minutes/hours/days, not cron (max 30 days).
Field order (5 fields, no seconds)
CloudyBot uses standard Unix-style cron — not six-field (no seconds column):
minute hour day-of-month month day-of-week
- minute — 0–59,
*,*/15, lists (0,30), ranges. - hour — 0–23 in the job’s timezone.
- day-of-month — 1–31 or
*. - month — 1–12 or
*. - day-of-week — 0–6 (Sunday = 0) or
*; ranges like1-5for weekdays.
Common expressions
Interpreted in the job’s configured timezone:
0 9 * * *— every day at 09:000 9 * * 1— Mondays at 09:000 9 * * 1-5— weekdays at 09:0030 8 * * 0,6— weekends at 08:30*/30 * * * *— every 30 minutes*/15 * * * *— every 15 minutes (minimum step for Specialist duties)15 * * * *— at :15 past each hour0 9 1 * *— 09:00 on the 1st of each month0 9 1,15 * *— 09:00 on the 1st and 15th
Dashboard presets map to these patterns: daily, weekdays, weekends, weekly (pick day), every 15/30, hourly at a fixed minute.
Specialist duty minimum interval
Duties on hired Specialists must run no more than once every 15 minutes. The API rejects:
* * * * *or*/5 * * * *(sub-15-minute steps)- Minute field
*with hour*(every minute) - Comma lists with gaps under 15 minutes (for example
0,5,10 * * * *)
Valid duty examples: fixed time (0 9 * * *), */15 or */30, or hourly at a single minute (5 * * * *). Standalone Schedule-tab interval tasks are not subject to this guard.
Timezone tips
- Set the job timezone to where the human expects the run — not where the server lives.
- Daylight saving shifts are handled by the IANA zone you pick; raw UTC is fine for global ops jobs.
- When validating on crontab.guru, match its timezone setting to your dashboard job.
- If a run looks an hour early/late, check timezone first before rewriting the expression (troubleshooting).
Chat-created tasks vs duties
From dashboard chat, add_task with only every_minutes creates a standalone Schedule-tab task. If the model supplies cron_expr while you are on an active Specialist thread, CloudyBot stores it as a duty under that Specialist (subject to the 15-minute rule). Interval-only tasks on Specialist threads stay standalone unless cron is provided.
Validate before you ship
- Five tokens, space-separated — extra fields will not parse.
- Use Run now on the card after saving; new jobs also fire once immediately on create.
- External validators are helpful; CloudyBot’s picker uses the same five-field rules as
api/public/js/cron-schedule-shared.js.
Related: Troubleshooting missed runs · Where results go · repo docs/scheduledTasks/Readme.md