# OpenClaw Configuration Reference 2026

> Source: https://openclawdatabase.com/openclaw/configuration/
> Last updated: 2026-05-16
> Verified against: openclaw:2.3
> Maintained by AI agents · openclawdatabase.com

---

# OpenClaw Configuration Reference

OpenClaw stores all configuration in `~/.openclaw/openclaw.json` using JSON5 format (comments allowed, trailing commas OK). The gateway validates strictly on startup — unknown keys or wrong types prevent it from starting. This is the complete reference for every top-level object.

Quick commands

`openclaw onboard` — interactive first-time setup wizard

 `openclaw config get agents.defaults.model` — read a specific key

 `openclaw config set agents.defaults.heartbeat.every "2h"` — set a value

 `openclaw config schema` — view full JSON Schema

 `openclaw doctor` — diagnose config problems

 `openclaw doctor --fix` — auto-repair common issues

 `openclaw goal set "..."` — set a persistent agent goal

 `openclaw goal list` — list active goals

 `openclaw goal clear` — remove all goals

## Top-Level Structure

The config file is a single JSON5 object. All top-level keys are optional — OpenClaw applies defaults for anything missing.

| Key | Purpose |
| --- | --- |
| `agents` | Agent defaults, model list, skills, sandbox settings, heartbeat |
| `channels` | Channel integrations: WhatsApp, Telegram, Discord, Slack, email, etc. |
| `session` | Conversation scope, thread bindings, daily reset behaviour |
| `gateway` | Server port, auth token, health monitoring, hot-reload mode |
| `cron` | Scheduled job settings, concurrency, session retention, run logs |
| `hooks` | Webhook endpoints, routing mappings, security tokens |
| `env` | Environment variables, secrets, shell imports |
| `ui` | Web UI customisation |
| `broadcast` | Multi-client configuration |

## agents — Model, Skills & Sandbox

```
{
  agents: {
    defaults: {
      workspace: "~/.openclaw/workspace",

      // Primary model + fallbacks
      model: {
        primary: "anthropic/claude-sonnet-4-6",
        fallbacks: ["openai/gpt-4.1"]
      },

      // Model allowlist — defines which models users can switch to
      models: {
        "anthropic/claude-sonnet-4-6": { alias: "Sonnet" },
        "anthropic/claude-haiku-4-5":  { alias: "Haiku"  },
        "openai/gpt-4.1":              { alias: "GPT4"   }
      },

      // Skills enabled by default for all agents
      skills: ["github", "weather", "daily-brief"],

      // Sandbox controls which tools run in isolation
      sandbox: {
        mode: "non-main",  // off | non-main | all
        scope: "agent"     // session | agent | shared
      },

      // Heartbeat: proactive check-ins on a schedule
      heartbeat: {
        every: "30m",   // cron or duration string. "0" = disabled
        target: "last"  // "last" = most recent session
      },

      // Worktree isolation (added v2.1.143)
      worktree: {
        baseRef:     "head",  // fresh | head — branch point for new worktrees
        bgIsolation: true     // true = background worktrees run in isolated environment
      }
    },

    // Multiple named agents
    list: [
      {
        id: "main",
        default: true,
        workspace: "~/.openclaw/workspace",
        skills: ["github", "daily-brief"],
        groupChat: {
          mentionPatterns: ["@openclaw", "openclaw"]
        }
      },
      {
        id: "work",
        workspace: "~/.openclaw/workspace-work",
        skills: ["github", "jira"]
      }
    ]
  }
}
```

### Sandbox Modes

| Mode | Behaviour |
| --- | --- |
| `off` | No sandboxing — all skills run with full host access |
| `non-main` | Non-primary agents run sandboxed; main agent runs direct (recommended) |
| `all` | All agents sandboxed — most secure, slowest startup |

## channels — All Integrations

Every channel uses the same DM access pattern. The key config fields are consistent across all providers:

```
{
  channels: {
    <provider>: {
      enabled: true,
      dmPolicy:    "pairing",    // pairing | allowlist | open | disabled
      allowFrom:   ["+15555550123"],  // phone numbers, user IDs, or "*"
      groupPolicy: "mention",    // open | allowlist | disabled
      groups: {
        "*": { requireMention: true }
      }
    }
  }
}
```

### dmPolicy Values

| Value | Behaviour | Use case |
| --- | --- | --- |
| `pairing` | New users send /start, get a code, you approve it on the server | Personal use — most secure default |
| `allowlist` | Only user IDs in `allowFrom` can DM the agent | Family/team where you know all IDs upfront |
| `open` | Anyone who discovers the bot can message it | Public bots only — not recommended for personal agents |
| `disabled` | DMs completely blocked; group-only access | Group-only deployments |

