Configuration
All configuration options for ~/.openclaw/openclaw.json with examples
OpenClaw reads an optional JSON5 config from ~/.openclaw/openclaw.json (comments + trailing commas allowed).
If the file is missing, OpenClaw uses safe-ish defaults. You usually only need a config to:
- restrict who can trigger the bot (
channels.whatsapp.allowFrom,channels.telegram.allowFrom, etc.) - control group allowlists + mention behavior (
channels.whatsapp.groups,channels.telegram.groups,channels.discord.guilds,agents.list[].groupChat) - customize message prefixes (
messages) - set the agent's workspace (
agents.defaults.workspaceoragents.list[].workspace)
Tutorial.alert.info
Configuration File
The config file is ~/.openclaw/openclaw.json and uses JSON5 (not strict JSON).
For small changes, prefer incremental updates (e.g., config.patch) over full replacement.
Strict config validation
OpenClaw only accepts configurations that fully match the schema. Unknown keys, malformed types, or invalid values cause the Gateway to refuse to start for safety.
When validation fails:
- The Gateway does not boot.
- Only diagnostic commands are allowed (for example:
openclaw doctor,openclaw logs,openclaw health,openclaw status). - Run
openclaw doctorto see the exact issues. - Run
openclaw doctor --fix(or--yes) to apply migrations/repairs.
Doctor never writes changes unless you explicitly opt into --fix/--yes.
Schema + UI hints
The Gateway exposes a JSON Schema representation of the config via config.schema for UI editors.
The Control UI renders a form from this schema, with a **Raw JSON** editor as an escape hatch.
Plugins can register schema + UI hints (labels, grouping, sensitive fields) so clients can render better forms without hard-coding config knowledge.
Apply + restart (RPC)
Use config.apply to validate + write the full config and restart the Gateway in one step.
Warning: config.apply replaces the entire config. If you want to change only a few keys, use config.patch or openclaw config set. Keep a backup of ~/.openclaw/openclaw.json.
Params:
raw(string) β JSON5 payload for the entire configbaseHash(optional) β config hash fromconfig.get(required when a config already exists)sessionKey(optional) β last active session key for the wake-up pingnote(optional) β note to include in the restart sentinelrestartDelayMs(optional) β delay before restart (default 2000)
Example (via gateway call):
openclaw gateway call config.get --params '{}' # capture payload.hash
openclaw gateway call config.apply --params '{
"raw": "{\n agents: { defaults: { workspace: \"~/.openclaw/workspace\" } }\n}\n",
"baseHash": "<hash-from-config.get>",
"sessionKey": "agent:main:whatsapp:dm:+15555550123",
"restartDelayMs": 1000
}'Partial updates (RPC)
Use config.patch to merge a partial update into the existing config without clobbering unrelated keys. It applies JSON merge patch semantics:
Merge patch semantics:
- objects merge recursively
nulldeletes a key- arrays replace
Params:
raw(string) β JSON5 payload containing just the keys to changebaseHash(required) β config hash fromconfig.getsessionKey(optional) β last active session key for the wake-up pingnote(optional) β note to include in the restart sentinelrestartDelayMs(optional) β delay before restart (default 2000)
Example:
openclaw gateway call config.get --params '{}' # capture payload.hash
openclaw gateway call config.patch --params '{
"raw": "{\n channels: { telegram: { groups: { \"*\": { requireMention: false } } } }\n}\n",
"baseHash": "<hash-from-config.get>",
"sessionKey": "agent:main:whatsapp:dm:+15555550123",
"restartDelayMs": 1000
}'Minimal config (recommended starting point)
Set the workspace and restrict WhatsApp DMs to an allowlist:
{
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
channels: { whatsapp: { allowFrom: ["+15555550123"] } },
}Config Includes (<code>$include</code>)
Split your config into multiple files using the $include directive. This is useful for:
- Organizing large configs (e.g., per-client agent definitions)
- Sharing common settings across environments
- Keeping sensitive configs separate
Example:
// ~/.openclaw/openclaw.json
{
gateway: { port: 18789 },
agents: { $include: "./agents.json5" },
broadcast: { $include: ["./clients/mueller.json5", "./clients/schmidt.json5"] },
}Env vars + .env
OpenClaw reads env vars from the parent process (shell, launchd/systemd, CI, etc.). Additionally, it loads:
.envfrom the current working directory (if present)~/.openclaw/.env(aka$OPENCLAW_STATE_DIR/.env) as a global fallback.- Neither .env file overrides existing env vars.
You can also provide inline env vars in config. These are only applied if the process env is missing the key (same non-overriding rule):
{
env: {
OPENROUTER_API_KEY: "sk-or-...",
vars: { GROQ_API_KEY: "gsk-..." },
},
}See [/environment](/environment) for full precedence and sources.
Env var substitution in config
ReferenceGatewayConfigurationPage.steps.envSubstitution.p1
{
gateway: { auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" } },
models: { providers: { custom: { apiKey: "${CUSTOM_API_KEY}" } } },
}Rules:
- Only uppercase env var names are matched:
[A-Z_][A-Z0-9_]* - Missing or empty env vars throw an error at config load
- ReferenceGatewayConfigurationPage.steps.envSubstitution.rules.escape
- Works with
$include(included files also get substitution)
Auth storage (OAuth + API keys)
OpenClaw stores per-agent auth profiles (OAuth + API keys) in:
- Primary file:
<agentDir>/auth-profiles.json - Legacy import:
$OPENCLAW_STATE_DIR/credentials/oauth.json - Agent dir can be overridden via
OPENCLAW_AGENT_DIR(preferred) orPI_CODING_AGENT_DIR(legacy).
See also: [/concepts/oauth](/concepts/oauth)
Safety tips
- Back up
~/.openclaw/openclaw.jsonbefore major changes. - Use logging redaction to avoid leaking secrets (
logging.redactSensitive). - For multi-agent setups, use per-agent sandbox/tools policies. See [Multi-agent sandbox and tools](/concepts/sandbox#multi-agent).