Configuration and CLI
Core runtime settings for custom code and the most important Easy API CLI flags.
Use this page to choose runtime settings, CLI flags, environment variables, and plugin configuration that match the way you start open-wa.
Common config fields
Use the config object passed to createClient() or exported from wa.config.* for library/runtime behavior such as:
sessionId: stable session naminguserDataDir: persistent browser profile directoryheadless: visible vs background browseruseChrome/executablePath: browser selectionqrTimeout/authTimeout: authentication timingmaxQr: limit QR emission countcacheEnabled: page/runtime memory trade-offlicenseKey: feature unlocks where applicableproxyServerCredentials: outbound proxy supportlinkCode: link-code login for embeddedcreateClientapplications
Full Configuration Reference
The reference below lists supported configuration fields, types, defaults, and descriptions.
Prop
Type
Example
import { createClient } from '@open-wa/wa-automate';
const client = await createClient({
sessionId: 'sales',
useChrome: true,
headless: true,
qrTimeout: 0,
authTimeout: 60,
});Config file discovery
The CLI loads configuration through the shared config package before applying CLI overrides. By default, discovery starts from the current working directory.
Discovery order is:
- The
wakey inpackage.json wa.config.jswa.config.cjswa.config.mjswa.config.tswa.config.mtswa.config.ctswa.config.json.warc.warc.jsoncli.config.jslegacy compatibilitycli.config.jsonlegacy compatibility
The first matching file wins. Use --config ./path/to/config when you want to load a specific file instead of relying on discovery.
The config loader merges values in this order:
- schema defaults
- config file
WA_*environment variables- CLI flags
- programmatic overrides, mainly for tests and embedding
The config loader replaces arrays instead of concatenating them. A later plugins value replaces the earlier value.
Config files can export a plain object or a function that returns an object. The config loader supports TypeScript config files.
JSON/TS examples
These config fields are available to embedded createClient applications. In the published Easy API CLI 5.1.0, startup applies host: 0.0.0.0 and port: 8002 after config and environment loading, so pass --host and --port explicitly when starting the CLI.
Use JSON when your config is static:
{
"sessionId": "sales",
"port": 8080,
"host": "0.0.0.0",
"apiKey": "replace-with-env-in-production",
"headless": true,
"qrTimeout": 0,
"authTimeout": 60,
"licenseKey": "YOUR-LICENSE-KEY"
}Env vars
Supply runtime config with WA_* environment variables. The loader converts snake-case names to config keys. For example, WA_SESSION_ID becomes sessionId.
The config loader converts values when possible:
true,1,yes, andonbecometruefalse,0,no, andoffbecomefalse- numeric strings become numbers for numeric schema fields
- the loader parses JSON values such as
{...}or[...]for object and array fields
Common runtime environment variables:
| Environment variable | Config field | Notes |
|---|---|---|
WA_SESSION_ID | sessionId | Stable session name |
WA_PORT | port | The shared config loader reads this value, but the published CLI 5.1.0 applies port: 8002 after environment variables. Pass --port to choose another port. |
WA_HOST | host | The shared config loader reads this value, but the published CLI 5.1.0 applies host: 0.0.0.0 after environment variables. Pass --host to choose another bind address. |
WA_API_KEY | apiKey | API authentication key |
WA_USER_DATA_DIR | userDataDir | Persistent browser profile directory |
WA_LICENSE_KEY | licenseKey | License key where applicable |
WA_LINK_CODE | linkCode | The shared config loader maps this variable. The published CLI 5.1.0 does not forward the field into startup; pass linkCode explicitly to embedded createClient. |
WA_HEADLESS | headless | Browser visibility |
WA_USE_CHROME | useChrome | Prefer local Chrome |
WA_QR_TIMEOUT | qrTimeout | QR wait time |
WA_AUTH_TIMEOUT | authTimeout | Auth wait time |
WA_WEBHOOK | webhook | Webhook target URL |
WA_PLUGINS | plugins | JSON array of plugin refs |
WA_PLUGIN_CONFIG | pluginConfig | JSON object keyed by plugin name |
There are also compatibility aliases for a few browser-related settings, including WA_DEBUG for devtools, WA_BROWSER_WS_ENDPOINT for browserWSEndpoint, WA_BYPASS_CSP for bypassCSP, and WA_USE_LIGHTPANDA for useLightpanda.
High-value CLI flags
# networking (pass explicit values to override published CLI 5.1.0 defaults)
--host "127.0.0.1"
--port 8080
--api-key "your-secure-key"
# session identity
--session-id sales
# runtime helpers
--pm2
--tunnel
# licensing
--license-key "YOUR-LICENSE-KEY"
# isolate explicit chat-triggered code/tool execution
--sandbox-chats
--sandbox-isolation containerPass linkCode explicitly in an embedded createClient configuration. The shared config loader maps WA_LINK_CODE, but direct createClient calls do not load environment variables automatically. The published Easy API CLI 5.1.0 does not forward link-code settings and has no --link-code flag, so use its QR flow. Select a config file with --config when you need to choose it explicitly. sandboxChats applies only to code or tools explicitly sent through executeInChatSandbox; it does not create a Chromium session per chat or change ordinary message handlers. The boolean form uses the process policy, while the object form controls the isolation boundary and resource access:
export default defineConfig({
sandboxChats: {
isolation: 'container', // worker | process | container
timeoutMs: 30_000,
idleTimeoutMs: 300_000,
memoryMb: 256,
concurrency: 1,
filesystem: 'none', // none | read-only | workspace
network: 'none', // none | allowlist
networkAllowlist: [],
env: 'none',
capabilities: ['sendText'],
},
});Container mode is the strong boundary for hostile code. Process mode strips ambient globals, environment, and filesystem permission and applies time/memory/output limits, but Node's permission model is defense in depth rather than a complete security boundary. Worker mode is intended for availability isolation around trusted code. Worker and process policies fail closed if they request filesystem, network, or environment access; those host-access policies require container mode.
Full CLI reference
These are the major flags most users need when starting the Easy API from the command line.
| Flag | Maps to | Description |
|---|---|---|
--port 8080, -p 8080 | port | Port for the Easy API server. |
--api-key "key", --key "key", -k "key" | apiKey | Protects API requests. Use this before exposing the API beyond localhost. |
--session-id sales | sessionId | Names the session and keeps auth state separate from other sessions. |
--webhook "https://...", -w "https://..." | webhook | Parsed as a webhook target URL, but current v5 source warns that CLI webhook registration parity is not restored. Use @open-wa/integration-webhook in plugins plus pluginConfig.webhook for source-backed delivery. |
--pm2 | PM2 wrapper | Starts the CLI under PM2 instead of running directly. |
--license-key "key", -l "key" | licenseKey | Supplies a license key for licensed features where applicable. |
linkCode in library config | linkCode | Embedded createClient in 5.1.0 supports link-code login. The published Easy API CLI does not forward this setting and has no --link-code flag. |
--tunnel | transitional | Legacy tunnel flag. v5 currently warns that tunnel setup parity is not restored. |
--mcp | unsupported by the current v5 CLI | The parser does not accept this flag. Configure mcp: { enabled: true } in wa.config.*, keep apiKey enabled, and use --config ./wa.config.mjs when selecting that file explicitly. |
--host "0.0.0.0", -h "0.0.0.0" | host | Local bind host for the Easy API server. |
--sandbox-chats | sandboxChats: true | Enables isolated execution for explicit per-chat code/tool calls. |
--sandbox-isolation process | sandboxChats.isolation | Selects worker, process, or container; use container for hostile code. |
Other useful runtime flags include --host, --headless, --headful, --use-chrome, --use-lightpanda, --qr-timeout, --dashboard-port, --no-dashboard, --no-ezqr, --ephemeral, --sandbox-chats, --sandbox-isolation, --log-console, --log-level, and --verbose.
The standalone @open-wa/cli entrypoint also accepts output-mode flags such as --interactive, --non-interactive, and --output-mode plain. Those affect terminal output before the runtime config is parsed.
CLI-to-schema mapping
Most CLI flags are thin aliases over config schema fields. For example:
npx @open-wa/wa-automate@5.1.0 \
--session-id sales \
--host 127.0.0.1 \
--port 8080 \
--api-key "$WA_API_KEY" \
--license-key "$WA_LICENSE_KEY"is equivalent to these config fields:
export default {
sessionId: 'sales',
port: 8080,
apiKey: process.env.WA_API_KEY,
licenseKey: process.env.WA_LICENSE_KEY,
};Explicit CLI flags win over config-file and environment values. The published CLI 5.1.0 also applies its 0.0.0.0 and 8002 startup defaults after config loading, so always pass --host and --port when those values matter.
Not every flag is a schema field. --config selects which file to load, --pm2 controls process management, and --name controls the PM2 process name.
Deprecated flags
Some v4-era flags remain as compatibility warnings in v5. Replace them with the documented v5 settings below.
When in doubt, prefer the config schema and the flags in this page over older v4 examples.
Plugins field docs
Use plugins to load reusable integrations into the runtime process.
export default {
plugins: [
'@open-wa/integration-webhook',
'@open-wa/integration-chatwoot',
'./plugins/my-local-plugin',
'/absolute/path/to/plugin.js',
],
};Each item is a plugin reference. It can be an npm package name, a scoped package name, or a file path. The module must export a default plugin or a named plugin export.
Plugins loaded from plugins are imported during createClient() startup. If a plugin does not expose meta.name, it cannot be registered correctly.
PluginConfig docs
Use pluginConfig for plugin-specific settings. The object is keyed by each plugin's meta.name, not necessarily by the package name.
export default {
plugins: ['@open-wa/integration-webhook', './plugins/moderation'],
pluginConfig: {
webhook: {
url: 'https://your-app.example/webhooks/open-wa',
headers: {
'X-Webhook-Secret': process.env.WEBHOOK_SECRET,
},
},
moderation: {
enabled: true,
apiKey: process.env.MODERATION_API_KEY,
},
},
};At startup, open-wa looks up pluginConfig[plugin.meta.name]. If the plugin defines a config schema, that value is validated before it is passed to the plugin's init() function.
Example with plugin
import { defineConfig } from '@open-wa/config';
export default defineConfig({
sessionId: 'support',
port: 8080,
host: '0.0.0.0',
apiKey: process.env.WA_API_KEY,
webhook: process.env.WA_WEBHOOK,
plugins: [
'@open-wa/integration-webhook',
'./plugins/internal-audit-plugin',
],
pluginConfig: {
webhook: {
url: process.env.WA_WEBHOOK,
headers: {
'X-Webhook-Secret': process.env.WEBHOOK_SECRET,
},
},
'internal-audit': {
enabled: true,
logLevel: 'info',
},
},
});Secret management
Keep secrets out of committed config files. Use environment variables for apiKey, licenseKey, webhook secrets, Chatwoot tokens, and plugin API keys.
For local development, keep the .env file in .gitignore. In production, use the platform secret store or a secret manager. Do not log complete config objects. Nested pluginConfig values frequently contain tokens.
Session events worth knowing about
If you need QR images, session-data capture, or low-level launch state, read Session events.
One important caveat
The old Docusaurus site generated a complete CLI options table at build time. This page gives the common flags first. The detailed config surface must agree with the generated reference and runtime schema.
Was this helpful?
Your answer includes the page path and docs version.
