Configuration Reference
~/.openclaw/openclaw.json
OpenClaw

CONFIGURATION GUIDE

Master your openclaw.json with copy-paste examples for every setting

openclaw.json
// JSON5 - comments allowed!
{
  identity: {
    name: "Clawd",
    emoji: "🦞",
  },
  agent: {
    workspace: "~/.openclaw/workspace",
  },
  channels: {
    whatsapp: { ... },
  },
}

JSON5 Format Supported

Quick Start

Phase 1: Install

CLI Installation

macOS / Linux
curl -fsSL https://openclaw.ai/install.sh | bash

This installs the openclaw CLI globally. Windows users use the PowerShell installer from our site.

Phase 2: Onboard

Setup Wizard
openclaw onboard --install-daemon

The wizard configures your first model, links your primary channel, and installs the gateway background service.

Recommended Manual Config (openclaw.json)

{
  identity: { name: "Samantha", emoji: "🦞" },
  agent: {
    workspace: "~/.openclaw/workspace",
    model: "anthropic/claude-sonnet-4-5"
  },
  channels: {
    whatsapp: { allowFrom: ["+15555550123"] }
  }
}

Save to ~/.openclaw/openclaw.json

Config Specs

JSON5 Format

Comments and trailing commas are fully supported for easier manual edits.

Strict Validation

Unknown keys or invalid types will prevent Gateway boot. Run openclaw doctor to debug.

Live Updates

Changes to openclaw.json require a Gateway restart, or use config.patch RPC.

🆔

Identity

Agent Identity

identity: {
  name: "Samantha",       // Agent display name
  theme: "helpful sloth",  // Personality theme
  emoji: "🦥",              // Used for reactions
  avatar: "avatars/sam.png", // Path or URL
}

Fields

nameDisplayed name, used for @mentions in groups
themePersonality descriptor injected into system prompt
emojiDefault ackReaction (👀 fallback)
avatarWorkspace path, http(s) URL, or data: URI
📄

Workspace Bootstrap Context

IDENTITY.md

Core persona, quirks, and relationship with Clawd.

SOUL.md

Deep behavioral traits and long-term goals.

USER.md

Known info about the user (preferences, style).

HEARTBEAT.md

Routine tasks run on thinking cycles.

* Files in your workspace are automatically injected into the system prompt to give the agent persistent context.

💬

Channels

📱

WhatsApp

QR Scan
whatsapp: {
  dmPolicy: "pairing",
  allowFrom: ["+1555..."],
  groupPolicy: "allowlist",
}
✈️

Telegram

Bot Token
telegram: {
  enabled: true,
  botToken: "123:ABC...",
  allowFrom: ["123456"],
}
🎮

Discord

Bot Token
discord: {
  enabled: true,
  token: "YOUR_TOKEN",
  dm: { allowFrom: ["user"] },
}
🏢

Slack

Bot + App Token
slack: {
  botToken: "xoxb-...",
  appToken: "xapp-...",
  channels: { "#gen": {...} },
}
🔒

Signal

Linked Device
signal: {
  enabled: true,
  groupPolicy: "allowlist",
  groupAllowFrom: ["+1..."],
}
💬

iMessage

macOS Native
imessage: {
  enabled: true,
  groupPolicy: "allowlist",
}

DM Policy Options

"pairing"

Unknown senders get pairing code; owner approves

"allowlist"

Only allow senders in allowFrom list

"open"

Allow all inbound DMs (requires "*" in allowFrom)

"disabled"

Ignore all inbound DMs

WhatsApp Full

Expanded WhatsApp Config

whatsapp: {
  dmPolicy: "pairing",
  allowFrom: ["+15555550123"],
  selfChatMode: false,
  groupPolicy: "allowlist",
  groups: { "*": { requireMention: true } },
  ackReaction: {
    emoji: "👀",
    direct: true,
    group: "mentions"
  },
  sendReadReceipts: true,
  textChunkLimit: 4000,
  mediaMaxMb: 50,
}

ackReaction: auto-react on receipt (👀, ✅, etc)

selfChatMode: for personal number setup

• Login: openclaw channels login

Discord Full

Expanded Discord Config