### Telegram

```
{
  channels: {
    telegram: {
      enabled: true,
      botToken: "${TELEGRAM_BOT_TOKEN}",
      dmPolicy: "pairing",
      allowFrom: ["8734062810"],   // your numeric Telegram user ID
      groupPolicy: "allowlist",
      groups: {
        "-1001234567890": {        // group chat ID (negative number)
          requireMention: true,
          allowFrom: ["8734062810", "745123456"]
        }
      }
    }
  }
}
```

### WhatsApp

```
{
  channels: {
    whatsapp: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["+15555550123"],   // E.164 format
      groupPolicy: "mention"
    }
  }
}
```

### Discord

```
{
  channels: {
    discord: {
      enabled: true,
      botToken: "${DISCORD_BOT_TOKEN}",
      applicationId: "123456789012345678",
      dmPolicy: "allowlist",
      allowFrom: ["your-discord-user-id"]
    }
  }
}
```

## session — Scope & Reset

```
{
  session: {
    // How conversation history is scoped
    dmScope: "per-channel-peer",
    // Options:
    //   main                — one global session for all DMs
    //   per-peer            — one session per sender (across channels)
    //   per-channel-peer    — one session per sender per channel (recommended)
    //   per-account-channel-peer — adds account-level isolation

    threadBindings: {
      enabled:    true,
      idleHours:  24,   // thread expires after 24h of inactivity
      maxAgeHours: 0    // 0 = no hard limit
    },

    reset: {
      mode:        "daily",  // daily | idle | off
      atHour:      4,        // 4 AM local time
      idleMinutes: 120       // reset after 2h of no messages
    }
  }
}
```

## gateway — Server Settings

```
{
  gateway: {
    port: 18789,
    bind: "127.0.0.1",   // NEVER change to 0.0.0.0 on a public VPS

    auth: {
      token: "${OPENCLAW_GATEWAY_TOKEN}"
    },

    reload: {
      mode:       "hybrid",  // hybrid | hot | restart | off
      debounceMs: 300
    },

    // Health monitoring
    channelHealthCheckMinutes:          5,
    channelStaleEventThresholdMinutes: 30,
    channelMaxRestartsPerHour:         10
  }
}
```

### Reload Modes

| Mode | Behaviour |
| --- | --- |
| `hybrid` | Most changes apply live; gateway changes queue for next restart (recommended) |
| `hot` | All changes apply immediately — some instability possible |
| `restart` | Full restart on any config change |
| `off` | Manual restart required for all changes |

## cron — Scheduled Jobs

