- Team work: clawboo Routines. The
team-taskdomain: a fire materializes a board task and runs it. Clawboo fully owns these rows. - Runtime’s own life: the OpenClaw Gateway’s own cron jobs. The
runtime-own-lifedomain: an OpenClaw agent’s standalone scheduled wake, which lives on the Gateway, not in Clawboo’s ledger. Clawboo reads and writes these through the Gateway as an operator surface.
SchedulerPanel, backed by /api/schedules. This page covers what each control does, the create dialog’s options, and the error-halts policy that parks a failing routine instead of retry-burning it.
Prerequisites
The Scheduler tab is always available. Open it from the Scheduler nav item. The panel polls
GET /api/schedules on mount and re-fetches every 8 seconds, so nextRunAt countdowns and run status stay live without a manual refresh.- At least one agent exists (the create dialog populates its agent picker from
GET /api/agents). - Scheduling an OpenClaw agent’s own life (a Gateway cron job) additionally requires the OpenClaw Gateway connected and this device paired; that write rides the operator connection. Every other runtime, and the team-task domain, has no such requirement.
The Scheduler tab
The panel header shows aScheduler title, an N schedules count pill, a Schedule button (opens the create dialog), and a Refresh button.
Below the header, schedules are grouped by domain:
| Group | Domain | What lives here |
|---|---|---|
| Team work | team-task | clawboo Routines that fire team tasks |
| Runtime’s own life | runtime-own-life | The OpenClaw Gateway’s own cron jobs |
agentId), a status pill, the human-readable cron, the time until the next run, when it last ran, and, if a fire failed, the last error in red. The status pill maps to one of running, queued, claimed (all rendered as the “working” tone), paused (idle tone), error (error tone), or idle.
The row’s action buttons are a pure function of the schedule’s manageability. A managed Routine and an external-write Gateway cron are both writable, so they show Pause/Resume (managed) or Enable/Disable (external-write), Run now, and Delete. An observe-only schedule shows a read-only marker and no actions; the UI never offers a write the owning system forbids.

When the OpenClaw Gateway is disconnected, the read still returns 200; degradation is data, not an error. The panel shows an amber banner (“OpenClaw Gateway cron is unavailable … showing the last-known list”) and keeps rendering the last-known rows for that source.
Steps
Create a routine
- Click Schedule to open the create dialog.
- Pick an Agent from the dropdown (each option shows the agent name and its runtime).
- Choose the Schedule intent:
- A team task: a clawboo Routine (
team-taskdomain). Available for every agent. - Its own life: an OpenClaw Gateway cron job (
runtime-own-lifedomain). This chip is enabled only when the selected agent’s runtime isopenclaw; for any other runtime it reads “OpenClaw only” and is disabled. (If you switch to a non-OpenClaw agent while “Its own life” is selected, the dialog snaps the intent back to “A team task”.)
- A team task: a clawboo Routine (
- Pick when it Runs from the cron presets (see Options below).
- Give it a Label (optional; defaults to “Scheduled task” for a team task or “Scheduled wake” for own-life).
- Click Create schedule.
{ source: 'clawboo-routine', domain: 'team-task', agentId, cronSpec, label, teamId, taskTemplate }. An own-life create posts { source: 'openclaw-gateway-cron', domain: 'runtime-own-life', agentId, cronSpec, label, payload }. On success (201) the dialog closes and the list refreshes.
Pause or resume
Click the pause/play button on a writable row. For a Routine this is Pause → Resume; for a Gateway cron it’s labeled Disable → Enable (the samePATCH /api/schedules/:id with { action: 'pause' | 'resume' }, just different wording for the external system). A paused schedule never auto-fires until you resume it.
Run now
Click the refresh-arrow button to force-fire immediately. ThisPOST /api/schedules/:id/run returns 202 (an enqueue-style acknowledgement): for a Routine it flips the row to queued so the ticker picks it up on the next pass; for a Gateway cron it asks the Gateway to run that job now. It does not wait for the run to finish.
Delete
Click the trash button. The panel confirms first; the wording differs by domain (a Gateway cron job warns that it “removes the agent’s own scheduled wake on the OpenClaw Gateway”; a Routine warns it “is removed permanently”). Delete sendsDELETE /api/schedules/:id.
Options
Schedule presets (cron expressions)
The create dialog offers eight cron-expression presets. A cron expression is the one spec dialect both sources accept, so the same preset works whether you target a Routine or a Gateway cron:| Preset | Cron |
|---|---|
| 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 · 9am | 0 9 * * * |
| Weekly · Mon 9am | 0 9 * * 1 |
One-shot runs (once@<ISO>)
A Routine’s cronSpec also accepts a one-shot form, once@<ISO-8601> (for example once@2026-07-01T09:00:00Z), parsed by the scheduler package. The create dialog’s preset chips only emit recurring cron expressions, so to schedule a one-shot you post a once@… spec to POST /api/schedules directly. After it fires successfully the row re-enters idle with nextRunAt set to null, so it self-disables and never repeats.
Domain and manageability
| Field | Values | What it controls |
|---|---|---|
domain | team-task · runtime-own-life | Which group the row renders under, and what a fire does (board task vs. the agent’s own Gateway wake) |
manageability | managed · external-write · observe-only | Which row actions the UI offers; observe-only is read-only |
source | clawboo-routine · openclaw-gateway-cron | Which engine owns the row and which API the write routes to |
The error-halts policy
A failed recurring fire parks the routine; it does not silently retry. When a recurring Routine errors, its status goes toerror and its nextRunAt is set to null, so the due-pass (which only queues rows with a non-null nextRunAt) skips it. The row stays disarmed, with the failure shown as lastError on the row, until a human resumes it. This is deliberate: autonomous scheduled work that retries a broken fire on every tick would burn budget and noise without progress.
A paused or errored routine never auto-fires. To re-arm a parked routine, click Resume (the
paused | error → idle transition re-arms it). A one-shot once@ that fired successfully is a different case; it self-disables on purpose and is not an error.Verify it worked
- The new schedule appears under its domain group with a live
nextRunAtcountdown (in 5m,in 1h, …). - When a fire is due, the status pill flips to
queued→claimed→running, then back toidle(re-armed) on success. - After a fire, the row shows
ran <relative time>. - A
team-taskfire materializes a task on the board for the routine’s team; open the board to see it. - If a recurring fire fails, the row goes to the
errorpill with alastErrorline and an empty next-run countdown; resume it to re-arm.
Troubleshooting
A create returns
409. The scheduler enforces a one-firing-owner rule: binding a Routine to a board task that another non-manual owner already fires is refused as a conflict, and an illegal status transition is also a 409. These are conflicts, not transient errors; they are not retried. A 422 means a team-task schedule was aimed at the Gateway-cron source (a domain violation); a 403 means the targeted source is observe-only.Related
- Scheduling: the model: team-task cron vs. runtime-own-life cron, the ledger, the ticker
- The board: where a
team-taskfire lands /api/schedulesreference: full request/response shapes and status codes- Connecting runtimes: get a runtime online so it can run scheduled work
- Observability dashboard: see a scheduled run’s trace