How to Configure a Proxy for Each Individual WhatsApp Session in OpenWA

OpenWA supports per-session proxy configuration by storing proxyUrl and proxyType in the database and injecting --proxy-server arguments into Puppeteer when launching each WhatsApp Web client.

OpenWA is an open-source WhatsApp API server that treats each connection as an isolated session, making it possible to run multiple WhatsApp Web clients simultaneously with different network configurations. When you set up a proxy for each individual WhatsApp session, the configuration travels through the entire stack—from the initial API request to the underlying Puppeteer browser instance—ensuring complete network isolation between sessions.

How Per-Session Proxy Configuration Works in OpenWA

OpenWA implements session-scoped proxying by extending the Session entity with two dedicated columns and piping those values through the engine creation pipeline. Unlike global proxy settings, this architecture allows every session to route through a distinct endpoint without affecting other active connections.

The Data Flow from API to Puppeteer

The proxy configuration follows a strict path through the codebase:

  1. API ingestion – The CreateSessionDto at src/modules/session/dto/create-session.dto.ts accepts optional proxyUrl and proxyType fields from the HTTP request payload.

  2. Persistence – SessionService.create() (located at src/modules/session/session.service.ts lines 103-108) writes these values to the proxyUrl and proxyType columns of the Session entity defined in src/modules/session/entities/session.entity.ts.

  3. Engine initialization – When you start the session, SessionService.initializeEngine() (lines 224-231) retrieves the stored proxy fields and passes them to EngineFactory.create() at src/engine/engine.factory.ts (lines 9-13).

  4. Plugin forwarding – The factory forwards the options to the WhatsAppWebJsPlugin at src/plugins/engines/whatsapp-web-js/index.ts, specifically within the createEngine() method (lines 45-60).

  5. Puppeteer injection – Finally, the WhatsAppWebJsAdapter at src/engine/adapters/whatsapp-web-js.adapter.ts (lines 73-89) constructs the Puppeteer launch arguments, appending --proxy-server=<proxyUrl> when a proxy is present.

Because the proxy information is stored per-session in the database, you can restart individual sessions without re-entering proxy credentials, and multiple sessions can run concurrently with completely different proxy endpoints.

Step-by-Step Implementation Guide

1. Create a Session with Proxy Settings

Send a POST request to the /sessions endpoint including the proxyUrl and proxyType fields in the JSON body:

curl -X POST http://localhost:3000/sessions \
  -H "Content-Type: application/json" \
  -d '{
        "name": "my-bot-1",
        "config": { "autoReconnect": true },
        "proxyUrl": "http://user:pass@proxy.example.com:8080",
        "proxyType": "http"
      }'

This stores the proxy configuration in the sessions table alongside the session metadata. The proxyType supports standard protocols including http, https, socks4, and socks5.

2. Start the Session to Activate the Proxy

Initialize the WhatsApp Web client by starting the session:

curl -X POST http://localhost:3000/sessions/<session-id>/start

During startup, SessionService.initializeEngine() injects the stored proxy URL into the Puppeteer launch arguments. The client will route all WhatsApp Web traffic through the specified proxy endpoint rather than the host machine's default connection.

3. Verify Proxy Connection in Logs

The WhatsAppWebJsAdapter logs a sanitized confirmation line when it applies the proxy configuration:


Using proxy: http://***@proxy.example.com:8080

Monitor your server console or log files (generated by the internal createLogger utility) to confirm the proxy is active. If authentication fails or the proxy is unreachable, Puppeteer will throw a timeout error during the browser launch phase.

4. Running Multiple Sessions with Different Proxies

To run several WhatsApp accounts through different geographic endpoints, create multiple sessions with distinct proxy configurations:


# Session A – US proxy

curl -X POST http://localhost:3000/sessions \
  -d '{"name":"bot-us","proxyUrl":"http://us-proxy:3128","proxyType":"http"}'

# Session B – EU proxy  

curl -X POST http://localhost:3000/sessions \
  -d '{"name":"bot-eu","proxyUrl":"http://eu-proxy:3128","proxyType":"http"}'

Start each session independently. Because OpenWA maintains separate Puppeteer instances for each session—each with its own --proxy-server argument—the traffic from bot-us routes through the US endpoint while bot-eu routes through the EU endpoint, with no cross-contamination between sessions.

Supported Proxy Types and Authentication

The proxyType field accepts the following values as implemented in the Session entity:

  • http – Standard HTTP proxy
  • https – SSL/TLS proxy connections
  • socks4 – SOCKS version 4
  • socks5 – SOCKS version 5 with additional authentication support

Include username and password directly in the proxyUrl string (e.g., http://user:pass@host:port) for authenticated proxies. OpenWA passes this string verbatim to Puppeteer's --proxy-server argument; authentication is handled at the browser level during the WhatsApp Web connection handshake.

Summary

  • OpenWA stores proxyUrl and proxyType per session in the Session entity database table.
  • The SessionService.create() method persists proxy settings during session creation, while SessionService.initializeEngine() retrieves them at startup.
  • The WhatsAppWebJsAdapter converts stored proxy data into Puppeteer's --proxy-server launch argument.
  • Multiple concurrent sessions can each use different proxies because the configuration is scoped to individual database records.
  • No global environment variables or external proxy managers are required—the functionality is native to the OpenWA source code.

Frequently Asked Questions

How do I update the proxy for an existing session?

You cannot update the proxy URL for a running session without stopping and recreating it. According to the SessionService implementation in src/modules/session/session.service.ts, proxy fields are only read during the initializeEngine() phase when the Puppeteer browser launches. To change proxies, delete the session and create a new one with the updated proxyUrl value.

Does OpenWA support rotating proxies within a single session?

No, the current architecture binds one proxy URL to one session for its entire lifecycle. The WhatsAppWebJsAdapter sets the --proxy-server argument once during browser initialization at line 73-89 of src/engine/adapters/whatsapp-web-js.adapter.ts. To implement rotation, you must implement a rotating proxy endpoint upstream that provides different IPs through a single proxy URL, or programmatically restart sessions with new configurations.

What happens if the proxy connection fails during startup?

If Puppeteer cannot establish a connection through the specified proxy, the EngineFactory will throw an initialization error before the WhatsApp Web client loads. The session status remains in a pre-authentication state, allowing you to troubleshoot the proxy settings or network connectivity without corrupting the session record in the database. Check the sanitized proxy log line to verify the URL was parsed correctly before the connection attempt.

Can I use different proxy types for different sessions simultaneously?

Yes, the proxyType field is stored per-session in the database alongside proxyUrl. You can run one session with socks5 while another uses http on the same OpenWA instance. The adapter passes the proxy URL directly to Puppeteer, which handles the protocol negotiation based on the URL scheme (socks5:// vs http://), though OpenWA logs the proxyType value for administrative clarity.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →