Skip to main content
GOWA supports managing multiple WhatsApp accounts simultaneously within a single server instance. Each WhatsApp connection is represented as a “device” with its own state, session, and configuration.

Device concepts

Device ID vs JID

Two distinct identifiers are used throughout the system:

Device ID

User-defined alias or auto-generated UUID
  • Used in API requests (X-Device-Id header)
  • Used in URLs (/devices/{device_id})
  • Example: my-business-account, customer-support

JID (WhatsApp ID)

WhatsApp-assigned identifier
  • Format: [email protected]
  • Assigned after successful login
  • Used for database queries and webhook payloads
Confusing Device ID and JID causes data isolation bugs. Always use the correct identifier for your use case.

Device instance

Each device maintains:
  • WhatsApp connection - Active WebSocket to WhatsApp servers
  • Session storage - SQLite database with encryption keys
  • Message history - Chat and message records
  • Event handlers - Webhook forwarding, auto-reply, auto-read
  • Media storage - Downloaded images, videos, files

Device lifecycle

1

Create device

Register a new device slot with a custom ID or auto-generated UUID:
cURL
curl -X POST http://localhost:3000/devices \
  -H "Content-Type: application/json" \
  -d '{"device_id": "my-device"}'
Initial state: disconnected
2

Login to WhatsApp

Choose authentication method:
curl http://localhost:3000/devices/my-device/login
Scan QR with WhatsApp mobile app.
State transitions: disconnectedconnectingconnected
3

Use device

All API requests require device scoping:
curl -X POST http://localhost:3000/send/message \
  -H "X-Device-Id: my-device" \
  -H "Content-Type: application/json" \
  -d '{"phone": "[email protected]", "message": "Hello"}'
4

Logout and remove

Proper cleanup sequence:
# 1. Logout from WhatsApp (removes from linked devices)
curl -X POST http://localhost:3000/devices/my-device/logout

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

Device states

StateDescriptionCan send messages?
disconnectedCreated but not logged in
connectingAuthentication in progress
connectedLogged in and ready
reconnectingTemporary connection loss⚠️ Queued
logged_outSession invalidated

Default device behavior

If only one device is registered:
  • X-Device-Id header is optional
  • All requests automatically use the single device
  • Simplifies single-account deployments
With multiple devices:
  • X-Device-Id header is required
  • Missing header returns 400 DEVICE_ID_REQUIRED error
  • Each device maintains independent state

Device manager

Central orchestrator (src/infrastructure/whatsapp/device_manager.go) handles:
  • Device instance lifecycle
  • Connection pooling
  • Session persistence
  • Event distribution
  • Database scoping
// Key responsibilities:
// - CreateDevice() - Register new device slot
// - GetDevice() - Retrieve device by ID
// - LoginDevice() - Initiate WhatsApp login
// - LogoutDevice() - Clean session and disconnect
// - RemoveDevice() - Delete from registry
Source: src/infrastructure/whatsapp/device_manager.go (602 lines)

Storage isolation

Each device has isolated storage:
storages/
├── [email protected]/  # Device 1 JID
│   ├── session.db                 # Encryption keys
│   └── media/                      # Downloaded files
└── [email protected]/  # Device 2 JID
    ├── session.db
    └── media/
Database tables (chats, messages) use device_id column for data isolation. Always include device_id in queries to prevent cross-device data leaks.

Next steps

Authentication

Learn about QR code and pairing code login methods

Device scoping

Understand X-Device-Id header and query parameters

Multi-device guide

Best practices for managing multiple accounts

Device API

Complete device management API reference

Build docs developers (and LLMs) love