OpenClawSkills
GitHub
Automation β€’ TutorialHeader.readTime

Cron Jobs

Gateway scheduler cron jobs + wake.

Tutorial.alert.info

''Cron vs Heartbeat?'' See ''Cron vs Heartbeat'' for a guide on when to use each.

Cron is the gateway's built-in scheduler. It holds jobs, wakes the agent

at the right time, and can optionally pipe output back to chat.

If you want _"run this every morning"_ or _"poke the agent in 20 minutes"_,

cron is the mechanism.

Tutorial.step

The long and short; TL;DR

- Cron runs <strong>inside the gateway</strong> (not inside the model).

- Jobs persist under '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'~/.openclaw/cron/'</code>', so restarts don't lose schedules.

- Two execution modes:

- <strong>Main session</strong>: queues a system event, then runs at the next heartbeat.

- '<strong>'Isolated'</strong>': runs a dedicated agent turn in '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron:&lt;jobId&gt;'</code>', optionally delivering output.

- Wake is first-class: jobs can request "wake now" vs "next heartbeat".

Tutorial.step

Quickstart (actionable)

Create a one-time reminder, verify it exists, and run it immediately:

Bash
openclaw cron add   --name "Reminder"   --at "2026-02-01T16:00:00Z"   --session main   --system-event "Reminder: check the cron docs draft"   --wake now   --delete-after-run

openclaw cron list
openclaw cron run <job-id> --force
openclaw cron runs --id <job-id>

Schedule a repeating isolated job with delivery:

Bash
openclaw cron add   --name "Morning brief"   --cron "0 7 * * *"   --tz "America/Los_Angeles"   --session isolated   --message "Summarize overnight updates."   --deliver   --channel slack   --to "channel:C1234567890"
Tutorial.step

Tool call equivalents (gateway cron tools)

See '<a href="/automation/cron-jobs#json-schema-for-tool-calls" className="text-emerald-400 hover:text-emerald-300 transition-colors">'JSON schema for tool calls'</a>' for the canonical JSON shape and examples.

Tutorial.step

Where cron jobs are stored

By default, cron jobs persist on the gateway host at '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'~/.openclaw/cron/jobs.json'</code>'.

The gateway loads the file into memory and writes it back on changes, so manual editing

is only safe when the gateway is stopped. Prefer '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'openclaw cron add/edit'</code>' or cron

tool call APIs for changes.

Tutorial.step

Beginner-friendly overview

Think of a cron job as: <strong>when</strong> to run + <strong>what</strong> to do.

1. <strong>Pick a schedule</strong>

- One-time reminder β†’ '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'schedule.kind = &quot;at&quot;'</code>' (CLI: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--at'</code>')

- Repeating job β†’ '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'schedule.kind = &quot;every&quot;'</code>' or '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'schedule.kind = &quot;cron&quot;'</code>'

- If your ISO timestamp omits a timezone, it's treated as <strong>UTC</strong>.

2. <strong>Pick where to run</strong>

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'sessionTarget: &quot;main&quot;'</code>' β†’ runs in main context during next heartbeat.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'sessionTarget: &quot;isolated&quot;'</code>' β†’ runs a dedicated agent turn in '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron:&lt;jobId&gt;'</code>'.

3. <strong>Pick a payload</strong>

- Main session β†’ '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'payload.kind = &quot;systemEvent&quot;'</code>'

- Isolated session β†’ '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'payload.kind = &quot;agentTurn&quot;'</code>'

Optional: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deleteAfterRun: true'</code>' removes a successful one-time job from storage.

Tutorial.step

Concepts

#

Tutorial.step

Jobs

A cron job is a stored record of:

- a <strong>schedule</strong> (when to run),

- a <strong>payload</strong> (what it should do),

optional <strong>delivery</strong> (where output should be sent).

- optional '<strong>'agent binding'</strong>' ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agentId'</code>'): run the job under a specific agent; if

missing or unknown, the gateway falls back to the default agent.

Jobs are identified by a stable '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'jobId'</code>' (used by CLI/gateway API).

In agent tool calls, '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'jobId'</code>' is canonical; legacy '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'id'</code>' is accepted for compatibility.

Jobs can optionally auto-delete after a successful one-time run via '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deleteAfterRun: true'</code>'.

#

Tutorial.step

Schedules

Cron supports three schedule types:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'at'</code>': one-time timestamp (milliseconds since epoch). Gateway accepts ISO 8601 and coerces to UTC.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'every'</code>': fixed interval (milliseconds).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron'</code>': 5-field cron expression with optional IANA timezone.

Cron expressions use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'croner'</code>'. If timezone is omitted, the gateway host's

local timezone is used.

#

Tutorial.step

Main vs Isolated execution

##

Tutorial.step

Main session jobs (system events)

Main jobs queue a system event and optionally wake the heartbeat runner.

They must use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'payload.kind = &quot;systemEvent&quot;'</code>'.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'wakeMode: &quot;next-heartbeat&quot;'</code>' (default): event waits for the next scheduled heartbeat.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'wakeMode: &quot;now&quot;'</code>': event triggers an immediate heartbeat run.

