OpenClaw Runbook

Chapter 4 of 8 · 10 min read

Heartbeat & Task Tracking

A rotating heartbeat that batches checks on a cheap model, plus Todoist integration for full visibility into what your agent is doing.

Part 1 · Rotating heartbeat

01A practical rotating heartbeat pattern #

The heartbeat is a system-owned automation: a periodic agent turn, every 30 minutes by default (1 hour on Anthropic OAuth), that surfaces anything needing attention. Its instructions live in a private monitor scratch in the state database. The old workspace HEARTBEAT.md is retired; openclaw doctor --fix imports it into scratch and archives the file.

OpenClaw's docs now recommend one automation per recurring check. That's right for anything that needs precise timing. For a pile of small, cheap checks, a single heartbeat that rotates through them based on how overdue each one is still batches better.

The idea is simple. Each check has a cadence (how often it should run), an optional time window (when it's allowed to run), and a record of when it last ran. On each heartbeat tick, the system runs whichever check is most overdue.

This batches background work, keeps costs flat, and avoids the "everything fires at once" problem.

Heartbeat model cost

Use the cheapest model you have access to. Heartbeats run often but do simple checks (read a file, check a condition). There's no reason to burn premium models here.

Heartbeat cost comparison at 48 beats a day
48 beats a dayPer day
GPT-5 Nano~$0.005/day
Claude Sonnet~$0.24/day

That's $0.15/month vs $7.20/month: a 48x difference for work that doesn't need a premium model. Prices move, so treat the numbers as illustrative; the ratio is the point.

02Heartbeat prompt template #

Copy and customize this prompt to have your agent build a rotating heartbeat system:

Prompt · give this to your agent
Build a rotating heartbeat check system in your heartbeat monitor scratch:

Create these checks with their cadences:
- Email: every 30 min (9 AM - 9 PM only)
- Calendar: every 2 hours (8 AM - 10 PM only)
- Tasks: every 30 min (anytime)
- Git: every 24 hours (anytime)
- System: every 24 hours (3 AM only)

Create heartbeat-state.json in the workspace to track last run timestamps.

On each heartbeat:
1. Read state file
2. Calculate which check is most overdue (respect time windows)
3. Run that check
4. Update timestamp in state file
5. Report only if check finds something actionable
6. Reply NO_REPLY if nothing needs attention

Check implementations:
- Email: Check [your email service] for new messages from authorized senders
- Calendar: Check [your calendar] for events in next 24-48h
- Tasks: Check [your task manager] for stalled/blocked work
- Git: Check workspace for uncommitted changes
- System: Check for failed automation runs and error logs

Write the checklist into your monitor scratch (heartbeat_respond with
"scratch", or openclaw cron scratch <jobId> --file). Keep it short and
keep secrets out of it: scratch becomes prompt context.

Adapt these to my specific services and tools.

03Example monitor scratch #

The resulting monitor scratch should look something like this:

monitor scratch · heartbeat.md
# Heartbeat checklist

## Cadence-Based Checks

Read `heartbeat-state.json`. Run whichever check is most overdue.

**Cadences:**
- Email: every 30 min (9 AM - 9 PM)
- Calendar: every 2 hours (8 AM - 10 PM)
- Tasks: every 30 min (anytime)
- Git: every 24 hours (anytime)
- System: every 24 hours (3 AM only)

**Process:**
1. Load timestamps from heartbeat-state.json
2. Calculate which check is most overdue (considering time windows)
3. Run that check
4. Update timestamp
5. Report if actionable, otherwise NO_REPLY

---

## Email Check

Check [your email service] for new messages.

**Report ONLY if:** New email from authorized sender, contains actionable request
**Update:** email timestamp in state file

---

## Calendar Check

Check [your calendar] for upcoming events.

**Report ONLY if:** Event starting in <2 hours, new event since last check
**Update:** calendar timestamp in state file

---

## Task Check

Check [your task manager] for work status.

**Report ONLY if:** Tasks stalled >24h, blocked tasks need attention
**Update:** tasks timestamp in state file

---

## Git Check

Check workspace git status.

**Report ONLY if:** Uncommitted changes exist, unpushed commits found
**Update:** git timestamp in state file

---

## System Check

Check for system issues.

**Report ONLY if:** Failed automation runs found, recent errors in logs
**Update:** system timestamp in state file

Load it from a file, or let the agent write it itself through heartbeat_respond. A scratch that's effectively empty (only headings or blank checklist items) skips the tick entirely and saves the API call.

bash · manage the scratch
openclaw cron list --all                 # find the "Heartbeat (<agent>)" job id
openclaw cron scratch <jobId> --file heartbeat.md
openclaw cron scratch <jobId>            # print what the heartbeat sees

04State file and heartbeat config #

The state file lives in the workspace and tracks when each check last ran:

heartbeat-state.json
{
  "lastChecks": {
    "email": 1703275200000,
    "calendar": 1703260800000,
    "tasks": 1703270000000,
    "git": 1703250000000,
    "system": 1703240000000
  }
}

And the heartbeat itself, pinned to a cheap model and kept small:

openclaw.json · heartbeat
"agents": {
  "defaults": {
    "heartbeat": {
      "every": "30m",
      "model": "openai/gpt-5.4-mini",
      "isolatedSession": true,
      "lightContext": true,
      "activeHours": { "start": "08:00", "end": "22:00" }
    }
  }
}

Alerts go to the owner's DM by default (target: "owner", resolved from commands.ownerAllowFrom). Set target: "none" for internal-only runs. If the agent replies NO_REPLY, nothing is sent; the legacy HEARTBEAT_OK is still accepted from older prompts.

05Why this pattern works #

Single heartbeat, multiple checks

Simpler than managing a separate automation per check.

Spreads load

Checks run when overdue, not all at once.

Cost-efficient

One cheap model does all the routing.

Debuggable

The state file shows exactly when each check last ran.

Quiet by default

NO_REPLY turns stay silent; only real findings reach your DMs.

Small prompts

Isolated, light-context runs send a few thousand tokens, not your whole history.

06Customizing the heartbeat #

Adjust cadences

  • High priority: 15–30 min
  • Medium priority: 1–2 hours
  • Low priority: 6–24 hours

Time windows

  • Email and calendar: waking hours
  • System checks: overnight
  • Git: anytime

Replace check types

  • Email → RSS feeds, webhooks
  • Calendar → project deadlines
  • Tasks → CI/CD status
  • Git → backup status
  • System → service health

07Alternative: one automation per check #

If you prefer explicit scheduling, give each check its own automation (openclaw automations, with openclaw cron kept as an alias). Each job gets its own cadence, model, enable/disable state and run history:

bash · one automation per check
# Email check: every 30 min, 9 AM - 9 PM
openclaw automations create "*/30 9-21 * * *" \
  "Check email for actionable messages from authorized senders." \
  --name "Email check" \
  --session isolated \
  --light-context \
  --model "openai/gpt-5.4-mini" \
  --announce

# Git check: daily at 3 AM
openclaw automations create "0 3 * * *" \
  "Check the workspace for uncommitted or unpushed changes." \
  --name "Git check" \
  --session isolated \
  --announce

openclaw automations runs <jobId>        # run history per check

Isolated automation runs are unattended: the agent replies NO_REPLY when nothing needs doing, so quiet checks stay quiet. The rotating heartbeat is better for many tiny checks and cost control. Separate automations are better for precise timing and per-check history.

Part 2 · Task tracking with Todoist

08Using Todoist for task visibility #

Early on, OpenClaw feels like a black box. You can't tell what it's doing, what it has finished, or what's stuck. The logs aren't enough.

The fix is wiring up Todoist as the source of truth for task state. Tasks get created when work starts, updated as state changes, assigned to you when human intervention is required, and closed when done. If something fails, the agent leaves a comment on the task instead of retrying forever.

A lightweight heartbeat reconciles what's open, what's in progress and what looks stalled. It's not sophisticated, but you can glance at Todoist and know exactly where things stand without digging through logs.

09Why task tracking? #

Without it you don't know what the agent is doing, what's stuck, or what needs your attention. A task tracking system makes all agent work visible in a tool you already check (Todoist, GitHub Projects, Linear and so on).

10Prerequisites #

Before giving the prompt to your agent, you need:

  1. 1Todoist accountFree or paid, at todoist.com.
  2. 2API tokenSettings → Integrations → Developer → API Token.
  3. 3ProjectsCreate Backlog/Queue, Active and optionally Waiting/Blocked projects.
  4. 4Credentials directorySecure storage for the API token.
bash · set up credentials
mkdir -p ~/.openclaw/credentials
echo "your-todoist-api-token-here" > ~/.openclaw/credentials/todoist
chmod 700 ~/.openclaw/credentials
chmod 600 ~/.openclaw/credentials/todoist

11Task tracking prompt template #

Copy and customize this prompt to give to your agent:

Prompt · task tracking system
Build a Todoist-based task tracking system for OpenClaw:

GOAL: Make agent work visible without checking logs. Glance at Todoist
and see exactly what's happening.

STATE MODEL:
- Queue/Backlog: Tasks waiting to start
- Active: Work currently in progress
- Waiting/Assigned to me: Blocked on human input
- Done: Completed

OPERATIONS NEEDED:
1. create_task(title, project) - Add task to queue/backlog
2. move_to_active(task_id) - Start work, move to Active project
3. assign_to_me(task_id, reason) - Mark blocked, assign with comment
4. complete_task(task_id) - Mark done and close
5. add_comment(task_id, status) - Add progress updates to task

RECONCILIATION (runs via heartbeat every 30 min):
- Find Active tasks with no updates >24 hours (stalled)
- List tasks assigned to me (need my attention)
- Report summary if issues found, otherwise NO_REPLY

TECHNICAL:
- Use Todoist REST API v1: https://api.todoist.com/api/v1/
- API Documentation: https://developer.todoist.com/api/v1/
- Python SDK: https://doist.github.io/todoist-api-python/
- TypeScript SDK: https://doist.github.io/todoist-api-typescript/
- Store API token in ~/.openclaw/credentials/todoist
- Handle API rate limits gracefully

VISIBILITY:
I should open Todoist and immediately understand:
- What the agent is working on right now
- What's waiting for me
- What's stuck
- What's been completed

Adapt this to my Todoist setup.

12Expected behavior #

Once built, the system should:

  • Auto-create tasks when the agent starts work
  • Update task status as work progresses
  • Assign to you when blocked on input
  • Add comments with progress updates
  • Complete tasks when done
  • Report stalled work via heartbeat reconciliation

13Customizing task tracking #

Alternative task managers

  • GitHub Projects: use the GitHub Projects API
  • Linear: use the Linear API
  • Notion: use the Notion database API
  • Asana: use the Asana API

State model variations

  • Simpler: Queue → Active → Done (no waiting state)
  • More complex: Queue → Active → Review → Waiting → Done
  • Kanban-style: To Do → In Progress → Blocked → Done

Reconciliation frequency

  • More aggressive: every 15 minutes
  • Less aggressive: every hour
  • Time-windowed: only during work hours

14Troubleshooting #

Agent not creating tasks

  • Verify the API token is correct
  • Check the credentials file holds the raw token (no ENV format)
  • Ensure the projects exist or the agent has permission to create them

Tasks stuck in Active

  • Check reconciliation is running: openclaw system heartbeat last
  • Look for stalled task reports
  • Move tasks manually if needed

Rate limit errors

  • The Todoist API has rate limits (consult the docs)
  • Add exponential backoff to error handling
  • Reduce reconciliation frequency if needed

15Alternative approaches #

Instead of building from scratch, you can:

  1. Look for inspiration. Browse community skills for task management patterns, but don't install them blindly.
  2. Have your agent build it. Use the prompt above and let your agent create the system.
  3. Integrate with existing tools such as GitHub Issues or Jira.
  4. Build your own state tracking: file-based, a database, and so on.

What matters is making agent work visible, not the specific tool.

Adapted from digitalknk/openclaw-runbook. OpenClaw changes fast: check the official docs before copying config into production.