Skip to content

How to Use Configuration Examples

I know the feeling of looking at a blank configuration file and not knowing where to start. It is one of those common hurdles where you just want a working template so you can get moving. I have spent plenty of time staring at documentation, trying to figure out which fields are actually required and which ones are optional.

I have found that the best way to handle this is to start with examples that are already aligned with the current system requirements. It saves you from the trial and error of testing outdated settings.

  • Access to the Configuration reference
  • The current configuration schema

I recommend following these steps to get your configuration running in about five minutes. These examples stay aligned with the current schema so you do not have to worry about compatibility issues.

  1. Review the examples provided in the documentation.
  2. Compare your local file against the exhaustive reference to verify per-field notes.

If you encounter issues with specific settings, the best place to look is the reference documentation.

  • Field errors: Check the per-field notes in the main configuration guide.
  • Schema mismatches: Ensure your configuration file matches the current schema version mentioned in the examples.

Need more help with your specific setup? Check out the AI Setup Assistant.

I’ve spent too many afternoons wrestling with complex setups just to see if a tool actually works. It is frustrating when you want to talk to an AI but end up stuck in a mess of dependency issues or massive configuration files before you even send the first message.

If you are like me and want to get straight to the results, I found that OpenClaw makes this part easy. You can start with a tiny config and expand it as you go.

Before you start, make sure you have these two things ready:

  • A directory created at ~/.openclaw/
  • Access to the WhatsApp number you plan to use

You can get running in about five minutes. I suggest starting with the absolute minimum to verify your connection, then moving to the recommended setup.

If you want the shortest path possible, use this configuration. It sets up a workspace and allows messages from your specific phone number.

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

Save this code to ~/.openclaw/openclaw.json. Once it is saved, you can send a DM to the bot from that allowed number.

Once you know the connection works, I suggest using this setup. It gives your bot a personality and defines which model to use. This version also handles how the bot behaves in group chats.

{
identity: {
name: "Clawd",
theme: "helpful assistant",
emoji: "🦞",
},
agent: {
workspace: "~/.openclaw/workspace",
model: { primary: "anthropic/claude-sonnet-4-5" },
},
channels: {
whatsapp: {
allowFrom: ["+15555550123"],
groups: { "*": { requireMention: true } },
},
},
}

In this configuration, I’ve included four key areas:

  1. Identity: This sets the name “Clawd” and the “helpful assistant” theme.
  2. Model: It specifies anthropic/claude-sonnet-4-5 as the primary brain.
  3. Workspace: Defines where the agent stores its data.
  4. Group Logic: The requireMention: true setting ensures the bot only replies in groups when someone specifically mentions it.

If you run into any trouble during this setup, you can talk to the AI Setup Assistant for help.

I’ve been there—staring at a blank configuration file, wondering how to wire up multiple chat apps and different LLM providers without losing my mind. It is easy to get frustrated when you are trying to manage session resets, media processing, and tool permissions all at once.

I want to show you the expanded configuration example. This is the setup I recommend if you want to see how all the pieces fit together. It covers everything from identity and logging to complex routing and webhooks.

  • A config.json5 or config.json file.
  • API keys for your providers (like OpenRouter, Groq, or Anthropic).
  • An auth-profiles.json file (this is where your actual secrets live).

OpenClaw supports JSON5, which is great because you can use comments and trailing commas to keep things organized. If you prefer standard JSON, that works too.

Here is the full example showing the major options you can configure:

{
// Environment + shell
env: {
OPENROUTER_API_KEY: "sk-or-...",
vars: {
GROQ_API_KEY: "gsk-...",
},
shellEnv: {
enabled: true,
timeoutMs: 15000,
},
},
// Auth profile metadata (secrets live in auth-profiles.json)
auth: {
profiles: {
"anthropic:me@example.com": {
provider: "anthropic",
mode: "oauth",
email: "me@example.com",
},
"anthropic:work": { provider: "anthropic", mode: "api_key" },
"openai:default": { provider: "openai", mode: "api_key" },
"openai-codex:default": { provider: "openai-codex", mode: "oauth" },
},
order: {
anthropic: ["anthropic:me@example.com", "anthropic:work"],
openai: ["openai:default"],
"openai-codex": ["openai-codex:default"],
},
},
// Identity
identity: {
name: "Samantha",
theme: "helpful sloth",
emoji: "🦥",
},
// Logging
logging: {
level: "info",
file: "/tmp/openclaw/openclaw.log",
consoleLevel: "info",
consoleStyle: "pretty",
redactSensitive: "tools",
},
// Message formatting
messages: {
messagePrefix: "[openclaw]",
responsePrefix: ">",
ackReaction: "👀",
ackReactionScope: "group-mentions",
},
// Routing + queue
routing: {
groupChat: {
mentionPatterns: ["@openclaw", "openclaw"],
historyLimit: 50,
},
queue: {
mode: "collect",
debounceMs: 1000,
cap: 20,
drop: "summarize",
byChannel: {
whatsapp: "collect",
telegram: "collect",
discord: "collect",
slack: "collect",
signal: "collect",
imessage: "collect",
webchat: "collect",
},
},
},
// Tooling
tools: {
media: {
audio: {
enabled: true,
maxBytes: 20971520,
models: [
{ provider: "openai", model: "gpt-4o-mini-transcribe" },
// Optional CLI fallback (Whisper binary):
// { type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] }
],
timeoutSeconds: 120,
},
video: {
enabled: true,
maxBytes: 52428800,
models: [{ provider: "google", model: "gemini-3-flash-preview" }],
},
},
},
// Session behavior
session: {
scope: "per-sender",
reset: {
mode: "daily",
atHour: 4,
idleMinutes: 60,
},
resetByChannel: {
discord: { mode: "idle", idleMinutes: 10080 },
},
resetTriggers: ["/new", "/reset"],
store: "~/.openclaw/agents/default/sessions/sessions.json",
maintenance: {
mode: "warn",
pruneAfter: "30d",
maxEntries: 500,
rotateBytes: "10mb",
},
typingIntervalSeconds: 5,
sendPolicy: {
default: "allow",
rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }],
},
},
// Channels
channels: {
whatsapp: {
dmPolicy: "pairing",
allowFrom: ["+15555550123"],
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: { "*": { requireMention: true } },
},
telegram: {
enabled: true,
botToken: "YOUR_TELEGRAM_BOT_TOKEN",
allowFrom: ["123456789"],
groupPolicy: "allowlist",
groupAllowFrom: ["123456789"],
groups: { "*": { requireMention: true } },
},
discord: {
enabled: true,
token: "YOUR_DISCORD_BOT_TOKEN",
dm: { enabled: true, allowFrom: ["steipete"] },
guilds: {
"123456789012345678": {
slug: "friends-of-openclaw",
requireMention: false,
channels: {
general: { allow: true },
help: { allow: true, requireMention: true },
},
},
},
},
slack: {
enabled: true,
botToken: "xoxb-REPLACE_ME",
appToken: "xapp-REPLACE_ME",
channels: {
"#general": { allow: true, requireMention: true },
},
dm: { enabled: true, allowFrom: ["U123"] },
slashCommand: {
enabled: true,
name: "openclaw",
sessionPrefix: "slack:slash",
ephemeral: true,
},
},
},
// Agent runtime
agents: {
defaults: {
workspace: "~/.openclaw/workspace",
userTimezone: "America/Chicago",
model: {
primary: "anthropic/claude-sonnet-4-5",
fallbacks: ["anthropic/claude-opus-4-6", "openai/gpt-5.2"],
},
imageModel: {
primary: "openrouter/anthropic/claude-sonnet-4-5",
},
models: {
"anthropic/claude-opus-4-6": { alias: "opus" },
"anthropic/claude-sonnet-4-5": { alias: "sonnet" },
"openai/gpt-5.2": { alias: "gpt" },
},
thinkingDefault: "low",
verboseDefault: "off",
elevatedDefault: "on",
blockStreamingDefault: "off",
blockStreamingBreak: "text_end",
blockStreamingChunk: {
minChars: 800,
maxChars: 1200,
breakPreference: "paragraph",
},
blockStreamingCoalesce: {
idleMs: 1000,
},
humanDelay: {
mode: "natural",
},
timeoutSeconds: 600,
mediaMaxMb: 5,
typingIntervalSeconds: 5,
maxConcurrent: 3,
heartbeat: {
every: "30m",
model: "anthropic/claude-sonnet-4-5",
target: "last",
to: "+15555550123",
prompt: "HEARTBEAT",
ackMaxChars: 300,
},
memorySearch: {
provider: "gemini",
model: "gemini-embedding-001",
remote: {
apiKey: "${GEMINI_API_KEY}",
},
extraPaths: ["../team-docs", "/srv/shared-notes"],
},
sandbox: {
mode: "non-main",
perSession: true,
workspaceRoot: "~/.openclaw/sandboxes",
docker: {
image: "openclaw-sandbox:bookworm-slim",
workdir: "/workspace",
readOnlyRoot: true,
tmpfs: ["/tmp", "/var/tmp", "/run"],
network: "none",
user: "1000:1000",
},
browser: {
enabled: false,
},
},
},
},
tools: {
allow: ["exec", "process", "read", "write", "edit", "apply_patch"],
deny: ["browser", "canvas"],
exec: {
backgroundMs: 10000,
timeoutSec: 1800,
cleanupMs: 1800000,
},
elevated: {
enabled: true,
allowFrom: {
whatsapp: ["+15555550123"],
telegram: ["123456789"],
discord: ["steipete"],
slack: ["U123"],
signal: ["+15555550123"],
imessage: ["user@example.com"],
webchat: ["session:demo"],
},
},
},
// Custom model providers
models: {
mode: "merge",
providers: {
"custom-proxy": {
baseUrl: "http://localhost:4000/v1",
apiKey: "LITELLM_KEY",
api: "openai-responses",
authHeader: true,
headers: { "X-Proxy-Region": "us-west" },
models: [
{
id: "llama-3.1-8b",
name: "Llama 3.1 8B",
api: "openai-responses",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 32000,
},
],
},
},
},
// Cron jobs
cron: {
enabled: true,
store: "~/.openclaw/cron/cron.json",
maxConcurrentRuns: 2,
sessionRetention: "24h",
},
// Webhooks
hooks: {
enabled: true,
path: "/hooks",
token: "shared-secret",
presets: ["gmail"],
transformsDir: "~/.openclaw/hooks",
mappings: [
{
id: "gmail-hook",
match: { path: "gmail" },
action: "agent",
wakeMode: "now",
name: "Gmail",
sessionKey: "hook:gmail:{{messages[0].id}}",
messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}",
textTemplate: "{{messages[0].snippet}}",
deliver: true,
channel: "last",
to: "+15555550123",
thinking: "low",
timeoutSeconds: 300,
transform: {
module: "./transforms/gmail.js",
export: "transformGmail",
},
},
],
gmail: {
account: "openclaw@gmail.com",
label: "INBOX",
topic: "projects/<project-id>/topics/gog-gmail-watch",
subscription: "gog-gmail-watch-push",
pushToken: "shared-push-token",
hookUrl: "http://127.0.0.1:18789/hooks/gmail",
includeBody: true,
maxBytes: 20000,
renewEveryMinutes: 720,
serve: { bind: "127.0.0.1", port: 8788, path: "/" },
tailscale: { mode: "funnel", path: "/gmail-pubsub" },
},
},
// Gateway + networking
gateway: {
mode: "local",
port: 18789,
bind: "loopback",
controlUi: { enabled: true, basePath: "/openclaw" },
auth: {
mode: "token",
token: "gateway-token",
allowTailscale: true,
},
tailscale: { mode: "serve", resetOnExit: false },
remote: { url: "ws://gateway.tailnet:18789", token: "remote-token" },
reload: { mode: "hybrid", debounceMs: 300 },
},
skills: {
allowBundled: ["gemini", "peekaboo"],
load: {
extraDirs: ["~/Projects/agent-scripts/skills"],
},
install: {
preferBrew: true,
nodeManager: "npm",
},
entries: {
"nano-banana-pro": {
enabled: true,
apiKey: "GEMINI_KEY_HERE",
env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" },
},
peekaboo: { enabled: true },
},
},
}