This is best when you want a normal heartbeat prompt + main session context.

See '<a href="/gateway/heartbeat" className="text-emerald-400 hover:text-emerald-300 transition-colors">'Heartbeat'</a>'.

##

Tutorial.step

Isolated jobs (dedicated cron sessions)

Isolated jobs run a dedicated agent turn in session '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron:&lt;jobId&gt;'</code>'.

Key behaviors:

- Prompts are prefixed with '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'[cron:&lt;jobId&gt; &lt;job name&gt;]'</code>' for traceability.

- Each run starts a <strong>new session ID</strong> (no prior conversation carryover).

- Summary is posted to main session (prefix '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'Cron'</code>', configurable).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'wakeMode: &quot;now&quot;'</code>' triggers heartbeat immediately after posting summary.

- If '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'payload.deliver: true'</code>', output is delivered to channel; otherwise it stays internal.

Use isolated jobs for noisy, frequent, or "background chores" that shouldn't spam

your main chat history.

#

Tutorial.step

Payload shapes (what runs)

Two payload types are supported:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'systemEvent'</code>': main session only, routed via heartbeat prompt.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agentTurn'</code>': isolated session only, runs a dedicated agent turn.

Common '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agentTurn'</code>' fields:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'message'</code>': required text prompt.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'model'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'thinking'</code>': optional overrides (see below).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'timeoutSeconds'</code>': optional timeout override.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deliver'</code>': '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'true'</code>' sends output to channel target.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>': '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'last'</code>' or specific channel.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>': channel-specific target (phone/chat/channel ID).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'bestEffortDeliver'</code>': avoid job failure on delivery failure.

Isolation options (only for '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'session=isolated'</code>'):

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'postToMainPrefix'</code>' (CLI: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--post-prefix'</code>'): prefix for system event in main.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'postToMainMode'</code>': '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'summary'</code>' (default) or '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'full'</code>'.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'postToMainMaxChars'</code>': max characters when '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'postToMainMode=full'</code>' (default 8000).

#

Tutorial.step

Model and thinking overrides

Isolated jobs ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agentTurn'</code>') can override model and thinking level:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'model'</code>': provider/model string (e.g., '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'anthropic/claude-sonnet-4-20250514'</code>') or alias (e.g., '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'opus'</code>')

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'thinking'</code>': thinking level ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'off'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'minimal'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'low'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'medium'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'high'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'xhigh'</code>'; GPT-5.2 + Codex models only)

Note: You can also set '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'model'</code>' on a main session job, but it changes the shared main

session model. We recommend model overrides only for isolated jobs to avoid

unexpected context changes.

Resolution priority:

1. Job payload override (highest)

