Skip to main content
The Schedules API provides a single merged view over two schedule sources: Clawboo Routines (the team-task domain — recurring team work owned by the scheduled_runs SQLite ledger) and the OpenClaw Gateway cron (the runtime-own-life domain — an OpenClaw agent’s standalone cron). You can read both sources together and write to either, with each write routed automatically based on the composite schedule id.
The two sources are never conflated. A Routine schedules team work fired on a cadence for any runtime class. A Gateway-cron row schedules an OpenClaw agent’s own standalone life. Clawboo never registers a team task into the Gateway cron.
Every schedule id is a composite of the form <source>:<rawId> — for example clawboo-routine:123 or openclaw-gateway-cron:abc. Mutation routes URL-decode and parse the id back to its owning source. An id that matches no source returns 404.

Routes

MethodPathSummary
GET/api/schedulesMerged list across both sources
POST/api/schedulesCreate a schedule
PATCH/api/schedules/:idPause/resume or patch a schedule
DELETE/api/schedules/:idRemove a schedule
POST/api/schedules/:id/runForce-fire now

The ScheduleRecord shape

Every source normalizes its rows to this shape:
id
string
Composite <source>:<sourceScheduleId> — treat as opaque.
source
string
'clawboo-routine' | 'openclaw-gateway-cron'
domain
string
'team-task' (Routine) | 'runtime-own-life' (Gateway cron)
cronSpec
string
A cron expression (e.g. "0 9 * * *"), once@<iso> for a one-shot, or every:<ms>[@anchor:<ms>].
status
string
'queued' | 'claimed' | 'running' | 'idle' | 'paused' | 'error'
nextRunAt
number | null
Epoch ms of the next scheduled fire. null when disarmed.
manageability
string
'managed' — Clawboo owns the row. 'external-write' — the runtime owns the store. 'observe-only' — read-only.
SourceDomainManageabilityBacked by
clawboo-routineteam-taskmanagedscheduled_runs SQLite ledger
openclaw-gateway-cronruntime-own-lifeexternal-writeGateway cron over operator WS-RPC

GET /api/schedules

Returns the merged schedule list across both sources. A source that fails or is disconnected contributes a degraded sources[] entry rather than failing the request. This route always returns 200.

Response 200 OK

schedules
ScheduleRecord[]
Merged schedule records from both sources.
sources
array
Per-source status. A degraded source is noted here but does not fail the response.
curl http://localhost:18790/api/schedules

POST /api/schedules

Creates a schedule. The body routes the write to spec.source. Clawboo enforces that a team-task schedule cannot be aimed at the Gateway cron source (422), and that a recurring spec cannot be bound to an existing board task (400) — a bound task is claimable exactly once.

Request body

source
string
required
'clawboo-routine' | 'openclaw-gateway-cron'
domain
string
required
'team-task' | 'runtime-own-life'
agentId
string
required
The agent this schedule targets.
cronSpec
string
required
A cron expression ("0 9 * * *"), once@<iso> for a one-shot, or an every: interval.
label
string
Human-readable label for the schedule.
teamId
string
Team scope for Routine schedules.
teamTaskId
string
Bind this schedule to an existing board task. Only valid with a one-shot once@<iso> spec — recurring specs cannot bind to a one-shot-only task.
taskTemplate
object
For Routine rows: the task template to create when the schedule fires.

Response 201 Created

{ "schedule": { "<ScheduleRecord>" } }
Common error codes:
CodeStatusMeaning
invalid_body400Body failed the shape check
invalid_cron_spec400The cron spec is unparseable
bound_recurring_schedule400A recurring spec was bound to an existing board task
unknown_schedule404spec.source matched no registered source
duplicate_firing_owner409The bound task already has a different firing owner — do not retry
team_task_domain_violation422A team-task create aimed at the Gateway cron
schedule_source_unavailable503The Gateway cron source is disconnected
# Daily Routine (team-task) for a native agent
curl -X POST http://localhost:18790/api/schedules \
  -H 'Content-Type: application/json' \
  -d '{
    "source": "clawboo-routine",
    "domain": "team-task",
    "agentId": "<agent-id>",
    "cronSpec": "0 9 * * *",
    "label": "Daily standup digest",
    "taskTemplate": { "title": "Daily standup digest", "kind": "code" }
  }'

PATCH /api/schedules/:id

Pauses or resumes a schedule, or patches its cron spec, label, task template, or payload. The body must be exactly one of the two shapes below.
id
string
required
Composite schedule id (URL-decoded). Returns 404 if no source matches.

Request body — action

action
string
required
'pause' or 'resume'.

Request body — patch

patch
object
required
Fields to update. For Routines: cronSpec, label, taskTemplate. For Gateway cron: cronSpec, label, payload.

Response 200 OK

{ "schedule": { "<ScheduleRecord>" } }
A Gateway-cron update may return { "schedule": null } when the read-back after update cannot reload the job.
# Pause a Routine
curl -X PATCH 'http://localhost:18790/api/schedules/clawboo-routine:<row-id>' \
  -H 'Content-Type: application/json' \
  -d '{"action":"pause"}'

# Update its cron spec
curl -X PATCH 'http://localhost:18790/api/schedules/clawboo-routine:<row-id>' \
  -H 'Content-Type: application/json' \
  -d '{"patch":{"cronSpec":"0 8 * * 1-5"}}'

DELETE /api/schedules/:id

Removes a schedule. For a Routine, deletes the ledger row. For the Gateway cron, calls cron.remove on the operator connection.

Response 200 OK

{ "ok": true }
curl -X DELETE 'http://localhost:18790/api/schedules/clawboo-routine:<row-id>'

POST /api/schedules/:id/run

Force-fires a schedule immediately. This is an enqueue-style acknowledgement, not a synchronous run. A Routine moves to queued (the ticker picks it up); the Gateway cron receives a cron.run { mode: 'force' } call. Watch the observability event log for the actual execution result.

Response 202 Accepted

{ "ok": true }
curl -X POST 'http://localhost:18790/api/schedules/clawboo-routine:<row-id>/run'

Error codes reference

All error responses include a code field for stable branch-on logic:
codeStatusMeaning
invalid_body400Body failed shape check
invalid_cron_spec400Unparseable cron spec
bound_recurring_schedule400Recurring spec bound to a one-shot board task
unsupported_schedule_write403Target source’s manageability forbids this action
unknown_schedule404Id matched no source or is unknown within it
duplicate_firing_owner409Bound task already has a different owner — do not retry
illegal_schedule_transition409Pause/resume/run is illegal from the current status
team_task_domain_violation422team-task create aimed at a runtime-own-life source
schedule_source_unavailable503Source backing connection is down

See also