discord: {
  enabled: true,
  token: "YOUR_BOT_TOKEN",
  dm: {
    enabled: true,
    policy: "pairing",
    allowFrom: ["123456789"],
  },
  groupPolicy: "allowlist",
  guilds: {
    "YOUR_GUILD_ID": {
      slug: "my-server",
      requireMention: true,
      channels: {
        help: { allow: true },
      },
    },
  },
}

• Enable Message Content Intent in Dev Portal

guilds.*.requireMention for @mention gating

• Per-channel rules in guilds.*.channels

🤖

Agents

Single Agent Config

agent: {
  workspace: "~/.openclaw/workspace",
  model: { primary: "anthropic/claude-sonnet-4-5" },
  elevated: { enabled: true },
  heartbeat: { every: "30m", target: "last" },
}
Multi-Agent

Multiple Agents

agents: {
  defaults: { workspace: "~/.openclaw/workspace" },
  list: [
    { id: "main", default: true },
    { id: "work", workspace: "~/work-agent" },
  ],
}

Multi-Agent Routing (Bindings)

bindings: [
  {
    agentId: "work",
    match: { 
      channel: "whatsapp", 
      peer: { kind: "group", id: "123@g.us" } 
    }
  }
]

* Bindings map specific conversations to specific agents (separate workspaces, history, and tools).

Match Tiers (Priority order)

1

match.peer — Exact conversation/DM

2

match.guildId / teamId — Entire server/org

3

match.accountId — Specific bot/account

4

default agent — Fallback when no match wins

Agent Config Keys

workspace

Agent's working directory

model

Primary + fallback models

elevated

Allow elevated tool access

heartbeat

Periodic check-in config

🧠

Models & Auth

Model + Fallbacks

agent: {
  model: {
    primary: "anthropic/claude-sonnet-4-5",
    fallbacks: [
      "anthropic/claude-opus-4-6",
      "openai/gpt-5.2"
    ],
  },
}

Custom Provider (Local LLM)

models: {
  providers: {
    "local-llm": {
      baseUrl: "http://127.0.0.1:1234/v1",
      apiKey: "lmstudio",
      api: "openai-responses",
    },
  },
}

Two-Stage Failover System

1Auth Profile Rotation

OpenClaw rotates through auth profiles (OAuth → API keys) within the same provider on rate limits.

2Model Fallback

If all profiles fail, moves to next model in agents.defaults.model.fallbacks.

1 min

First cooldown

5 min

Second retry

25 min

Third retry

1 hour

Cap

Session Stickiness: Auth profiles are pinned per session (not rotated per request) to keep provider caches warm. Resets on /new, /reset, or compaction.
🔐

Sessions

⚠️

Security Warning: Multi-User DMs

If your agent receives DMs from multiple people, enable secure DM mode! Without it, all users share the same conversation context — Alice's private topics could leak to Bob.

session: { dmScope: "per-channel-peer" }

Basic Session Config

session: {
  scope: "per-sender",
  reset: { mode: "daily", atHour: 4 },
  resetTriggers: ["/new", "/reset"],
  typingIntervalSeconds: 5,
}
Secure DM

DM Scope + Identity Links

session: {
  dmScope: "per-channel-peer",
  identityLinks: {
    alice: ["telegram:123", "discord:987"],
  },
}

dmScope Options

"main"All DMs share main session (default, single-user)
"per-peer"Isolate by sender ID across all channels
"per-channel-peer"Isolate by channel + sender (recommended)
"per-account-channel-peer"Full isolation for multi-account inboxes

Reset Modes

"daily"Clears at specified atHour (0-23, default 4 AM)
"idle"Clears after idleMinutes of inactivity
"weekdays"Resets every Mon-Fri at atHour
"never"Only /reset or /new triggers reset

Advanced: Per-Type Reset Overrides

session: {
  dmScope: "per-channel-peer",
  reset: { mode: "daily", atHour: 4, idleMinutes: 120 },
  resetByType: {
    thread: { mode: "daily", atHour: 4 },
    dm: { mode: "idle", idleMinutes: 240 },
    group: { mode: "idle", idleMinutes: 120 },
  },
  resetByChannel: {
    discord: { mode: "idle", idleMinutes: 10080 },  // 7 days
  },
}

resetByType overrides default for dm/group/thread. resetByChannel overrides per channel. When both daily + idle are set, whichever expires first wins.

🔧

Tools & Elevated Mode

Tool Access Control