2. Hook-specific defaults (e.g., '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail.model'</code>')

3. Agent config defaults

#

Tutorial.step

Delivery (channel + target)

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>': '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'whatsapp'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'telegram'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'discord'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'slack'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'mattermost'</code>' (plugin) / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'signal'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'imessage'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'last'</code>'

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>': channel-specific recipient target

If '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>' or '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>' are omitted, cron can fall back to the main session's "last route"

(where the agent last replied).

Delivery notes:

- If '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>' is set, cron automatically delivers the agent's final output even if '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deliver'</code>' is omitted.

- Use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deliver: true'</code>' when you want last-route delivery without an explicit '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>'.

- Use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deliver: false'</code>' to keep output internal even if '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>' is present.

Target format reminders:

- Slack/Discord/Mattermost (plugin) targets should use explicit prefixes (e.g., '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel:&lt;id&gt;'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'user:&lt;id&gt;'</code>') to avoid ambiguity.

- Telegram topics should use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">':topic:'</code>' format (see below).

##

Tutorial.step

Telegram delivery targets (topics/forum threads)

Telegram supports forum topics via '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'message_thread_id'</code>'. For cron delivery, you can encode

the topic/thread into the '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>' field:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'-1001234567890'</code>' (chat ID only)

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'-1001234567890:topic:123'</code>' (preferred: explicit topic marker)

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'-1001234567890:123'</code>' (shorthand: numeric suffix)

Prefixed targets like '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'telegram:...'</code>' / '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'telegram:group:...'</code>' are also accepted:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'telegram:group:-1001234567890:topic:123'</code>'

Tutorial.step

JSON schema for tool calls

ReferenceAutomationCronJobsPage step 16: P1

ReferenceAutomationCronJobsPage step 16: P2

ReferenceAutomationCronJobsPage step 16: Content

Tutorial.step

Examples

One-time reminder:

Json
{
  "name": "Reminder",
  "schedule": { "kind": "at", "atMs": 1738262400000 },
  "sessionTarget": "main",
  "wakeMode": "now",
  "payload": { "kind": "systemEvent", "text": "Reminder text" },
  "deleteAfterRun": true
}

Repeating, isolated delivery job:

Json
{
  "name": "Morning brief",
  "schedule": { "kind": "cron", "expr": "0 7 * * *", "tz": "America/Los_Angeles" },
  "sessionTarget": "isolated",
  "wakeMode": "next-heartbeat",
  "payload": {
    "kind": "agentTurn",
    "message": "Summarize overnight updates.",
    "deliver": true,
    "channel": "slack",
    "to": "channel:C1234567890",
    "bestEffortDeliver": true
  },
  "isolation": { "postToMainPrefix": "Cron", "postToMainMode": "summary" }
}

Notes:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'schedule.kind'</code>': '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'at'</code>' ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'atMs'</code>'), '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'every'</code>' ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'everyMs'</code>') or '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron'</code>' ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'expr'</code>', optional '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'tz'</code>').

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'atMs'</code>' and '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'everyMs'</code>' are epoch milliseconds.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'sessionTarget'</code>' must be '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'&quot;main&quot;'</code>' or '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'&quot;isolated&quot;'</code>' and must match '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'payload.kind'</code>'.

- Optional fields: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agentId'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'description'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'enabled'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deleteAfterRun'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'isolation'</code>'.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'wakeMode'</code>' defaults to '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'&quot;next-heartbeat&quot;'</code>' when omitted.

#

Tutorial.step

cron.update parameters

Json
{
  "jobId": "job-123",
  "patch": {
    "enabled": false,
    "schedule": { "kind": "every", "everyMs": 3600000 }
  }
}

Notes:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'jobId'</code>' is canonical; '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'id'</code>' is accepted for compatibility.

- Use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agentId: null'</code>' in patch to clear agent binding.

#

Tutorial.step

cron.run and cron.remove parameters

Json
{ "jobId": "job-123", "mode": "force" }
Json
{ "jobId": "job-123" }
Tutorial.step

Storage and history

- Job storage: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'~/.openclaw/cron/jobs.json'</code>' (gateway-managed JSON).

- Run history: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'~/.openclaw/cron/runs/&lt;jobId&gt;.jsonl'</code>' (JSONL, auto-trimmed).

- Override storage path in config: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.store'</code>'.

Tutorial.step

Configuration

Json5
{
  cron: {
    enabled: true, // default true
    store: "~/.openclaw/cron/jobs.json",
    maxConcurrentRuns: 1, // default 1
  },
}

Disable cron entirely:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.enabled: false'</code>' (config)

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'OPENCLAW_SKIP_CRON=1'</code>' (environment)

Tutorial.step

CLI quickstart

One-time reminder (UTC ISO, auto-delete after success):

Bash
openclaw cron add   --name "Send reminder"   --at "2026-01-12T18:00:00Z"   --session main   --system-event "Reminder: submit expense report."   --wake now   --delete-after-run

One-time reminder (main session, immediate wake):

Bash
openclaw cron add   --name "Calendar check"   --at "20m"   --session main   --system-event "Next heartbeat: check calendar."   --wake now

Repeating isolated job (send to WhatsApp):

Bash
openclaw cron add   --name "Morning status"   --cron "0 7 * * *"   --tz "America/Los_Angeles"   --session isolated   --message "Summarize inbox + calendar for today."   --deliver   --channel whatsapp   --to "+15551234567"

Repeating isolated job (send to Telegram topic):

Bash
openclaw cron add   --name "Nightly summary (topic)"   --cron "0 22 * * *"   --tz "America/Los_Angeles"   --session isolated   --message "Summarize today; send to the nightly topic."   --deliver   --channel telegram   --to "-1001234567890:topic:123"

Isolated job with model and thinking overrides:

Bash
openclaw cron add   --name "Deep analysis"   --cron "0 6 * * 1"   --tz "America/Los_Angeles"   --session isolated   --message "Weekly deep analysis of project progress."   --model "opus"   --thinking high   --deliver   --channel whatsapp   --to "+15551234567"

Agent selection (multi-agent setup):

Bash
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops


openclaw cron edit <jobId> --agent ops
openclaw cron edit <jobId> --clear-agent

Manual run (debugging):

Bash
openclaw cron run <jobId> --force

Edit existing job (patch fields):

Bash
openclaw cron edit <jobId>   --message "Updated prompt"   --model "opus"   --thinking low

Run history:

Bash
openclaw cron runs --id <jobId> --limit 50

System event immediately without creating a job:

Bash
openclaw system event --mode now --text "Next heartbeat: check battery."
Tutorial.step

Gateway API

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.list'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.status'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.add'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.update'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.remove'</code>'

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.run'</code>' (force or due), '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.runs'</code>'

For immediate system events without a job, use '<a href="/cli/system" className="text-emerald-400 hover:text-emerald-300 transition-colors">''<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'openclaw system event'</code>''</a>'.

Tutorial.step

Troubleshooting

#

Tutorial.step

"Nothing runs"

- Check if cron is enabled: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron.enabled'</code>' and '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'OPENCLAW_SKIP_CRON'</code>'.

- Check that gateway is running continuously (cron runs inside the gateway process).

- For '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'cron'</code>' schedules: confirm timezone ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'--tz'</code>') matches host timezone.

#

Tutorial.step

Telegram sends to wrong place

- For forum topics, use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'-100…:topic:&lt;id&gt;'</code>' to be explicit and unambiguous.

- If you see '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'telegram:...'</code>' prefixes in logs or stored "last route" targets, this is normal;

cron delivery accepts them and still parses topic IDs correctly.