If you run into trouble, check these common configuration areas:

  • Secrets exposure: If you are worried about tools leaking sensitive data, check the logging block. Setting redactSensitive: "tools" will help hide that information.
  • Provider failures: If your primary model is down, ensure you have fallbacks defined in the agents.defaults.model section. This tells OpenClaw which models to try next.
  • Shell timeouts: If your scripts are dying too early, look at the env.shellEnv.timeoutMs setting. The default in this example is 15000ms.
  • Docker permission issues: In the sandbox section, we use user: "1000:1000". If your environment requires different permissions, you will need to adjust this and the readOnlyRoot setting.

Still stuck? Head over to the AI Setup Assistant for real-time help with your specific config.

I often find myself spending too much time tweaking configuration files instead of building. It gets tricky when you try to balance multiple chat channels or set up reliable model fallbacks. I want to share some patterns that help organize these setups effectively.

Configuring an agent can feel like a chore when you are juggling different platforms and API keys. I’ve spent plenty of time staring at config files trying to get model fallbacks and channel permissions just right. These patterns cover the most common setups I use to keep things running.

  • A workspace directory (e.g., ~/.openclaw/workspace)
  • API tokens or OAuth credentials for your chosen providers (Anthropic, Discord, etc.)
  • Local model server credentials if you are using LM Studio

If you want to get up and running with multiple platforms quickly, use this structure. It defines a workspace and sets up WhatsApp, Telegram, and Discord in one go.

{
agent: { workspace: "~/.openclaw/workspace" },
channels: {
whatsapp: { allowFrom: ["+15555550123"] },
telegram: {
enabled: true,
botToken: "YOUR_TOKEN",
allowFrom: ["123456789"],
},
discord: {
enabled: true,
token: "YOUR_TOKEN",
dm: { allowFrom: ["yourname"] },
},
},
}

