Problem: Your AI Assistant Only Works When You Remember to Ask It
You set up OpenClaw, but it sits there waiting for commands. You want morning briefings, automatic inbox checks, and proactive reminders—the stuff that makes AI feel genuinely useful.
You'll learn:
- How Heartbeat makes OpenClaw proactive (not reactive)
- Set up automated check-ins every 30 minutes
- Create a HEARTBEAT.md checklist your agent follows
Time: 15 min | Level: Intermediate
Why This Matters
Traditional AI assistants are reactive—they wait for you to type something. OpenClaw's Heartbeat feature flips this model: your agent wakes up on a schedule, reviews its context, and decides if something needs your attention.
Real-world use cases:
- Morning briefing with unread emails, calendar events, weather
- Monitor inbox every 30 minutes, surface urgent messages
- Check flight status 12 hours before departure
- Daily standup summary from your team's Slack channels
How it works: Every X minutes (default 30), the Gateway sends your agent a heartbeat prompt. The agent reads HEARTBEAT.md in its workspace, checks for pending tasks, and either sends HEARTBEAT_OK (silent) or messages you.
Solution
Step 1: Verify Your Gateway Is Running
Heartbeats only work when the OpenClaw Gateway is active.
# Check Gateway status
openclaw gateway status
Expected: Should show Gateway is running on port 18789
If not running:
# Start Gateway as a background service
openclaw gateway --port 18789 --daemon
Step 2: Configure Heartbeat Interval
Edit your OpenClaw config file (usually ~/.openclaw/config.json or .openclaw.config.json in your project).
{
"agents": {
"defaults": {
"heartbeat": {
"every": "30m", // How often agent checks in
"model": "anthropic/claude-sonnet-4-5",
"target": "last", // Send to last used channel
"prompt": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.",
"ackMaxChars": 300 // Max chars in non-urgent messages
}
}
}
}
Why this works: every: "30m" tells the Gateway to wake your agent every 30 minutes. The agent then reads HEARTBEAT.md to know what to check.
Duration format: 1h, 45m, 2h30m all work. Set to 0m to disable.
Step 3: Create Your HEARTBEAT.md Checklist
This file lives in your agent's workspace (typically ~/.openclaw/workspace/HEARTBEAT.md).
# Create the file
cd ~/.openclaw/workspace
nano HEARTBEAT.md
Example checklist:
# Heartbeat Checklist
## Morning (8:00-8:30 AM)
- Check Gmail for urgent messages (subject contains "URGENT" or from boss)
- Pull today's calendar events
- Get local weather
- Send formatted morning briefing to Telegram
## Throughout Day (9 AM - 6 PM)
- Scan inbox every 30 min, surface emails from VIPs only
- If any calendar event starts in <15 min, remind me
## Evening (6:00 PM)
- Summarize unread Slack messages from #engineering channel
- Check if any tasks in Todoist are overdue
## Anytime
- If flight is <12 hours away, check status and send update
- Don't message me outside 8 AM - 10 PM unless flagged URGENT
Save and exit: Ctrl+X, then Y, then Enter
Step 4: Set Active Hours (Optional but Recommended)
Prevent late-night notifications by configuring active hours.
{
"agents": {
"defaults": {
"heartbeat": {
"every": "30m",
"activeHours": {
"start": "08:00",
"end": "22:00"
}
}
}
},
"timezone": "America/New_York" // Set your timezone
}
How it works: Heartbeats only run during activeHours in your configured timezone. Outside this window, the agent stays quiet.
Step 5: Test Your Heartbeat
Force an immediate heartbeat to verify setup.
# Trigger a manual heartbeat
openclaw message send --system '{"event": "heartbeat"}'
Expected: Within a few seconds, you should see either:
- A message in your configured channel (if something needed attention)
- Nothing (if agent determined
HEARTBEAT_OK)
Check logs for confirmation:
openclaw logs --tail 20
Look for: [Heartbeat] Agent processed heartbeat → HEARTBEAT_OK or similar.
Step 6: Route Heartbeats to a Specific Channel
By default, heartbeats go to your "last used" channel. For dedicated heartbeat messages, target a specific channel.
{
"agents": {
"defaults": {
"heartbeat": {
"every": "30m",
"target": "telegram", // Or "whatsapp", "discord", etc.
"to": "+15551234567", // Your phone number or chat ID
"accountId": "personal-bot" // For multi-account channels
}
}
}
}
Multi-agent example:
{
"agents": {
"list": [
{
"id": "personal",
"default": true
},
{
"id": "work",
"heartbeat": {
"every": "1h",
"target": "slack",
"to": "@yourself",
"prompt": "Check #engineering channel for mentions of my name. If nothing urgent, HEARTBEAT_OK."
}
}
]
}
}
Verification
After 30 minutes (or your configured interval):
You should see:
- A message in your configured channel if tasks were found
- Silence if nothing needed attention (check logs to confirm
HEARTBEAT_OKwas sent)
Test the full cycle:
- Add an urgent email to your inbox
- Wait for the next heartbeat (or trigger manually)
- Verify the agent surfaces it
Advanced: Dynamic Heartbeat Updates
Your agent can modify HEARTBEAT.md on the fly based on new tasks.
Example conversation:
You: "Add a daily check for my GitHub PRs that need review"
Agent: [Updates HEARTBEAT.md]
"Done. I'll now check your GitHub notifications during heartbeats and flag PRs awaiting your review."
How to enable: In your heartbeat prompt, add:
{
"prompt": "Read HEARTBEAT.md. Follow it strictly. If the checklist becomes stale or I ask you to modify it, update HEARTBEAT.md accordingly."
}
Safety note: Don't put API keys, passwords, or private tokens in HEARTBEAT.md—it's loaded into the prompt context.
What You Learned
- Heartbeat turns OpenClaw from reactive to proactive using scheduled check-ins
HEARTBEAT.mdis a human-readable task list your agent follows- Active hours prevent 3 AM notifications about non-urgent tasks
- Agents send
HEARTBEAT_OKwhen nothing needs attention (no spam)
Key difference from cron: Cron runs tasks blindly. Heartbeat thinks about whether something matters right now based on full context.
Limitation: Heartbeats consume tokens on every wake-up. On Claude Opus 4.5, expect $5-30/day depending on frequency and context size.