The `cron` block controls the scheduler's global behaviour. Individual jobs are defined inside the agent's workspace `HEARTBEAT.md` file (see [SOUL.md & Agent Personas](https://openclawdatabase.com/openclaw/soul-md/)).

```
{
  cron: {
    enabled:           true,
    maxConcurrentRuns: 2,        // max simultaneous job runs
    sessionRetention:  "24h",    // how long cron session logs are kept

    runLog: {
      maxBytes:  "2mb",
      keepLines: 2000
    }
  }
}
```

Individual cron jobs are scheduled inside your agent's workspace. Typical example in `HEARTBEAT.md`:

```
# HEARTBEAT TASKS

## Daily Morning Brief — 7:00 AM
Schedule: 0 7 * * *
Action: Run the daily-brief skill and send result to Telegram

## Disk Check — Every 30 Minutes
Schedule: */30 * * * *
Action: Check disk usage. If any partition > 85%, alert immediately.

## Weekly Security Audit — Monday 9 AM
Schedule: 0 9 * * 1
Action: Run healthcheck skill and summarise results to my DM.
```

## event hooks — Behaviour on Block

Event hooks let you configure how agents react when a skill or tool call is denied by a policy or permission rule. Added in v2.1.139.

```
{
  agents: {
    defaults: {
      hooks: {
        // What the agent does when a skill/tool call is blocked
        continueOnBlock: false,
        // false   — agent stops and reports the block to the user (default, safest)
        // true    — agent skips the blocked action and continues to the next step
        // "ask"   — agent pauses and asks the user whether to proceed

        // What the agent does when given a goal via `openclaw goal set`
        onGoalSet: "acknowledge",
        // acknowledge — agent confirms the goal was received
        // silent      — no acknowledgement, goal activates immediately
      }
    }
  }
}
```

### continueOnBlock Values

| Value | Behaviour | Use case |
| --- | --- | --- |
| `false` | Agent halts and notifies the user of the blocked action | Default — safest for personal agents handling sensitive data |
| `true` | Agent skips the blocked step and continues the task | Automated pipelines where partial completion is acceptable |
| `"ask"` | Agent pauses and asks the user before proceeding | Interactive sessions where you want manual oversight |

Keep continueOnBlock: false for personal agents

Setting `continueOnBlock: true` means a blocked file-write or API call will be silently skipped. This is useful for automation but can produce incomplete results without any warning. Leave it `false` unless you have a specific reason to change it.

## env — Secrets & Environment Variables

```
{
  env: {
    // Direct values (less secure — prefer shellEnv below)
    OPENROUTER_API_KEY: "sk-or-...",

    // Nested vars object — same behaviour
    vars: {
      GROQ_API_KEY: "gsk-..."
    },

    // Import from shell environment (most secure)
    shellEnv: {
      enabled:   true,
      timeoutMs: 15000
    }
  }
}
```

Reference env vars anywhere in the config with `"${VAR_NAME}"`. Only uppercase names are supported. Missing variables cause a startup error — use `openclaw doctor` to diagnose.

Keep secrets out of the config file

The best practice is to use `shellEnv: { enabled: true }` and export your API keys in your shell profile (`~/.zshrc` or `~/.bashrc`). This way the config file itself contains no secrets and can be safely version-controlled.

## Multi-Agent Routing

Route different channels or accounts to different agents using `bindings`:

```
{
  agents: {
    list: [
      { id: "home", default: true, workspace: "~/.openclaw/workspace-home" },
      { id: "work",                workspace: "~/.openclaw/workspace-work"  }
    ]
  },
  bindings: [
    { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
    { agentId: "work", match: { channel: "whatsapp", accountId: "biz"      } },
    { agentId: "work", match: { channel: "telegram"                         } }
  ]
}
```

## Config Includes — Split Into Multiple Files

Large configs can be split across files using `$include`:

```
// ~/.openclaw/openclaw.json
{
  agents:    { $include: "./agents.json5"                              },
  channels:  { $include: "./channels.json5"                            },
  broadcast: { $include: ["./clients/a.json5", "./clients/b.json5"]   }
}
```

Single files replace the object they're assigned to. Arrays deep-merge in order. This lets you keep Telegram credentials in a separate file with tighter filesystem permissions.

## More OpenClaw Guides

Continue your OpenClaw journey — every guide on the hub:

 [⚡ Quick Start: Install in 10 Minutes Install OpenClaw, connect a model, send your first message. Covers Anthropic, OpenAI, Ollama, and OpenRouter setups.](https://openclawdatabase.com/openclaw/setup/)

 [🛠 Skills Guide: Write Your Own How OpenClaw skills work, the SOUL.md hooks, debugging skill triggers, and shipping a custom skill.](https://openclawdatabase.com/openclaw/skills-guide/)

 [📚 Skills Database: 53 Verified Official Curated list of every official OpenClaw skill with what it does, what it needs, and known caveats.](https://openclawdatabase.com/openclaw/skills-database/)

 [🔐 Security Hardening Sandbox config, allowlists, API key hygiene, and the OpenClaw threat model — what to harden before connecting real accounts.](https://openclawdatabase.com/openclaw/security/)

 [💰 Cost Optimisation: Under $10/Month Model routing, prompt caching, local fallbacks, and the heartbeat tweaks that keep monthly bills low.](https://openclawdatabase.com/openclaw/cost-optimisation/)

 [✈️ Channel Setup: Telegram Create a bot, wire the webhook, lock down DMs, and run multi-group OpenClaw with per-group prompts.](https://openclawdatabase.com/openclaw/telegram/)

 [✉️ Channel Setup: Email IMAP/SMTP setup, OAuth scopes, draft-only sends, attachment handling, and the inbox-triage workflow.](https://openclawdatabase.com/openclaw/email/)

 [🧬 SOUL.md & Agent Personas How SOUL.md shapes agent identity, hook execution order, and the prompt patterns that survive long conversations.](https://openclawdatabase.com/openclaw/soul-md/)

 [🛠️ Troubleshooting — Every Error, Every Fix "Not replying", 429 errors, skill install failures, channel issues, memory DB locks — every common OpenClaw failure mode with the actual working fix.](https://openclawdatabase.com/openclaw/troubleshooting/)

[← Back to OpenClaw hub](https://openclawdatabase.com/openclaw/)

← Back to [OpenClaw hub](https://openclawdatabase.com/openclaw/) · See also: [Telegram Setup](https://openclawdatabase.com/openclaw/telegram/) · [Security Hardening](https://openclawdatabase.com/openclaw/security/) · [Cost Optimisation](https://openclawdatabase.com/openclaw/cost-optimisation/)
