open-wa v5 is alpha. Use v4.76.0 for mature production systems unless you are validating v5.
The Client APIAPI ExplorerLicensing

Configuration and CLI

Core runtime settings for custom code and the most important Easy API CLI flags.

CLI Wally

Configuration and CLI

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 naming
  • userDataDir — persistent browser profile directory
  • headless — visible vs background browser
  • useChrome / executablePath — browser selection
  • qrTimeout / authTimeout — authentication timing
  • maxQr — limit QR emission count
  • cacheEnabled — page/runtime memory trade-off
  • licenseKey — feature unlocks where applicable
  • proxyServerCredentials — outbound proxy support
  • linkCode — link-code login flow

Full Configuration Reference

Use the <AutoTypeTable /> to explore all available configuration options directly from the source code.

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:

  1. package.json using the wa key
  2. wa.config.js
  3. wa.config.cjs
  4. wa.config.mjs
  5. wa.config.ts
  6. wa.config.mts
  7. wa.config.cts
  8. wa.config.json
  9. .warc
  10. .warc.json
  11. cli.config.js legacy compatibility
  12. cli.config.json legacy compatibility

The first matching file wins. Use --config ./path/to/config when you want to load a specific file instead of relying on discovery.

Config values are merged in this order:

  1. schema defaults
  2. config file
  3. WA_* environment variables
  4. CLI flags
  5. programmatic overrides, mainly for tests and embedding

Arrays are replaced rather than concatenated, so a later plugins value replaces the earlier one.

Config files can export a plain object or a function that returns an object. TypeScript config files are supported by the config loader.

JSON/TS examples

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"
}

Use TypeScript or JavaScript when you need environment variables or computed values:

import { defineConfig } from '@open-wa/config';

export default defineConfig({
  sessionId: process.env.WA_SESSION_ID ?? 'sales',
  port: Number(process.env.WA_PORT ?? 8080),
  host: '0.0.0.0',
  apiKey: process.env.WA_API_KEY,
  userDataDir: process.env.WA_USER_DATA_DIR,
  headless: true,
  qrTimeout: 0,
  authTimeout: 60,
  licenseKey: process.env.WA_LICENSE_KEY,
});

In v5 config examples, prefer the same WA_* environment names that the config loader reads. If your deployment platform stores secrets under another name, map them into config explicitly instead of assuming bare names such as PORT or API_KEY are runtime config env vars.

Env vars

Runtime config can be supplied with WA_* environment variables. Names are converted from snake case to config keys, so WA_SESSION_ID becomes sessionId, WA_API_KEY becomes apiKey, and WA_QR_TIMEOUT becomes qrTimeout.

Values are coerced where possible:

  • true, 1, yes, and on become true
  • false, 0, no, and off become false
  • numeric strings become numbers for numeric schema fields
  • JSON-looking values such as {...} or [...] are parsed for object and array fields

Common runtime environment variables:

Environment variableConfig fieldNotes
WA_SESSION_IDsessionIdStable session name
WA_PORTportEasy API port
WA_HOSThostEasy API host
WA_API_KEYapiKeyAPI authentication key
WA_USER_DATA_DIRuserDataDirPersistent browser profile directory
WA_LICENSE_KEYlicenseKeyLicense key where applicable
WA_LINK_CODElinkCodePhone number for link-code login
WA_HEADLESSheadlessBrowser visibility
WA_USE_CHROMEuseChromePrefer local Chrome
WA_QR_TIMEOUTqrTimeoutQR wait time
WA_AUTH_TIMEOUTauthTimeoutAuth wait time
WA_WEBHOOKwebhookWebhook target URL
WA_PLUGINSpluginsJSON array of plugin refs
WA_PLUGIN_CONFIGpluginConfigJSON 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
--port 8080
--api-key "your-secure-key"
--host "0.0.0.0"

# session identity
--session-id sales
--link-code "447123456789"

# runtime helpers
--pm2
--tunnel
--multi-device

# licensing
--license-key "YOUR-LICENSE-KEY"

Full CLI reference

These are the major flags most users need when starting the Easy API from the command line.

FlagMaps toDescription
--port 8080, -p 8080portPort for the Easy API server.
--api-key "key", --key "key", -k "key"apiKeyProtects API requests. Use this before exposing the API beyond localhost.
--session-id salessessionIdNames the session and keeps auth state separate from other sessions.
--webhook "https://...", -w "https://..."webhookParsed 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.
--pm2PM2 wrapperStarts the CLI under PM2 instead of running directly.
--license-key "key", -l "key"licenseKeySupplies a license key for licensed features where applicable.
--link-code "447123456789"linkCodeUses link-code login instead of relying only on QR scanning.
--tunneltransitionalLegacy tunnel flag. v5 currently warns that tunnel setup parity is not restored.
--mcpfuture or other-alpha shorthand onlyThe current source does not parse --mcp. Configure mcp: { enabled: true } in wa.config.* instead, keep apiKey enabled, and use --mcp only if your installed build documents it.
--host "0.0.0.0", -h "0.0.0.0"hostLocal bind host for the Easy API server.

Other useful runtime flags include --host, --headless, --headful, --use-chrome, --use-lightpanda, --qr-timeout, --dashboard-port, --no-dashboard, --no-ezqr, --ephemeral, --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 \
  --session-id sales \
  --port 8080 \
  --api-key "$WA_API_KEY" \
  --license-key "$WA_LICENSE_KEY" \
  --link-code "447123456789"

is equivalent to these config fields:

export default {
  sessionId: 'sales',
  port: 8080,
  apiKey: process.env.WA_API_KEY,
  licenseKey: process.env.WA_LICENSE_KEY,
  linkCode: '447123456789',
};

CLI flags win over config-file and environment values. That makes config files good for stable defaults and CLI flags good for one-off local overrides.

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

v5 is still alpha, so a few v4-era flags are present only as transitional compatibility warnings.

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, a relative path, or an absolute path. The module should export a plugin as its default export or as 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, a .env file is convenient, but it should stay in .gitignore. In production, prefer your platform's secret store or a dedicated secret manager. Avoid logging full config objects because nested pluginConfig values often 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 full CLI options table at build time. This new page intentionally documents the commonly used flags first, while the deeper config surface should ultimately stay aligned with the generated reference and runtime schema.

Wally the Walrus typing

Was this helpful?

Wally and his cute companion coffee mug are coding day and night to keep this up-to-date!

On this page