Skip to main content

Overview

Evolution API manages WhatsApp connections through instances. Each instance represents a separate WhatsApp connection with its own authentication, session, and message queue.
Connection behavior differs between providers: Baileys requires active connection management, while Business API connections are always active.

Connection Lifecycle

1

Create Instance

Initialize a new WhatsApp instance:
POST /instance/create
{
  "instanceName": "customer-support",
  "token": "your-api-key",
  "qrcode": true
}
Response:
{
  "instance": {
    "instanceName": "customer-support",
    "status": "created"
  },
  "hash": {
    "apikey": "generated-instance-token"
  }
}
2

Connect to WhatsApp

For Baileys, authenticate via QR code or pairing code. For Business API, the connection is immediate.Baileys Connection:
public async connectToWhatsapp(number?: string): Promise<WASocket> {
  try {
    this.loadChatwoot();
    this.loadSettings();
    this.loadWebhook();
    this.loadProxy();

    return await this.createClient(number);
  } catch (error) {
    this.logger.error(error);
    throw new InternalServerErrorException(error?.toString());
  }
}
Business API Connection:
public stateConnection: wa.StateConnection = { state: 'open' };
// Business API is always connected once configured
3

Monitor Status

Track connection state through webhooks or API queries:
GET /instance/connectionState/:instanceName
{
  "instance": {
    "instanceName": "customer-support",
    "state": "open"
  },
  "statusReason": 200
}
4

Disconnect or Delete

Gracefully disconnect or remove the instance:
DELETE /instance/logout/:instanceName
# or
DELETE /instance/delete/:instanceName

Connection States

Baileys Connection States

public stateConnection: wa.StateConnection = { state: 'close' };

export interface StateConnection {
  state: 'connecting' | 'open' | 'close';
  statusReason?: number;
}
Instance is establishing connection to WhatsApp servers.
{
  "event": "connection.update",
  "instance": "customer-support",
  "state": "connecting"
}
What’s happening:
  • WebSocket connection opening
  • Authenticating session credentials
  • Syncing initial data
Typical duration: 5-30 seconds

Reconnection Strategies

Automatic Reconnection

Evolution API handles reconnections automatically for transient failures:
if (connection === 'close') {
  const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode;
  const shouldReconnect = !codesToNotReconnect.includes(statusCode);
  
  if (shouldReconnect) {
    await this.connectToWhatsapp(this.phoneNumber);
  } else {
    // Permanent disconnection - log out
    this.eventEmitter.emit('logout.instance', this.instance.name, 'inner');
    this.client?.ws?.close();
    this.client.end(new Error('Close connection'));
  }
}
Automatic reconnection includes exponential backoff to avoid overwhelming WhatsApp servers.

Manual Reconnection

Force reconnection of an existing instance:
POST /instance/connect/:instanceName
{
  "number": "5511999999999"
}
Backend implementation:
public async reloadConnection(): Promise<WASocket> {
  try {
    return await this.createClient(this.phoneNumber);
  } catch (error) {
    this.logger.error(error);
    throw new InternalServerErrorException(error?.toString());
  }
}

Session Persistence

Evolution API persists session data to enable seamless reconnections:

Storage Options

Store encrypted credentials in PostgreSQL or MySQL:
.env
DATABASE_SAVE_DATA_INSTANCE=true
DATABASE_PROVIDER=postgresql
DATABASE_CONNECTION_URI='postgresql://user:pass@host:5432/evolution'
Implementation:
if (db.SAVE_DATA.INSTANCE) {
  return await useMultiFileAuthStatePrisma(this.instance.id, this.cache);
}
Pros:
  • Persistent across restarts
  • Centralized management
  • Easy backup
Cons:
  • Database dependency
  • Slightly slower than Redis

Connection Monitoring

Webhook Events