If more than one person can DM your bot, you should use secure DM mode. This prevents DMs from different senders from sharing one context by default. This is useful for multi-user inboxes or sensitive agents.

{
// Secure DM mode (recommended for multi-user or sensitive DM agents)
session: { dmScope: "per-channel-peer" },
channels: {
// Example: WhatsApp multi-user inbox
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15555550123", "+15555550124"],
},
// Example: Discord multi-user inbox
discord: {
enabled: true,
token: "YOUR_DISCORD_BOT_TOKEN",
dm: { enabled: true, allowFrom: ["alice", "bob"] },
},
},
}

I recommend setting up an order for your authentication profiles. This pattern tries your Anthropic subscription via OAuth first and falls back to a standard API key if needed.

{
auth: {
profiles: {
"anthropic:subscription": {
provider: "anthropic",
mode: "oauth",
email: "me@example.com",
},
"anthropic:api": {
provider: "anthropic",
mode: "api_key",
},
},
order: {
anthropic: ["anthropic:subscription", "anthropic:api"],
},
},
agent: {
workspace: "~/.openclaw/workspace",
model: {
primary: "anthropic/claude-sonnet-4-5",
fallbacks: ["anthropic/claude-opus-4-6"],
},
},
}

Anthropic subscription + API key, MiniMax fallback

Section titled “Anthropic subscription + API key, MiniMax fallback”

This setup is great if you want high reliability. It uses your Anthropic subscription and API key as primary options, but routes to MiniMax if the primary models are unavailable.

{
auth: {
profiles: {
"anthropic:subscription": {
provider: "anthropic",
mode: "oauth",
email: "user@example.com",
},
"anthropic:api": {
provider: "anthropic",
mode: "api_key",
},
},
order: {
anthropic: ["anthropic:subscription", "anthropic:api"],
},
},
models: {
providers: {
minimax: {
baseUrl: "https://api.minimax.io/anthropic",
api: "anthropic-messages",
apiKey: "${MINIMAX_API_KEY}",
},
},
},
agent: {
workspace: "~/.openclaw/workspace",
model: {
primary: "anthropic/claude-opus-4-6",
fallbacks: ["minimax/MiniMax-M2.1"],
},
},
}

For a professional environment, you might want to restrict the bot to specific Slack channels and disable elevated permissions.

{
identity: {
name: "WorkBot",
theme: "professional assistant",
},
agent: {
workspace: "~/work-openclaw",
elevated: { enabled: false },
},
channels: {
slack: {
enabled: true,
botToken: "xoxb-...",
channels: {
"#engineering": { allow: true, requireMention: true },
"#general": { allow: true, requireMention: true },
},
},
},
}

If you prefer running everything locally, you can point your configuration to an LM Studio instance.

{
agent: {
workspace: "~/.openclaw/workspace",
model: { primary: "lmstudio/minimax-m2.1-gs32" },
},
models: {
mode: "merge",
providers: {
lmstudio: {
baseUrl: "http://127.0.0.1:1234/v1",
apiKey: "lmstudio",
api: "openai-responses",
models: [
{
id: "minimax-m2.1-gs32",
name: "MiniMax M2.1 GS32",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 196608,
maxTokens: 8192,
},
],
},
},
},
}

Issue: DMs from different users are sharing the same conversation history. This happens when the agent uses a global context for direct messages. To fix this, enable per-channel-peer scoping in your session settings:

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

Need help with a specific setup? Check out the AI Setup Assistant.

I’ve spent too many hours staring at a configuration file, wondering why a service isn’t responding even though everything looks correct. Usually, it is a small mismatch between two settings or a formatting error in an ID that causes the silence.

Getting these details right the first time saves you from a lot of debugging later. Here are a few specific things I recommend checking to keep your setup running correctly.

  • Access to your configuration file
  • Provider-specific documentation for ID formats

If you want your configuration to work without issues, pay close attention to how you define your policies and IDs.

When you set your dmPolicy to "open", the system expects a matching permission level. You must include "*" in your allowFrom list. Without this wildcard, the “open” policy will not function as expected.

Provider IDs are not standardized across different services. Depending on the platform, you might need to use:

  • Phone numbers
  • User IDs
  • Channel IDs

I suggest checking the specific Providers documentation to confirm the exact format required for the service you are using.

You can expand your configuration later by adding these optional sections:

  • web and browser
  • ui and discovery
  • canvasHost and talk
  • signal and imessage

If your connection fails, the first thing I would check is the ID format. Since phone numbers and user IDs look very different, a mismatch here is a common culprit.

For more detailed help with specific errors, you can visit the Troubleshooting page.

If you hit a wall or need a specific question answered, check out the AI Setup Assistant.

OpenClaw

OpenClaw Expert

Still stuck?

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