Skip to main content
GOWA v8 introduced full multi-device support, allowing you to connect and manage multiple WhatsApp accounts within a single server instance. Each account operates independently with its own sessions, webhooks, and configuration.

What is multi-device?

Multi-device in GOWA refers to managing multiple WhatsApp accounts (different phone numbers), not WhatsApp’s own multi-device feature (which allows linking phones, tablets, and desktops to a single account).

Single-device mode

  • One WhatsApp account per server
  • Simplified API (no device scoping required)
  • Default behavior for one registered device

Multi-device mode

  • Multiple WhatsApp accounts per server
  • Device scoping required (X-Device-Id header)
  • Ideal for agencies, multi-tenant systems

Device scoping

All API requests in multi-device mode must specify which device to use.
cURL
curl -X POST http://localhost:3000/send/message \
  -H "X-Device-Id: business-account" \
  -H "Content-Type: application/json" \
  -d '{"phone": "[email protected]", "message": "Hello"}'

device_id query parameter

curl -X POST "http://localhost:3000/send/message?device_id=business-account" \
  -H "Content-Type: application/json" \
  -d '{"phone": "[email protected]", "message": "Hello"}'
If only one device is registered, device scoping is optional and the single device is used automatically.

Setting up multiple devices

1

Create first device

curl -X POST http://localhost:3000/devices \
  -H "Content-Type: application/json" \
  -d '{"device_id": "sales-team"}'
2

Login first device

curl http://localhost:3000/devices/sales-team/login
Scan QR code with Sales team WhatsApp account.
3

Create second device

curl -X POST http://localhost:3000/devices \
  -H "Content-Type: application/json" \
  -d '{"device_id": "support-team"}'
4

Login second device

curl http://localhost:3000/devices/support-team/login
Scan QR code with Support team WhatsApp account.
5

Use both devices

# Send from Sales
curl -X POST http://localhost:3000/send/message \
  -H "X-Device-Id: sales-team" \
  -d '{"phone": "[email protected]", "message": "Sales inquiry"}'

# Send from Support
curl -X POST http://localhost:3000/send/message \
  -H "X-Device-Id: support-team" \
  -d '{"phone": "[email protected]", "message": "Support ticket"}'

Device isolation

Each device maintains completely isolated:

Sessions

storages/
├── [email protected]/  # Sales team JID
│   ├── session.db
│   └── media/
└── [email protected]/  # Support team JID
    ├── session.db
    └── media/

Database records

All chat and message records include device_id for isolation:
SELECT * FROM messages 
WHERE device_id = '[email protected]';
Always scope database queries by device_id to prevent data leaks between accounts.

Webhooks

Webhook payloads include top-level device_id field:
{
  "event": "message",
  "device_id": "[email protected]",
  "payload": {
    "from": "[email protected]",
    "message": "Hello"
  }
}
Your webhook handler can route events by device:
app.post('/webhook', (req, res) => {
  const { device_id, event, payload } = req.body;
  
  if (device_id === '[email protected]') {
    // Handle Sales team events
  } else if (device_id === '[email protected]') {
    // Handle Support team events
  }
  
  res.sendStatus(200);
});

Managing devices

List all devices

curl http://localhost:3000/devices
Response:
{
  "code": 200,
  "data": [
    {
      "device_id": "sales-team",
      "phone": "628111111111",
      "name": "Sales WhatsApp",
      "state": "connected",
      "jid": "[email protected]"
    },
    {
      "device_id": "support-team",
      "phone": "628222222222",
      "name": "Support WhatsApp",
      "state": "connected",
      "jid": "[email protected]"
    }
  ]
}

Check device status

curl http://localhost:3000/devices/sales-team/status

Remove device

# 1. Logout from WhatsApp
curl -X POST http://localhost:3000/devices/sales-team/logout

# 2. Remove from server
curl -X DELETE http://localhost:3000/devices/sales-team

WebSocket device scoping

Connect WebSocket with device_id query parameter:
const ws = new WebSocket('ws://localhost:3000/ws?device_id=sales-team');

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log('Sales team message:', message);
};

Use cases

Each customer gets their own WhatsApp device:
// Customer signup flow
async function createCustomerWhatsApp(customerId, phone) {
  // Create device with customer ID
  await fetch('http://localhost:3000/devices', {
    method: 'POST',
    body: JSON.stringify({ device_id: `customer-${customerId}` })
  });
  
  // Generate pairing code
  const { code } = await fetch(`http://localhost:3000/devices/customer-${customerId}/login/code`, {
    method: 'POST',
    body: JSON.stringify({ phone })
  }).then(r => r.json());
  
  return code; // Show to customer
}
Each client gets dedicated WhatsApp account:
# Client A - E-commerce store
device_id: client-a-ecommerce

# Client B - Restaurant
device_id: client-b-restaurant

# Client C - Consultancy
device_id: client-c-consulting
Different departments use different accounts:
  • sales - Sales team
  • support - Customer support
  • marketing - Marketing campaigns
  • hr - HR recruitment
Different numbers for different regions:
  • us-east - US East Coast
  • us-west - US West Coast
  • eu - Europe
  • apac - Asia Pacific

Error handling

Missing device_id

With multiple devices registered:
{
  "code": 400,
  "message": "DEVICE_ID_REQUIRED: Multiple devices registered, X-Device-Id header or device_id query parameter required"
}
Solution: Add X-Device-Id header or device_id query param.

Device not found

{
  "code": 404,
  "message": "DEVICE_NOT_FOUND: Device 'invalid-id' not found"
}
Solution: List devices with GET /devices to verify device_id.

Device not connected

{
  "code": 400,
  "message": "Device not connected. Please login first."
}
Solution: Check status with GET /devices/{device_id}/status and login if needed.

Best practices

Descriptive IDs

Use meaningful device IDs: customer-123, sales-team, not device1, dev2

Monitor connections

Regularly check device status and reconnect disconnected devices

Database queries

Always include device_id in WHERE clauses to prevent data leaks

Webhook routing

Use device_id in webhook payloads to route events correctly

Limitations

WhatsApp rate limits apply per account - Multiple devices don’t increase rate limits, they provide account isolation.
  • Maximum devices: Limited by server resources (memory, CPU)
  • Each device requires ~50-100MB RAM
  • Typical server handles 10-50 devices comfortably

Next steps

Device management API

Complete device CRUD operations

Device scoping

Detailed device scoping reference

Webhooks

Multi-device webhook handling

Configuration

Environment variables and settings

Build docs developers (and LLMs) love