Subscribe to connection events via webhooks:
.env
WEBHOOK_GLOBAL_ENABLED=true
WEBHOOK_GLOBAL_URL=https://your-server.com/webhook
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_QRCODE_UPDATED=true
Event payload:
{
  "event": "connection.update",
  "instance": "customer-support",
  "data": {
    "instance": "customer-support",
    "state": "open",
    "statusReason": 200,
    "wuid": "[email protected]",
    "profileName": "Customer Support",
    "profilePictureUrl": "https://pps.whatsapp.net/..."
  },
  "date_time": "2024-03-04T10:30:00.000Z",
  "sender": "evolution-api",
  "server_url": "https://evolution.example.com",
  "apikey": "instance-api-key"
}

API Polling

Query connection status programmatically:
GET /instance/connectionState/:instanceName
Response:
{
  "instance": {
    "instanceName": "customer-support",
    "state": "open"
  },
  "statusReason": 200
}

Health Checks

Implement health monitoring:
public get connectionStatus() {
  return this.stateConnection;
}

// Usage in monitoring
const status = instance.connectionStatus;
if (status.state !== 'open') {
  // Alert or reconnect
}

Multi-Instance Management

Manage multiple WhatsApp connections:
# List all instances
GET /instance/fetchInstances
[
  {
    "instanceName": "customer-support",
    "connectionStatus": "open",
    "ownerJid": "[email protected]"
  },
  {
    "instanceName": "sales-team",
    "connectionStatus": "connecting",
    "ownerJid": null
  }
]

Instance Isolation

Evolution API is multi-tenant. Always scope operations by instance:
// CORRECT - Instance-scoped query
const messages = await prismaRepository.message.findMany({
  where: { instanceId: instance.id }
});

// INCORRECT - Cross-instance leak
const messages = await prismaRepository.message.findMany();

Connection Best Practices

1

Monitor Connection Events

Subscribe to connection.update webhooks to track instance health:
app.post('/webhook', (req, res) => {
  const { event, data } = req.body;
  
  if (event === 'connection.update') {
    if (data.state === 'close') {
      // Handle disconnection
      console.log(`Instance ${data.instance} disconnected:`, data.statusReason);
    }
  }
  
  res.sendStatus(200);
});
2

Enable Session Persistence

Always enable session storage to prevent re-authentication:
.env
DATABASE_SAVE_DATA_INSTANCE=true
# or
CACHE_REDIS_SAVE_INSTANCES=true
3

Handle QR Code Expiration

Baileys QR codes expire after a limit:
.env
QRCODE_LIMIT=30  # Maximum regenerations
Monitor qrcode.updated events and alert users to scan promptly.
4

Implement Graceful Shutdown

Properly close connections on application shutdown:
process.on('SIGTERM', async () => {
  await instance.client?.logout('Shutting down');
  await instance.client?.ws?.close();
  process.exit(0);
});

Connection Limits

Baileys Limitations

  • Concurrent connections per number: 1 active connection
  • QR code timeout: ~45 seconds per code
  • Max QR regenerations: Configurable (default 30)
  • Reconnection delay: Automatic exponential backoff
Multiple simultaneous connections with the same WhatsApp number will cause disconnections.

Business API Limitations

  • No active connection required: Always available
  • Rate limits: Based on account tier
  • Webhook timeout: 5-second response required

Troubleshooting

Connection Keeps Closing

Check logs for disconnect reason:
GET /instance/connectionState/:instanceName
Common causes:
StatusReasonCauseSolution
401Logged out manuallyRe-authenticate with QR code
403Number bannedUse different number
428Connection timeoutCheck network/firewall
500WhatsApp server errorWait and retry

Session Not Persisting

Verify storage configuration:
// Check logs for auth state provider
this.logger.info('Using auth state provider: Prisma/Redis/Provider');
Ensure database or Redis is accessible:
# Test database connection
POST /instance/create
# Check logs for connection errors

Instance Not Found

Query instance existence:
GET /instance/fetchInstances?instanceName=customer-support
If missing, recreate:
POST /instance/create

Next Steps

Baileys Connection

Learn Baileys-specific connection details

Business API

Understand Business API connection flow

Webhooks

Configure connection event webhooks

Instance Management

Create and manage instances

Build docs developers (and LLMs) love