Skip to content

Getting Started with OpenClaw Configuration

We’ve all been there—staring at a blank configuration file, wondering why an application won’t start. It is frustrating when you have to dig through pages of settings just to change one simple path or an API key. I prefer tools that give me a clear path forward without making me guess the syntax or hidden file locations.

OpenClaw handles this by using a central JSON5 file. It is strict enough to catch mistakes early but flexible enough to let you edit it however you prefer.

  • OpenClaw installed on your system
  • A basic understanding of JSON5 (which allows you to use comments and trailing commas)

If you want to get moving in under five minutes, I recommend the interactive route. Run this command in your terminal:

Terminal window
openclaw onboard

This wizard handles the full setup for you. If you prefer to write your own file, OpenClaw looks for an optional config at ~/.openclaw/openclaw.json. Here is a minimal example to get your workspace and communication channels ready:

~/.openclaw/openclaw.json
{
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
channels: { whatsapp: { allowFrom: ["+15555550123"] } },
}

You have four ways to manage these settings:

  1. The CLI: You can run one-liners like openclaw config set agents.defaults.heartbeat.every "2h" or openclaw config get agents.defaults.workspace.
  2. Control UI: Open http://127.0.0.1:18789 in your browser and use the Config tab for a visual form.
  3. Direct Editing: Open ~/.openclaw/openclaw.json in your editor. The Gateway watches for changes and applies them automatically.
  4. Config Wizard: Run openclaw configure for a guided experience.

OpenClaw uses strict validation. If you have an unknown key, a malformed type, or an invalid value, the Gateway will refuse to start. This prevents weird bugs later, but it can be annoying if you don’t know what is wrong.

If the Gateway does not boot, try these steps:

  • Run openclaw doctor to see the exact validation issues.
  • Run openclaw doctor --fix (or --yes) to let the tool automatically repair the config.
  • Check your status with openclaw logs or openclaw status.
  • Use openclaw health to verify the environment.

If you run into a specific error or need help with a complex field, check in with the AI Setup Assistant.

I’ve spent many late nights wrestling with bot configurations that feel more like a puzzle than a tool. Usually, you just want to get a bot running on Telegram or WhatsApp without reading a hundred pages of API docs. I’ve found that keeping things modular and clear from the start makes everything easier to manage as your setup grows.

Here is how I handle the most common tasks when setting up the gateway.

  • A functional installation of the gateway.
  • API credentials for your chosen channels (like a Telegram botToken).
  • Docker installed (if you plan on using sandboxing).
  • A configuration file (like openclaw.json5).

If you want to get up and running in five minutes, focus on these two steps: pick your channel and set your model.

Each channel lives under its own section in channels.<provider>. For a Telegram bot, your config looks like this:

{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing", // options: pairing | allowlist | open | disabled
allowFrom: ["tg:123"], // used for allowlist/open
},
},
}

You can find specific setup steps for other providers here:

I recommend setting a primary model and a fallback so you aren’t stuck if a provider goes down.

{
agents: {
defaults: {
model: {
primary: "anthropic/claude-sonnet-4-5",
fallbacks: ["openai/gpt-5.2"],
},
models: {
"anthropic/claude-sonnet-4-5": { alias: "Sonnet" },
"openai/gpt-5.2": { alias: "GPT" },
},
},
},
}

Model refs use the provider/model format. You can check the Models CLI for switching models in chat or Model Failover for auth rotation details.


You control DM access per channel using the dmPolicy field:

  • "pairing": This is the default. Unknown senders get a one-time pairing code.
  • "allowlist": Only senders listed in allowFrom get through.
  • "open": Everyone can talk to the bot (requires allowFrom: ["*"]).
  • "disabled": The bot ignores all DMs.

For group chats, check the full reference for groupPolicy and groupAllowFrom.

By default, group messages require a mention. I configure specific patterns for my agents like this:

{
agents: {
list: [
{
id: "main",
groupChat: {
mentionPatterns: ["@openclaw", "openclaw"],
},
},
],
},
channels: {
whatsapp: {
groups: { "*": { requireMention: true } },
},
},
}

This supports native @-mentions (like Telegram @bot) and custom text patterns via regex.


Sessions keep your conversations isolated. I usually recommend the per-channel-peer scope for multi-user environments.

{
session: {
dmScope: "per-channel-peer",
reset: {
mode: "daily",
atHour: 4,
idleMinutes: 120,
},
},
}

Check Session Management for more on identity links and send policies.

If you want to run agent sessions in isolated Docker containers, use the sandbox config. You need to build the image first using scripts/sandbox-setup.sh.

{
agents: {
defaults: {
sandbox: {
mode: "non-main", // options: off | non-main | all
scope: "agent", // options: session | agent | shared
},
},
},
}