tools: {
  allow: ["exec", "read", "write", "edit"],
  deny: ["browser", "canvas"],
  elevated: {
    enabled: true,
    allowFrom: { whatsapp: ["+1555..."] },
  },
}
Multi-Channel

Elevated + Exec Config

tools: {
  elevated: {
    enabled: true,
    allowFrom: {
      whatsapp: ["+15555550123"],
      telegram: ["123456789"],
      discord: ["steipete"],
    },
  },
  exec: { backgroundMs: 10000, timeoutSec: 1800 },
}

/elevated Directives (Chat Commands)

/elevated onRun on gateway host, keep exec approvals
/elevated askSame as "on" — runs on host with approvals
/elevated fullRun on host + auto-approve exec (skip approval UI)
/elevated offDisable elevated mode (back to sandbox)
⚠️

Security: Elevated Mode

Elevated = host execution. When enabled, specified senders can run commands directly on your gateway host (rm, sudo, etc).

/elevated full skips approval prompts entirely. Only enable for fully trusted users.

Resolution order: inline directive → session override → global default (agents.defaults.elevatedDefault).

Common Tool Categories

exec

Run commands

read

Read files

write

Write files

edit

Edit files

browser

Web automation

web

HTTP requests

📦

Sandbox & Docker Isolation

Docker Isolation

Sandbox Config

sandbox: {
  mode: "non-main",
  scope: "session",
  docker: {
    image: "openclaw-sandbox:bookworm-slim",
    network: "none",
    readOnlyRoot: true,
  },
}

Sandbox Modes

"off"No isolation — runs directly on host
"non-main"Sandbox for groups/threads, host for main DM
"all"All sessions run inside Docker container

Scope Options

"session"One container per session (default, most isolated)
"agent"One container per agent (shared across sessions)
"shared"All agents share a single sandbox container

Tool Groups (Shorthands)

group:runtime

exec, bash, process

group:fs

read, write, edit, apply_patch

group:ui

browser, canvas

group:messaging

message, sessions_*

Use in tools.sandbox.tools.allow to restrict sandboxed agents.

⚙️

Automation & Hooks

Cron Jobs

Recurring Tasks (cron)

{
  "name": "Morning Brief",
  "schedule": { "kind": "cron", "expr": "0 8 * * *" },
  "sessionTarget": "isolated",
  "payload": { 
    "kind": "agentTurn", 
    "message": "Summarize today." 
  }
}

Persisted at ~/.openclaw/cron/jobs.json. Isolated jobs start a fresh session each run.

Gateway Hooks

Event-Driven Hooks

hooks: {
  internal: {
    enabled: true,
    entries: {
      "session-memory": { enabled: true }
    }
  }
}

session-memory

Save context on /new

command-logger

Audit trail of commands

Cron Schedule Kinds

  • "at": One-shot ISO timestamp
  • "every": Interval in milliseconds
  • "cron": 5-field cron expression

Target Sessions

  • "main": Run in your active chat
  • "isolated": Background agent run

Hook Discovery

OpenClaw scans workspace/hooks/ and ~/.openclaw/hooks/ for custom TypeScript hooks with a HOOK.md.
📊

Logging

logging: {
  level: "info",
  file: "/tmp/oc.log",
  consoleStyle: "pretty",
}

Levels: debug, info, warn, error

🌐

Gateway

gateway: {
  mode: "local",
  port: 18789,
  bind: "loopback",
}

Control UI: http://localhost:18789/openclaw

⚙️

Environment

Substitution & shellEnv
env: {
  OPENROUTER_API_KEY: "...",
  shellEnv: { enabled: true }
}

Variable Substitution

auth: { token: "${OPENCLAW_TOKEN}" }

Reference UPPERCASE env vars anywhere in your config. They are substituted at load time. Use $$${VAR} to escape.

🔑

Auth Profiles

auth: {
  profiles: {
    "anthropic:subscription": { mode: "oauth", email: "me@example.com" },
    "anthropic:api":          { mode: "api_key" },
    "openai:default":         { mode: "api_key" },
  },
  order: {
    anthropic: ["anthropic:subscription", "anthropic:api"],
    openai:    ["openai:default"],
  },
}
💡

Failover Order

Profiles in order are tried sequentially. OAuth subscriptions take priority, with API keys as fallback.