Multiple sessions
Run more than one WhatsApp account with separate session profiles, API keys, and failure boundaries.
Give each WhatsApp account a unique sessionId and persistent browser profile.
For separate Easy API processes, also assign a unique port and API key. The
Easy API quick start covers installation and
API-key setup; use the Docker guide when each
session needs its own persistent volume.
One process per session
Separate processes keep browser failures, restarts, and API credentials scoped
to one account. The commands below target the published v5.1.0 CLI; specify
--host and --port explicitly for that release. Before running them, set
different, nonempty SALES_API_KEY and SUPPORT_API_KEY values in your secret
store or shell environment.
npx @open-wa/wa-automate@5.1.0 \
--session-id sales --host 127.0.0.1 --port 8081 --api-key "$SALES_API_KEY"
npx @open-wa/wa-automate@5.1.0 \
--session-id support --host 127.0.0.1 --port 8082 --api-key "$SUPPORT_API_KEY"Keep the API processes on loopback or a private network and configure your
reverse proxy with a separate upstream credential for each session. /health
is public and can include QR or diagnostic data, so do not expose it through a
public proxy. See Easy API security.
One Node.js process
Use one process when your application needs direct control of each runtime. Create and retain one runtime per session, and stop each runtime during application shutdown.
import { createClient } from '@open-wa/wa-automate';
import { PuppeteerDriver } from '@open-wa/driver-puppeteer';
const sessions = new Map();
for (const sessionId of ['sales', 'support']) {
const runtime = await createClient({
sessionId,
userDataDir: `./private/sessions/${sessionId}`,
driver: new PuppeteerDriver(),
headless: true,
});
sessions.set(sessionId, runtime);
await runtime.start();
}Each runtime owns a browser context, so resource use grows with the number of active accounts. If one process exits, all its sessions stop; supervise and recover them as a unit or move sessions into separate processes when they need independent availability.
Route requests to the intended session
Keep the session-to-origin and session-to-key mapping in your application. Authenticate the upstream request with the key for that session and reject unknown session names before forwarding traffic.
| Session | Local API origin | API key source |
|---|---|---|
sales | http://127.0.0.1:8081 | SALES_API_KEY |
support | http://127.0.0.1:8082 | SUPPORT_API_KEY |
For example, a request to sales can be forwarded to the method route on its
own API process:
const salesApiKey = process.env.SALES_API_KEY;
if (!salesApiKey) {
throw new Error('Set SALES_API_KEY before sending requests');
}
const response = await fetch('http://127.0.0.1:8081/api/sendText', {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': salesApiKey,
},
body: JSON.stringify({
to: '447700900000@c.us',
content: 'Your update is ready.',
}),
});
if (!response.ok) {
throw new Error(`The sales session returned ${response.status}`);
}The exact input shape comes from the method contract; see the
sendText reference. Do not let a
user with access to one session inherit permission to send from another.
Recovery and capacity
Monitor each Easy API process separately and wait for /health to report
connected: true and session.ready: true after startup or restart. A
responding port establishes HTTP liveness only. Keep the session ID, profile
directory, API key, logs, and restart policy paired so you can recover one
account without changing another.
Browser memory, CPU, media work, sockets, and reconnect bursts determine how many sessions a host can support. There is no fixed safe count; add sessions only after measuring the workload on the intended host. For process supervision, use your platform's service manager or container runtime.
See authentication and session recovery for profile handling and configuration and CLI for runtime flags.
Was this helpful?
Your answer includes the page path and docs version.
