Skip to main content

Overview

Baileys is a free, open-source WhatsApp Web API implementation that lets you connect to WhatsApp without official business API credentials. It works by emulating the WhatsApp Web client and uses QR code scanning for authentication.
Baileys connects through WhatsApp Web, making it perfect for personal use, testing, or applications that don’t require official Meta Business API credentials.

How It Works

Baileys establishes a WebSocket connection to WhatsApp servers by:
  1. Generating a QR code or pairing code for authentication
  2. Maintaining a persistent session with encrypted credentials
  3. Synchronizing messages, contacts, and chat history
  4. Handling reconnections automatically

Authentication Methods

The default authentication method displays a QR code that you scan with your WhatsApp mobile app.
# Configure in .env
QRCODE_LIMIT=30
QRCODE_COLOR='#175197'

QR Code Configuration

  • QRCODE_LIMIT: Maximum number of QR code regenerations before timeout (default: 30)
  • QRCODE_COLOR: HEX color for the QR code dark pixels (default: ‘#175197’)
When you create an instance, the API generates a QR code accessible via webhook events:
{
  "event": "qrcode.updated",
  "qrcode": {
    "instance": "my-instance",
    "code": "2@abc123...",
    "base64": "data:image/png;base64,iVBOR..."
  }
}

Session Configuration

Configure how your instance appears in WhatsApp’s “Linked Devices”:
.env
# Name displayed on smartphone connection
CONFIG_SESSION_PHONE_CLIENT=Evolution API

# Browser type: Chrome | Firefox | Edge | Opera | Safari
CONFIG_SESSION_PHONE_NAME=Chrome
These settings determine how your connection appears in WhatsApp:
const session = this.configService.get<ConfigSessionPhone>('CONFIG_SESSION_PHONE');

if (number || this.phoneNumber) {
  this.phoneNumber = number;
} else {
  const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()];
  browserOptions = { browser };
}

Connection Lifecycle

1

Initialize Connection

Create an instance to start the connection process:
POST /instance/create
{
  "instanceName": "my-instance",
  "token": "your-api-key"
}
2

Authenticate

Scan the QR code or enter the pairing code in WhatsApp. The API monitors authentication status and emits connection events:
// Connection states tracked in source
public stateConnection: wa.StateConnection = { state: 'close' };

// States: 'connecting' | 'open' | 'close'
3

Session Persistence

Evolution API automatically saves your session to prevent re-authentication:
  • Database: Prisma stores encrypted credentials
  • Redis: Optional caching layer for faster reconnections
  • File Provider: Alternative storage backend
// Session storage is automatic
if (cache?.REDIS.ENABLED && cache?.REDIS.SAVE_INSTANCES) {
  return await useMultiFileAuthStateRedisDb(this.instance.id, this.cache);
}

if (db.SAVE_DATA.INSTANCE) {
  return await useMultiFileAuthStatePrisma(this.instance.id, this.cache);
}
4

Reconnection Handling

The API automatically reconnects on disconnection, except for:
  • Logout (code 401)
  • Forbidden/banned account (code 403)
  • Payment required (code 402)
  • Invalid session (code 406)
const codesToNotReconnect = [
  DisconnectReason.loggedOut,
  DisconnectReason.forbidden,
  402,
  406
];
const shouldReconnect = !codesToNotReconnect.includes(statusCode);

Connection Events

Monitor connection status through webhook events:
{
  "event": "connection.update",
  "instance": "my-instance",
  "state": "open",
  "statusReason": 200,
  "wuid": "[email protected]",
  "profileName": "John Doe",
  "profilePictureUrl": "https://..."
}

Connection States

StateDescription
connectingEstablishing connection to WhatsApp servers
openSuccessfully connected and authenticated
closeDisconnected (may attempt reconnection)

Features

Message Synchronization

Baileys supports full history sync when enabled:
.env
# Sync full message history on first connection
SYNC_FULL_HISTORY=true

Group Support

Control whether to ignore group messages:
# Settings can be configured per instance
{
  "groupsIgnore": false,
  "alwaysOnline": true,
  "readMessages": false,
  "readStatus": false,
  "syncFullHistory": true
}
Set groupsIgnore: true to reduce message volume if you only need direct messages.

Media Handling

Baileys automatically downloads and processes media messages:
const isMedia = received?.message?.imageMessage ||
                received?.message?.videoMessage ||
                received?.message?.stickerMessage ||
                received?.message?.documentMessage ||
                received?.message?.audioMessage;

Limitations vs Business API

Baileys has important limitations compared to the official Business API:
FeatureBaileysBusiness API
CostFreePaid per conversation
AuthenticationQR code/pairingAPI credentials
Rate limitsWhatsApp Web limitsHigher API limits
Ban riskPossible if misusedLower risk
Message templatesNot supportedSupported
Official supportCommunityMeta support
Multi-deviceLimitedFull support
Business featuresBasicAdvanced (catalogs, etc.)

Best Practices

1

Avoid Spam

Don’t send bulk messages or automated spam. This can get your number banned from WhatsApp.
2

Rate Limiting

Implement delays between messages to avoid detection:
{
  "number": "5511999999999",
  "text": "Hello!",
  "delay": 1200
}
3

Session Backup

Regularly backup your session data to avoid re-authentication if the instance is deleted.
4

Monitor Connection

Subscribe to connection.update webhooks to handle disconnections gracefully.

Troubleshooting

QR Code Not Appearing

Check your webhook configuration and ensure events are enabled:
.env
WEBHOOK_EVENTS_QRCODE_UPDATED=true

Connection Keeps Closing

Verify your session is being saved:
.env
DATABASE_SAVE_DATA_INSTANCE=true

Messages Not Syncing

Enable full history sync and check group settings:
{
  "syncFullHistory": true,
  "groupsIgnore": false
}

Advanced Configuration

Proxy Support

Configure proxy settings for Baileys connections:
.env
PROXY_HOST=proxy.example.com
PROXY_PORT=8080
PROXY_PROTOCOL=http
PROXY_USERNAME=user
PROXY_PASSWORD=pass

Custom Baileys Version

The API automatically fetches the latest WhatsApp Web version:
const baileysVersion = await fetchLatestWaWebVersion({});
const version = baileysVersion.version;
// Baileys version: [2, 3000, 1234567890]

Logging

Control Baileys log output:
.env
# Log levels: fatal | error | warn | info | debug | trace
LOG_BAILEYS=error

Next Steps

Send Messages

Learn how to send text, media, and interactive messages

Receive Messages

Set up webhooks to receive messages and events

Connection Management

Master connection lifecycle and reconnection strategies

Business API

Compare with official WhatsApp Business API

Build docs developers (and LLMs) love