Skip to content

OpenClaw Config Reference: Every openclaw.json Option

·11 min read·By Christopher Kvamme

OpenClaw was previously known as Clawdbot and Moltbot. Configuration and commands depend on the version in use.

OpenClaw environment variables and openclaw.json config keys organized by category: gateway, channels, agents, session, cron, tools, and security.

OpenClaw Config Reference: Every openclaw.json Option
Share:
On this page

On this page

Key takeaways

  • Every OpenClaw config lives in ~/.openclaw/openclaw.json (JSON5 format: comments and trailing commas allowed)
  • The schema is strict. Any unknown key causes the gateway to refuse to start. Run openclaw doctor to diagnose failures.
  • Sensitive credentials like bot tokens have environment variable fallbacks so you can keep secrets out of the config file
  • You can edit config with openclaw config set <key> <value>, the interactive wizard (openclaw configure), or the Control UI at http://127.0.0.1:18789
  • All fields are optional. OpenClaw uses safe defaults when a key is omitted

What openclaw.json is and where to find it

The config file lives at ~/.openclaw/openclaw.json. If the file does not exist, OpenClaw boots with safe defaults. The format is JSON5, which means you can use comments (// or /* */) and trailing commas without breaking the parser.

OpenClaw validates the file against a strict schema on startup. Unknown keys, wrong types, and invalid values all prevent the gateway from starting. Only the root-level $schema key is exempt, so JSON Schema-aware editors can attach metadata. When validation fails, diagnostic commands like openclaw doctor, openclaw logs, openclaw health, and openclaw status continue to work so you can debug.

Run openclaw doctor --fix to auto-repair common issues.


How to edit the openclaw.json config

Four methods work for editing config:

CLI (best for scripting):

json

openclaw config get agents.defaults.workspace
openclaw config set agents.defaults.heartbeat.every "2h"
openclaw config unset plugins.entries.brave.config.webSearch.apiKey

Interactive wizard:

json

openclaw configure
openclaw onboard

Control UI: Open http://127.0.0.1:18789 and use the Config tab. The UI renders a form from the schema with a Raw JSON editor as a fallback.

Direct file edit: Edit ~/.openclaw/openclaw.json directly. The gateway watches the file and applies changes automatically without a restart (hot reload).


Environment variable fallbacks for API keys

These environment variables are read automatically without needing entries in openclaw.json. Useful for secrets management or CI environments.

Model provider API key resolution

OpenClaw checks these sources in priority order for each provider:

PriorityVariableNotes
1OPENCLAW_LIVE_<PROVIDER>_KEYSingle override, highest priority
2<PROVIDER>_API_KEYSComma-separated list for rotation
3<PROVIDER>_API_KEYStandard single key
4<PROVIDER>_API_KEY_*Wildcard pattern, lowest priority

Examples: ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY. Google providers also check GOOGLE_API_KEY as a fallback.

OpenClaw only retries with the next key for rate-limit errors (429, quota, resource exhausted). Non-rate-limit errors are not retried with alternate keys.

For daemon setups (systemd, launchd), put keys in ~/.openclaw/.env so the daemon can read them without shell inheritance.

Channel-specific environment variables

VariableConfig key it maps to
TELEGRAM_BOT_TOKENchannels.telegram.botToken (default account)
DISCORD_BOT_TOKENchannels.discord.token (default account)
SLACK_BOT_TOKENchannels.slack.botToken (default account)
SLACK_APP_TOKENchannels.slack.appToken (default account)
GOOGLE_CHAT_SERVICE_ACCOUNTchannels.googlechat.serviceAccount
GOOGLE_CHAT_SERVICE_ACCOUNT_FILEchannels.googlechat.serviceAccountFile

iOS push relay variables (temporary overrides)

VariablePurpose
OPENCLAW_APNS_RELAY_BASE_URLTemporary override for relay base URL
OPENCLAW_APNS_RELAY_TIMEOUT_MSTimeout in ms (default: 10000)
OPENCLAW_APNS_RELAY_ALLOW_HTTP=trueDev-only loopback override. Do not persist.

Gateway config options (gateway.*)

Controls the gateway server itself: binding, health checks, and push.

KeyTypeDefaultDescription
gateway.bindstring127.0.0.1Interface to bind. Use 0.0.0.0 to expose to the network
gateway.portnumber18789HTTP port for the gateway
gateway.channelHealthCheckMinutesnumber5How often the health monitor polls channels. Set to 0 to disable
gateway.channelStaleEventThresholdMinutesnumber30Minutes without events before a channel is considered stale. Should be >= check interval
gateway.channelMaxRestartsPerHournumber10Max auto-restarts per channel per hour
gateway.push.apns.relay.baseUrlstring(none)Relay URL for iOS push notifications on official builds
gateway.push.apns.relay.timeoutMsnumber10000Relay request timeout

Disable auto-restarts globally:

json

{
  gateway: {
    channelHealthCheckMinutes: 0,
  },
}

Disable auto-restarts for one channel only:

json

{
  channels: {
    telegram: {
      healthMonitor: { enabled: false },
    },
  },
}

Channel config keys by provider

DM and group access policy (all channels)

Every channel supports dmPolicy and groupPolicy.

dmPolicy valueBehavior
pairing (default)Unknown senders get a one-time pairing code. Owner approves. Codes expire after 1 hour. Max 3 pending per channel. See dmPolicy docs.
allowlistOnly senders in allowFrom or the paired allow store
openAllow all inbound DMs (requires allowFrom: ["*"])
disabledIgnore all inbound DMs
groupPolicy valueBehavior
allowlist (default)Only groups matching the configured allowlist
openBypass group allowlists (mention-gating still applies)
disabledBlock all group messages

Use channels.defaults.groupPolicy to set a fallback for all providers at once.

Channel defaults (channels.defaults.*)

json

{
  channels: {
    defaults: {
      groupPolicy: "allowlist",
      heartbeat: {
        showOk: false,
        showAlerts: true,
        useIndicator: true,
      },
    },
  },
}
KeyDescription
channels.defaults.groupPolicyFallback group policy when a provider-level groupPolicy is unset
channels.defaults.heartbeat.showOkInclude healthy channel statuses in heartbeat output
channels.defaults.heartbeat.showAlertsInclude degraded/error statuses in heartbeat output
channels.defaults.heartbeat.useIndicatorRender compact indicator-style heartbeat output

Channel model overrides (channels.modelByChannel.*)

Pin specific channel IDs to a model. Applies when a session does not already have a model override.

json

{
  channels: {
    modelByChannel: {
      telegram: {
        "-1001234567890": "openai/gpt-4.1-mini",
      },
      discord: {
        "123456789012345678": "anthropic/claude-opus-4-6",
      },
    },
  },
}

WhatsApp config (channels.whatsapp.*)

WhatsApp uses the Baileys Web protocol. It starts automatically when a linked session exists.

KeyTypeDefaultDescription
channels.whatsapp.dmPolicystringpairingDM access policy
channels.whatsapp.allowFromstring[](none)Phone numbers allowed to DM
channels.whatsapp.textChunkLimitnumber4000Max chars per message chunk
channels.whatsapp.chunkModestringlengthlength or newline
channels.whatsapp.mediaMaxMbnumber50Max inbound media size
channels.whatsapp.sendReadReceiptsbooleantrueSend blue read receipts
channels.whatsapp.groupPolicystringallowlistGroup access policy
channels.whatsapp.groupAllowFromstring[](none)Numbers allowed to use groups
channels.whatsapp.groups.*object(none)Per-group overrides. Use "*" for wildcard

Multi-account: add account IDs under channels.whatsapp.accounts.<id>. Per-account keys: sendReadReceipts, dmPolicy, allowFrom.

Reconnect settings live under web.*:

KeyDefaultDescription
web.enabledtrueEnable Baileys web transport
web.heartbeatSeconds60Keepalive interval
web.reconnect.initialMs2000First reconnect delay
web.reconnect.maxMs120000Max reconnect delay
web.reconnect.factor1.4Exponential backoff factor
web.reconnect.jitter0.2Jitter fraction
web.reconnect.maxAttempts00 = unlimited

Telegram config (channels.telegram.*)

KeyTypeDefaultDescription
channels.telegram.botTokenstring(none)Bot token from BotFather. Env fallback: TELEGRAM_BOT_TOKEN
channels.telegram.tokenFilestring(none)Path to token file (regular file only, no symlinks)
channels.telegram.dmPolicystringpairingDM access policy
channels.telegram.allowFromstring[](none)Allowed user IDs (tg:123456789 format)
channels.telegram.historyLimitnumber50Messages to include in context
channels.telegram.replyToModestringoffoff, first, or all
channels.telegram.linkPreviewbooleantrueEnable link previews
channels.telegram.streamingstringoffoff, partial, block, or progress. Opt-in to avoid preview-edit rate limits
channels.telegram.mediaMaxMbnumber100Max inbound media
channels.telegram.reactionNotificationsstringownoff, own, or all
channels.telegram.proxystring(none)SOCKS5 proxy URL
channels.telegram.webhookUrlstring(none)Webhook URL (alternative to polling)
channels.telegram.webhookSecretstring(none)Webhook validation secret
channels.telegram.configWritesbooleantrueSet false to block Telegram-initiated config writes
channels.telegram.defaultAccountstring(none)Default account ID in multi-account setups

Group config: channels.telegram.groups.<chatId>.* with keys allowFrom, systemPrompt, requireMention, topics.

Discord config (channels.discord.*)

KeyTypeDefaultDescription
channels.discord.tokenstring(none)Bot token. Env fallback: DISCORD_BOT_TOKEN
channels.discord.dmPolicystringpairingDM access policy
channels.discord.allowFromstring[](none)Allowed user IDs
channels.discord.allowBotsboolean/stringfalsetrue, false, or "mentions"
channels.discord.mediaMaxMbnumber8Max media upload size
channels.discord.historyLimitnumber20Context message count
channels.discord.textChunkLimitnumber2000Max chars per message
channels.discord.maxLinesPerMessagenumber17Max lines before splitting (even under 2000 chars)
channels.discord.replyToModestringoffoff, first, or all
channels.discord.streamingstringoffoff, partial, block, or progress
channels.discord.defaultAccountstring(none)Default account in multi-account setups

Thread bindings (channels.discord.threadBindings.*):

KeyDefaultDescription
enabledtrueEnable thread-bound session features
idleHours24Auto-unfocus idle threads after this many hours. 0 disables
maxAgeHours0Hard age cap for thread bindings. 0 disables
spawnSubagentSessionsfalseOpt-in for sessions_spawn({ thread: true }) auto thread creation

Voice (channels.discord.voice.*):

KeyDefaultDescription
enabledfalseEnable voice channel conversations
autoJoin(none)Array of {guildId, channelId} to auto-join
daveEncryptiontrueDAVE protocol encryption
tts.provider(none)TTS provider for voice output

Discord actions (channels.discord.actions.*):

All default to true except roles and moderation:

reactions, stickers, polls, permissions, messages, threads, pins, search, memberInfo, roleInfo, channelInfo, voiceStatus, events are all enabled by default. roles and moderation are disabled by default (opt-in).

Per-guild config: channels.discord.guilds.<guildId>.* with keys slug, requireMention, ignoreOtherMentions, reactionNotifications, users, channels.

Slack config (channels.slack.*)

KeyTypeDefaultDescription
channels.slack.botTokenstring(none)xoxb token. Env: SLACK_BOT_TOKEN
channels.slack.appTokenstring(none)xapp token for Socket Mode. Env: SLACK_APP_TOKEN
channels.slack.signingSecretstring(none)Required for HTTP Mode
channels.slack.dmPolicystringpairingDM policy
channels.slack.allowFromstring[](none)Allowed user IDs
channels.slack.allowBotsbooleanfalseAccept messages from bots
channels.slack.historyLimitnumber50Context message count
channels.slack.replyToModestringoffoff, first, or all
channels.slack.streamingstringoffoff, partial, block, or progress
channels.slack.nativeStreamingbooleanfalseUse Slack native streaming API when streaming=partial
channels.slack.textChunkLimitnumber4000Max chars per chunk
channels.slack.mediaMaxMbnumber20Max media size
channels.slack.typingReactionstring(none)Emoji shortcode shown while reply is running
channels.slack.reactionNotificationsstringownoff, own, all, or allowlist
channels.slack.configWritesbooleantrueSet false to block Slack-initiated config writes

Thread behavior (channels.slack.thread.*):

KeyDefaultDescription
historyScopethreadthread or channel
inheritParentfalseCopy parent channel transcript to new threads

Slash command (channels.slack.slashCommand.*):

KeyDefaultDescription
enabledfalseEnable slash command support
nameopenclawSlash command name
sessionPrefixslack:slashSession key prefix
ephemeraltrueRespond with ephemeral messages

Google Chat config (channels.googlechat.*)

KeyDescription
channels.googlechat.serviceAccountFilePath to service account JSON file
channels.googlechat.serviceAccountInline service account JSON
channels.googlechat.serviceAccountRefSecretRef for service account
channels.googlechat.audienceTypeapp-url or project-number
channels.googlechat.audienceAudience URL or project number
channels.googlechat.webhookPathPath for incoming webhooks
channels.googlechat.botUserBot user identifier (users/<id>)
channels.googlechat.dmPolicyVia dm.policy key
channels.googlechat.mediaMaxMbMax media size
channels.googlechat.typingIndicatormessage or off

Env fallbacks: GOOGLE_CHAT_SERVICE_ACCOUNT, GOOGLE_CHAT_SERVICE_ACCOUNT_FILE.

Signal config (channels.signal.*)

KeyDescription
channels.signal.enabledEnable Signal channel
channels.signal.accountOptional phone number binding
channels.signal.dmPolicyDM access policy
channels.signal.allowFromAllowed numbers or UUIDs (uuid:... format)
channels.signal.configWritesAllow/deny Signal-initiated config writes

Mattermost config (channels.mattermost.*)

Mattermost requires the plugin: openclaw plugins install @openclaw/mattermost.

KeyDefaultDescription
channels.mattermost.botToken(none)Mattermost bot token
channels.mattermost.baseUrl(none)Mattermost server URL
channels.mattermost.dmPolicypairingDM access policy
channels.mattermost.chatmodeoncalloncall (mention), onmessage (all), onchar (prefix trigger)
channels.mattermost.oncharPrefixes(none)Trigger prefixes for onchar mode
channels.mattermost.textChunkLimit4000Max chars per chunk
channels.mattermost.requireMention(none)Require @mention before responding
channels.mattermost.commands.nativefalseEnable Mattermost native slash commands
channels.mattermost.commands.callbackPath(none)Path for command callbacks
channels.mattermost.commands.callbackUrl(none)Full URL if behind a reverse proxy

Agent and model config options (agents.*)

Controls the agent runtime: workspace, models, thinking mode, heartbeat, and sandboxing.

agents.defaults.*

KeyTypeDefaultDescription
agents.defaults.workspacestring(none)Agent working directory
agents.defaults.userTimezonestring(none)Timezone for agent date/time context
agents.defaults.model.primarystring(none)Primary model (provider/model format)
agents.defaults.model.fallbacksstring[](none)Fallback models in order
agents.defaults.models.<id>.*object(none)Model catalog and allowlist for /model command
agents.defaults.imageModel.primarystring(none)Default image generation model
agents.defaults.imageMaxDimensionPxnumber1200Max dimension for vision tool images. Lower values reduce token usage
agents.defaults.thinkingDefaultstringoffoff, low, or high
agents.defaults.verboseDefaultstringoffVerbose mode default
agents.defaults.elevatedDefaultstringoffElevated tool permissions default
agents.defaults.timeoutSecondsnumber600Max session run time
agents.defaults.mediaMaxMbnumber5Max media file size for agent
agents.defaults.maxConcurrentnumber3Max concurrent agent sessions

Heartbeat (agents.defaults.heartbeat.*)

KeyDefaultDescription
every(none)Interval string (30m, 2h). Set 0m to disable
targetlastlast, whatsapp, telegram, discord, or none
directPolicyallowallow or block for DM-style heartbeat targets
prompt(none)Custom heartbeat prompt
ackMaxChars(none)Max chars for acknowledgment
model(none)Model to use for heartbeat runs
to(none)Override delivery target

Sandbox (agents.defaults.sandbox.*)

KeyDefaultDescription
modeoffoff, non-main, or all
scopeagentsession, agent, or shared
workspaceRoot(none)Base dir for sandbox workspaces
docker.image(none)Docker image name
docker.workdir/workspaceWorking directory inside container
docker.readOnlyRoot(none)Read-only root filesystem
docker.networknoneNetwork mode
docker.user(none)User inside container
docker.tmpfs(none)Tmpfs mounts
browser.enabledfalseEnable browser tools inside sandbox

Build the sandbox image first: scripts/sandbox-setup.sh.

Memory search (agents.defaults.memorySearch.*)

KeyDescription
providerSearch provider (e.g. gemini)
modelEmbedding model
remote.apiKeyAPI key for remote search provider
extraPathsAdditional directories to include in search

Per-agent list (agents.list[])

Override defaults per agent. Each entry requires id. Common per-agent keys:

KeyDescription
idAgent identifier
defaultSet true to mark as the default agent
model.primaryOverride primary model
thinkingDefaultOverride thinking mode
fastModeDefaultEnable fast mode for this agent
reasoningDefaultShow reasoning output
groupChat.mentionPatternsPatterns that trigger this agent in groups

Session management config (session.*)

Controls conversation continuity, scoping, and cleanup.

KeyTypeDefaultDescription
session.dmScopestringmainmain, per-peer, per-channel-peer, per-account-channel-peer
session.reset.modestring(none)daily, idle, or manual
session.reset.atHournumber4Hour (0-23) for daily reset
session.reset.idleMinutesnumber(none)Minutes idle before reset
session.resetByChannel.<provider>.*object(none)Per-channel reset overrides
session.resetTriggersstring[](none)Chat commands that trigger a reset
session.storestring(none)Custom path for sessions.json

Thread bindings (session.threadBindings.*):

KeyDescription
enabledEnable thread-bound session features
idleHoursAuto-unfocus idle hours
maxAgeHoursHard max age in hours

Session maintenance (session.maintenance.*):

KeyDefaultDescription
modewarnwarn, prune, or archive
pruneAfter30dAge at which sessions are pruned
maxEntries500Max session entries
rotateBytes10mbRotate sessions.json at this size
resetArchiveRetention30dHow long to keep reset archives
maxDiskBytes(none)Disk quota for session storage

Send policy (session.sendPolicy.*):

KeyDescription
defaultallow or deny
rules[]Array of {action, match} rules

Cron job config options (cron.*)

Controls scheduled task execution behavior.

KeyTypeDefaultDescription
cron.enabledbooleanfalseEnable the cron runner
cron.maxConcurrentRunsnumber2Max jobs running at the same time
cron.sessionRetentionstring/boolean24hHow long to keep completed isolated run sessions. Set false to disable cleanup
cron.runLog.maxBytesstring2mbMax size for per-job run logs
cron.runLog.keepLinesnumber2000Lines to retain in run logs

Cron jobs are defined separately in ~/.openclaw/cron/jobs.json. The cron.* config keys only control the runner behavior.


Webhooks and hooks config (hooks.*)

Enables HTTP webhook ingestion on the gateway.

KeyTypeDefaultDescription
hooks.enabledbooleanfalseEnable webhook endpoint
hooks.tokenstring(none)Shared secret for webhook verification
hooks.pathstring/hooksURL path for the webhook endpoint
hooks.defaultSessionKeystring(none)Default session key for inbound hooks
hooks.allowRequestSessionKeybooleanfalseAllow callers to specify session key in request
hooks.allowedSessionKeyPrefixesstring[](none)Allowed session key prefixes
hooks.mappings[]array(none)Routing rules: match.path, action, agentId, deliver

Treat all webhook payload content as untrusted input. Keep allowUnsafeExternalContent flags disabled except for tightly scoped debugging.


Tool permissions config (tools.*)

Controls which tools the agent can use, execution limits, and media handling.

KeyTypeDescription
tools.allowstring[]Allowlist of tool names
tools.denystring[]Denylist of tool names

Exec settings (tools.exec.*):

KeyDefaultDescription
backgroundMs10000Milliseconds before backgrounding a command
timeoutSec1800Max exec run time in seconds
cleanupMs1800000Time before cleaning up background processes

Elevated permissions (tools.elevated.*):

KeyDescription
enabledEnable elevated tool permissions
allowFrom.<channel>[]Senders allowed to use elevated tools per channel

Media tools (tools.media.audio., tools.media.video.):

KeyDefaultDescription
audio.enabledfalseEnable audio transcription
audio.maxBytes20971520Max audio file size (~20MB)
audio.models[](none)Transcription models to try
audio.timeoutSeconds120Transcription timeout
video.enabledfalseEnable video analysis
video.maxBytes52428800Max video file size (~50MB)
video.models[](none)Vision models for video

Identity, logging, routing, and environment config

Identity (identity.*)

KeyDescription
identity.nameAgent display name
identity.themeShort persona description
identity.emojiAgent emoji

Logging (logging.*)

KeyDefaultDescription
logging.levelinfoLog level: debug, info, warn, error
logging.file(none)Path to log file
logging.consoleLevelinfoConsole log level
logging.consoleStyleprettypretty or json
logging.redactSensitive(none)tools to redact sensitive tool output

Messages (messages.*)

KeyDescription
messages.messagePrefixPrefix prepended to messages
messages.responsePrefixPrefix for agent responses
messages.ackReactionEmoji reaction for acknowledgment
messages.ackReactionScopeWhen to react: all, group-mentions, etc.

Routing (routing.*)

KeyDefaultDescription
routing.groupChat.mentionPatterns(none)Text patterns that trigger the agent in groups
routing.groupChat.historyLimit(none)Context message count for group chats
routing.queue.modecollectQueue mode: collect or immediate
routing.queue.debounceMs1000Debounce delay before processing collected messages
routing.queue.cap20Max messages to collect
routing.queue.dropsummarizeWhat to do when queue overflows

Environment injection (env.*)

KeyDescription
env.vars.*Key-value pairs injected as environment variables
env.shellEnv.enabledInherit the shell environment when starting
env.shellEnv.timeoutMsTimeout for shell env resolution
env.<PROVIDER_KEY>Direct API key injection (e.g. env.OPENROUTER_API_KEY)

Auth profiles (auth.*)

Auth profile metadata lives in openclaw.json. Secrets live in ~/.openclaw/auth-profiles.json.

KeyDescription
auth.profiles.<id>.providerProvider name (anthropic, openai, etc.)
auth.profiles.<id>.modeapi_key or oauth
auth.order.<provider>[]Priority order of profile IDs for that provider

Custom model providers (models.*)

KeyDescription
models.modemerge (add to built-ins) or replace (use only custom)
models.providers.<id>.baseUrlCustom provider base URL
models.providers.<id>.apiKeyAPI key for custom provider
models.providers.<id>.apiAPI type: openai-responses, etc.
models.providers.<id>.models[]Model definitions for this provider

Key terms

JSON5: A superset of JSON that allows comments (//, /* */) and trailing commas. OpenClaw reads openclaw.json as JSON5.

dmPolicy: A per-channel setting controlling who can DM the bot. Options: pairing, allowlist, open, disabled.

Sandbox: An isolated Docker container for agent tool execution. Controlled by agents.defaults.sandbox.*.

SecretRef: A reference to a secret stored outside the config file. Supports env, file, and exec sources.

Socket Mode vs HTTP Mode (Slack): Socket Mode requires both botToken and appToken. HTTP Mode requires botToken and signingSecret.


FAQ

What happens in OpenClaw if I add an unknown key to openclaw.json?

OpenClaw validates the config against a strict schema on every startup. If you add a key that does not exist in the schema, or use the wrong type, the gateway refuses to start. You will see an error in openclaw doctor output. Use openclaw doctor --fix to apply automatic repairs for common issues. The only key that bypasses strict validation is the root-level $schema string.

Where does OpenClaw look for the ANTHROPIC_API_KEY and what is the priority order when multiple keys exist?

OpenClaw checks these sources in descending priority: OPENCLAW_LIVE_ANTHROPIC_KEY (single-session override), then ANTHROPIC_API_KEYS (comma-separated rotation list), then ANTHROPIC_API_KEY (standard single key), then any ANTHROPIC_API_KEY_* wildcard matches. For daemon setups, place the key in ~/.openclaw/.env. Keys rotate automatically on rate-limit errors (429, quota exceeded). Non-rate-limit errors do not trigger rotation.

How do I set channels.telegram.botToken in OpenClaw without putting the token directly in openclaw.json?

Set the TELEGRAM_BOT_TOKEN environment variable instead. OpenClaw reads it automatically as the fallback for the default Telegram account. For daemon setups, add it to ~/.openclaw/.env. You can also use channels.telegram.tokenFile to point to a regular file containing the token. This keeps secrets out of the JSON config while remaining file-based. Symlinks are rejected for security.

What is the difference between dmPolicy pairing and allowlist in OpenClaw channel config?

Both restrict who can DM the bot, but with different mechanics. pairing (the default) means any unknown sender gets a one-time code to request access. The owner reviews and approves or ignores it. Codes expire after 1 hour, with a cap of 3 pending requests per channel. allowlist is stricter: only senders in allowFrom or the paired allow store can contact the bot. Unknown senders are silently dropped with no code issued.

Can I run openclaw.json changes without restarting the gateway?

Yes. The OpenClaw gateway watches ~/.openclaw/openclaw.json for changes and applies them automatically via hot reload. You do not need to restart the gateway after editing the config file. The CLI method (openclaw config set <key> <value>) also applies changes immediately. If the change causes a schema validation failure, the gateway logs an error and continues running on the previous valid config.



Changelog

DateChange
2026-03-23Initial publication
Did I get something wrong? Or have any other feedback? Let me know here.

More from Stack Junkie.

Get new articles by email.

More guides in The OpenClaw Handbook