Prerequisites
- At least one agent exists in Clawboo. The create dialog picks agents from
GET /api/agents. - The agent’s runtime is connected and
ready. Routines work for every runtime class — Native, Claude Code, Codex, Hermes, and OpenClaw. See Connecting runtimes. - The Scheduler tab is open. Navigate to it from the sidebar. Everything here also works directly against the
/api/schedulesREST surface.
Steps
Open the Scheduler panel and click Schedule
Navigate to the Scheduler tab in the sidebar. The panel shows two groups: Team work (Routines you create here) and Agent’s own life (OpenClaw-only Gateway schedules Clawboo observes). Click Schedule to open the create dialog.
Configure the Routine
Fill in the dialog:
Any croner-parseable 5- or 6-field cron expression works, not just the presets. An unparseable spec is refused at creation with
- Agent — pick the agent that should run this task. Each option shows the agent name and its runtime.
- Schedule intent — leave it on A team task. The other option, Its own life, is enabled only for OpenClaw agents; for any other runtime it reads “OpenClaw only” and is disabled.
- Runs — pick a cadence from the cron presets (see the table below) or type your own expression.
- Label — an optional human-readable name. Defaults to “Scheduled task”.
| Preset | Cron expression |
|---|---|
| Every 5 minutes | */5 * * * * |
| Every 15 minutes | */15 * * * * |
| Every 30 minutes | */30 * * * * |
| Every hour | 0 * * * * |
| Every 6 hours | 0 */6 * * * |
| Every 12 hours | 0 */12 * * * |
| Daily at 9 am | 0 9 * * * |
| Weekly — Monday 9 am | 0 9 * * 1 |
400 code: "invalid_cron_spec".Click Create schedule. On success the dialog closes (201) and the list refreshes.Create the same Routine via the API (optional)
If you prefer REST, To schedule a one-off future run instead of a recurring cadence, use the A one-shot Routine re-enters
source, domain, agentId, and cronSpec are required. taskTemplate.title is required inside the template; kind defaults to code (which provisions a worktree).once@<ISO-8601> form — only available via the API, not the dialog:idle with nextRunAt: null after it fires successfully — it self-disables and never repeats.Verify the Routine is saved
The new Routine appears under the Team work group with a live Your new row should appear with
nextRunAt countdown (in 5m, in 1h, …). The panel re-fetches every 8 seconds, so the countdown and status stay current.Confirm over REST:"status": "idle" and a populated nextRunAt.Test it with Run Now
Click the run-now (refresh-arrow) button on the row to force-fire immediately without waiting for the cron tick:This returns
202 — an enqueue acknowledgement, not a synchronous result. The row flips to queued and the ticker picks it up on the next pass. Watch the trace in the Observability dashboard to see the outcome. A fire also materializes a task on the board — open it to confirm.Pause a Routine
Click the pause button on the row to stop the Routine from auto-firing until you resume it:A paused Routine never auto-fires. Resume it with the play button (or
{"action": "resume"}) when you’re ready — Clawboo recomputes nextRunAt from the current time.What happens when a Routine fires
When a Routine is due, the ticker flips it toqueued, atomically claims it, materializes the board task, and routes it to the correct runtime:
- Native, Claude Code, Codex, Hermes — runs through the one-shot executor: claim the board task, provision a worktree if the task kind requires it, run the adapter, verify, complete.
- OpenClaw — runs over its live Gateway connection through a separate operator dispatcher, bounded by a configurable watchdog (default 10 minutes, set
CLAWBOO_ROUTINE_OPENCLAW_TIMEOUT_MSto override).
routine_fired, routine_dispatched, then routine_completed or routine_error) so you can follow a scheduled run in the Observability dashboard exactly like any hand-created task.
Understand the error-halts policy
When a recurring Routine’s fire fails, the Routine parks itself: status goes toerror, the failure is recorded in lastError, and nextRunAt is set to null. It will not fire again until you manually resume it.
This is intentional. An autonomous scheduled task that silently retries a broken fire every tick would burn budget, churn the board, and hide the real problem. Parking surfaces the failure immediately and stops the bleeding. Fix the underlying cause, then click Resume to re-arm the Routine (
error → idle).Change the cadence
Update the cron spec, label, or task template on an existing Routine with aPATCH:
nextRunAt only for an already-armed (idle) row. A paused or parked row stays disarmed until you resume it.
Troubleshooting
Related
Governance and budgets
Cap what a scheduled fire can spend before you let it run unattended.
Scheduling concept
The two cron domains, the ledger, the rebuildable ticker, and the fire path.
Schedules API
Full request/response shapes and status codes.
Observability dashboard
Watch a scheduled run’s trace end to end.
Cross-runtime handoff
Another way scheduled work composes across runtimes.
The board
Where each fire lands and how the atomic claim works.