See the Sandboxing guide for the full walkthrough.

I use heartbeats to make sure the bot stays active.

{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last",
},
},
},
}

For automated tasks, you can enable cron jobs:

{
cron: {
enabled: true,
maxConcurrentRuns: 2,
sessionRetention: "24h",
},
}

Details are available in the Cron jobs documentation.

You can enable HTTP webhook endpoints to let external services trigger actions.

{
hooks: {
enabled: true,
token: "shared-secret",
path: "/hooks",
mappings: [
{
match: { path: "gmail" },
action: "agent",
agentId: "main",
deliver: true,
},
],
},
}

You can run multiple isolated agents with their own workspaces. I use this to separate home and work tasks.

{
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" } },
],
}

When your config gets too large, use $include to split it into multiple files.

~/.openclaw/openclaw.json
{
gateway: { port: 18789 },
agents: { $include: "./agents.json5" },
broadcast: {
$include: ["./clients/a.json5", "./clients/b.json5"],
},
}
  • Single file: Replaces the object.
  • Array of files: Deep-merged in order.
  • Sibling keys: These override included values.
  • Relative paths: Resolved based on the including file’s location.
  • Missing Files in $include: The gateway will throw a clear error if a file is missing or if there is a circular include.
  • JSON Parse Errors: If your split files have syntax errors, the gateway will fail to start and point to the specific file.
  • Unresponsive Bot in Groups: Double-check your mentionPatterns. If requireMention is true and your pattern doesn’t match, the bot will ignore the message.
  • Sandbox Failures: Ensure you have run scripts/sandbox-setup.sh before enabling mode: "non-main".

If you need more help with your specific configuration, try the AI Setup Assistant.

I hate it when I change a single line in a configuration file and have to manually kill the process and restart it. It breaks my flow and makes testing feel slow. If you feel the same way, you will like how the Gateway handles updates.

The Gateway watches your ~/.openclaw/openclaw.json file and applies changes automatically. For most settings, you don’t need to touch the terminal at all after you hit save.

  • A running OpenClaw Gateway instance.
  • Access to the ~/.openclaw/openclaw.json configuration file.

By default, the Gateway is ready to go with “hybrid” reloading. You can just open your config file, change a setting like an agent model or a UI preference, and save the file.

If you want to customize the reload behavior, add the reload object to your gateway configuration:

{
gateway: {
reload: { mode: "hybrid", debounceMs: 300 },
},
}

This setup waits 300 milliseconds after a save before applying changes, which helps if your editor saves files in small chunks.

I recommend sticking with the default hybrid mode, but you have four options depending on how much control you want over the process:

ModeBehavior
hybrid (default)Hot-applies safe changes instantly. Automatically restarts for critical ones.
hotHot-applies safe changes only. Logs a warning when a restart is needed — you handle it.
restartRestarts the Gateway on any config change, safe or not.
offDisables file watching. Changes take effect on the next manual restart.

Most things you change daily won’t cause any downtime. If you are in hybrid mode, the Gateway handles the heavy lifting for the few things that do require a restart.

CategoryFieldsRestart needed?
Channelschannels.*, web (WhatsApp) — all built-in and extension channelsNo
Agent & modelsagent, agents, models, routingNo
Automationhooks, cron, agent.heartbeatNo
Sessions & messagessession, messagesNo
Tools & mediatools, browser, skills, audio, talkNo
UI & miscui, logging, identity, bindingsNo
Gateway servergateway.* (port, bind, auth, tailscale, TLS, HTTP)Yes
Infrastructurediscovery, canvasHost, pluginsYes

Note: gateway.reload and gateway.remote are exceptions — changing them does not trigger a restart.

Changes aren’t applying in “hot” mode

Section titled “Changes aren’t applying in “hot” mode”

If you are using mode: "hot" and you change a server-level setting (like the port or TLS settings), the Gateway will not restart itself. It will log a warning letting you know that a manual restart is required. Check your logs to see if this warning appeared.

If you find the Gateway restarting too often while you are typing, try increasing the debounceMs value in your config. This gives you more time to finish your edits before the watcher triggers.

If you have more specific questions about your setup, check out the AI Setup Assistant.

I have spent too much time manually editing config files only to realize I broke the syntax or accidentally deleted a block I needed. When you start automating your setup, you want a way to update settings through code without worrying about file locks or manual restarts.

The Gateway provides RPC methods to handle these updates programmatically. It ensures your changes are validated before they are written.

  • The openclaw CLI tool
  • A running Gateway instance

The safest way to change a setting is to use config.patch. This merges your changes into the existing configuration.

  1. Get your current config hash: You need this to ensure you aren’t overwriting someone else’s changes.

    Terminal window
    openclaw gateway call config.get --params '{}'

    Look for the payload.hash in the output.

  2. Apply a partial update: Use that hash to update a specific key.

    Terminal window
    openclaw gateway call config.patch --params '{
    "raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }",
    "baseHash": "<hash>"
    }'

I find there are two main ways to handle these updates depending on whether you want to replace everything or just change a few lines.

This method validates and writes the full configuration, then restarts the Gateway. I suggest being careful here because it replaces the entire config. If you miss a section, it’s gone.

Parameters:

  • raw (string): JSON5 payload for the entire config.
  • baseHash (optional): The hash from config.get. It is required if a config already exists.
  • sessionKey (optional): A key for the post-restart wake-up ping.
  • note (optional): A note for the restart sentinel.
  • restartDelayMs (optional): How long to wait before restarting (default is 2000).
Terminal window
openclaw gateway call config.get --params '{}' # capture payload.hash
openclaw gateway call config.apply --params '{
"raw": "{ agents: { defaults: { workspace: \"~/.openclaw/workspace\" } } }",
"baseHash": "<hash>",
"sessionKey": "agent:main:whatsapp:dm:+15555550123"
}'

If you only need to change one or two values, this is the better choice. It uses JSON merge patch semantics:

  • Objects merge recursively.
  • Arrays are replaced entirely.
  • Setting a key to null deletes it.
  • Simple values are updated.

Parameters:

  • raw (string): JSON5 containing only the keys you want to change.
  • baseHash (required): The config hash from config.get.
  • sessionKey, note, restartDelayMs: These work the same as in config.apply.
Terminal window
openclaw gateway call config.patch --params '{
"raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }",
"baseHash": "<hash>"
}'

If things aren’t working as expected, check these two common issues:

  • Missing baseHash: If you try to call config.patch or config.apply (when a config exists) without the baseHash, the request will fail. This prevents race conditions where two scripts try to update the config at the same time.
  • Accidental Deletions: If you use config.apply and forget to include your existing agents or channels, they will be removed. For single key updates, I always recommend using openclaw config set or config.patch instead.

If you run into other issues, you can ask the AI Setup Assistant for help.

I hate it when I have to manually copy API keys into every single configuration file. It is messy, and it creates a security risk if you accidentally commit those secrets to a repository. You want a way to keep your sensitive data separate from your logic while making sure your tools can still find what they need.

In my experience, the best way to handle this is to let the tool do the heavy lifting. OpenClaw has a specific way of looking for variables so you don’t have to hardcode anything.

  • An OpenClaw configuration file (like a .json5 file).
  • API keys or tokens (e.g., OPENROUTER_API_KEY, GROQ_API_KEY).
  • A .env file (optional).

OpenClaw looks for environment variables in a specific order. It checks these four areas to build its configuration:

  1. The Parent Process: Any variables already set in your current terminal session.
  2. Local .env: A file named .env in your current working directory.
  3. Global .env: A fallback file located at ~/.openclaw/.env.
  4. Precedence Rule: Files never override variables that are already set in the parent process.

If you prefer to keep everything in one place, you can set variables directly inside your config file using the env block. I recommend this if you want to keep provider-specific keys organized:

{
env: {
OPENROUTER_API_KEY: "sk-or-...",
vars: { GROQ_API_KEY: "gsk-..." },
},
}

Sometimes your keys are already defined in your .zshrc or .bash_profile. Instead of copying them, you can tell OpenClaw to run your login shell and grab missing keys automatically.

You can enable this in your config:

{
env: {
shellEnv: { enabled: true, timeoutMs: 15000 },
},
}

Alternatively, you can just set the environment variable OPENCLAW_LOAD_SHELL_ENV=1 before running the tool.

This is the most useful feature for keeping configs clean. You can reference any environment variable inside a string using the ${VAR_NAME} syntax.

{
gateway: { auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" } },
models: { providers: { custom: { apiKey: "${CUSTOM_API_KEY}" } } },
}

Here are the rules for how this works:

  • OpenClaw only matches uppercase names like [A-Z_][A-Z0-9_]*.
  • If you need a literal ${VAR} in your output, escape it with two dollar signs: $${VAR}.
  • This works perfectly inside $include files.
  • You can use inline substitution, like "${BASE}/v1", which might turn into "https://api.example.com/v1".
  • Missing Variables: If you reference a variable with ${VAR_NAME} and it is missing or empty, OpenClaw will throw an error immediately at load time. Always double-check that your .env file is in the right directory.
  • Values Not Updating: Remember that .env files do not override existing environment variables. If you changed a value in your .env file but don’t see the change, check if the old value is still exported in your terminal session.

If you run into a specific edge case with your setup, you can always ask the AI Setup Assistant for help.

OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.