> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/EvolutionAPI/evolution-api/llms.txt
> Use this file to discover all available pages before exploring further.

# Connection Management

> Manage WhatsApp instance connections, monitor status, and handle reconnections

## Overview

Evolution API manages WhatsApp connections through instances. Each instance represents a separate WhatsApp connection with its own authentication, session, and message queue.

<Note>
  Connection behavior differs between providers: Baileys requires active connection management, while Business API connections are always active.
</Note>

## Connection Lifecycle

<Steps>
  <Step title="Create Instance">
    Initialize a new WhatsApp instance:

    ```bash theme={null}
    POST /instance/create
    ```

    ```json theme={null}
    {
      "instanceName": "customer-support",
      "token": "your-api-key",
      "qrcode": true
    }
    ```

    Response:

    ```json theme={null}
    {
      "instance": {
        "instanceName": "customer-support",
        "status": "created"
      },
      "hash": {
        "apikey": "generated-instance-token"
      }
    }
    ```
  </Step>

  <Step title="Connect to WhatsApp">
    For Baileys, authenticate via QR code or pairing code. For Business API, the connection is immediate.

    **Baileys Connection:**

    ```typescript theme={null}
    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:**

    ```typescript theme={null}
    public stateConnection: wa.StateConnection = { state: 'open' };
    // Business API is always connected once configured
    ```
  </Step>

  <Step title="Monitor Status">
    Track connection state through webhooks or API queries:

    ```bash theme={null}
    GET /instance/connectionState/:instanceName
    ```

    ```json theme={null}
    {
      "instance": {
        "instanceName": "customer-support",
        "state": "open"
      },
      "statusReason": 200
    }
    ```
  </Step>

  <Step title="Disconnect or Delete">
    Gracefully disconnect or remove the instance:

    ```bash theme={null}
    DELETE /instance/logout/:instanceName
    # or
    DELETE /instance/delete/:instanceName
    ```
  </Step>
</Steps>

## Connection States

### Baileys Connection States

```typescript theme={null}
public stateConnection: wa.StateConnection = { state: 'close' };

export interface StateConnection {
  state: 'connecting' | 'open' | 'close';
  statusReason?: number;
}
```

<Tabs>
  <Tab title="Connecting">
    Instance is establishing connection to WhatsApp servers.

    ```json theme={null}
    {
      "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
  </Tab>

  <Tab title="Open">
    Instance is connected and ready to send/receive messages.

    ```json theme={null}
    {
      "event": "connection.update",
      "instance": "customer-support",
      "state": "open",
      "statusReason": 200,
      "wuid": "5511999999999@s.whatsapp.net",
      "profileName": "Customer Support",
      "profilePictureUrl": "https://..."
    }
    ```

    **Instance capabilities:**

    * Send messages
    * Receive messages
    * Update profile
    * Manage groups
    * Access contacts

    Database record updated:

    ```typescript theme={null}
    await this.prismaRepository.instance.update({
      where: { id: this.instanceId },
      data: {
        ownerJid: this.instance.wuid,
        profileName: await this.getProfileName(),
        profilePicUrl: this.instance.profilePictureUrl,
        connectionStatus: 'open'
      }
    });
    ```
  </Tab>

  <Tab title="Close">
    Instance is disconnected from WhatsApp.

    ```json theme={null}
    {
      "event": "connection.update",
      "instance": "customer-support",
      "state": "close",
      "statusReason": 428
    }
    ```

    **Disconnect reasons (statusReason):**

    | Code | Reason             | Auto-reconnect |
    | ---- | ------------------ | -------------- |
    | 200  | Normal close       | No             |
    | 401  | Logged out         | No             |
    | 403  | Forbidden/banned   | No             |
    | 402  | Payment required   | No             |
    | 406  | Invalid session    | No             |
    | 408  | Connection timeout | Yes            |
    | 428  | Connection lost    | Yes            |
    | 500  | Server error       | Yes            |

    Reconnection logic:

    ```typescript theme={null}
    const codesToNotReconnect = [
      DisconnectReason.loggedOut,
      DisconnectReason.forbidden,
      402,
      406
    ];
    const shouldReconnect = !codesToNotReconnect.includes(statusCode);

    if (shouldReconnect) {
      await this.connectToWhatsapp(this.phoneNumber);
    }
    ```
  </Tab>
</Tabs>

## Reconnection Strategies

### Automatic Reconnection

Evolution API handles reconnections automatically for transient failures:

```typescript theme={null}
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'));
  }
}
```

<Tip>
  Automatic reconnection includes exponential backoff to avoid overwhelming WhatsApp servers.
</Tip>

### Manual Reconnection

Force reconnection of an existing instance:

```bash theme={null}
POST /instance/connect/:instanceName
```

```json theme={null}
{
  "number": "5511999999999"
}
```

Backend implementation:

```typescript theme={null}
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

<Tabs>
  <Tab title="Database (Prisma)">
    Store encrypted credentials in PostgreSQL or MySQL:

    ```bash .env theme={null}
    DATABASE_SAVE_DATA_INSTANCE=true
    DATABASE_PROVIDER=postgresql
    DATABASE_CONNECTION_URI='postgresql://user:pass@host:5432/evolution'
    ```

    Implementation:

    ```typescript theme={null}
    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
  </Tab>

  <Tab title="Redis Cache">
    Store sessions in Redis for faster access:

    ```bash .env theme={null}
    CACHE_REDIS_ENABLED=true
    CACHE_REDIS_URI=redis://localhost:6379/6
    CACHE_REDIS_SAVE_INSTANCES=true
    ```

    Implementation:

    ```typescript theme={null}
    if (cache?.REDIS.ENABLED && cache?.REDIS.SAVE_INSTANCES) {
      return await useMultiFileAuthStateRedisDb(this.instance.id, this.cache);
    }
    ```

    **Pros:**

    * Fastest reconnection
    * Reduces database load
    * Automatic expiration

    **Cons:**

    * Volatile (data loss on Redis restart)
    * Requires Redis infrastructure
  </Tab>

  <Tab title="File Provider">
    Store sessions in custom storage (S3, MinIO, etc.):

    ```bash .env theme={null}
    PROVIDER_ENABLED=true
    S3_ENABLED=true
    S3_BUCKET=evolution-sessions
    ```

    Implementation:

    ```typescript theme={null}
    if (provider?.ENABLED) {
      return await this.authStateProvider.authStateProvider(this.instance.id);
    }
    ```

    **Pros:**

    * Scalable storage
    * Independent infrastructure
    * Cloud-native

    **Cons:**

    * Network latency
    * Additional configuration
  </Tab>
</Tabs>

## Connection Monitoring

### Webhook Events

Subscribe to connection events via webhooks:

```bash .env theme={null}
WEBHOOK_GLOBAL_ENABLED=true
WEBHOOK_GLOBAL_URL=https://your-server.com/webhook
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_QRCODE_UPDATED=true
```

Event payload:

```json theme={null}
{
  "event": "connection.update",
  "instance": "customer-support",
  "data": {
    "instance": "customer-support",
    "state": "open",
    "statusReason": 200,
    "wuid": "5511999999999@s.whatsapp.net",
    "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:

```bash theme={null}
GET /instance/connectionState/:instanceName
```

Response:

```json theme={null}
{
  "instance": {
    "instanceName": "customer-support",
    "state": "open"
  },
  "statusReason": 200
}
```

### Health Checks

Implement health monitoring:

```typescript theme={null}
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:

```bash theme={null}
# List all instances
GET /instance/fetchInstances
```

```json theme={null}
[
  {
    "instanceName": "customer-support",
    "connectionStatus": "open",
    "ownerJid": "5511999999999@s.whatsapp.net"
  },
  {
    "instanceName": "sales-team",
    "connectionStatus": "connecting",
    "ownerJid": null
  }
]
```

### Instance Isolation

<Warning>
  Evolution API is multi-tenant. Always scope operations by instance:
</Warning>

```typescript theme={null}
// 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

<Steps>
  <Step title="Monitor Connection Events">
    Subscribe to `connection.update` webhooks to track instance health:

    ```javascript theme={null}
    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);
    });
    ```
  </Step>

  <Step title="Enable Session Persistence">
    Always enable session storage to prevent re-authentication:

    ```bash .env theme={null}
    DATABASE_SAVE_DATA_INSTANCE=true
    # or
    CACHE_REDIS_SAVE_INSTANCES=true
    ```
  </Step>

  <Step title="Handle QR Code Expiration">
    Baileys QR codes expire after a limit:

    ```bash .env theme={null}
    QRCODE_LIMIT=30  # Maximum regenerations
    ```

    Monitor `qrcode.updated` events and alert users to scan promptly.
  </Step>

  <Step title="Implement Graceful Shutdown">
    Properly close connections on application shutdown:

    ```typescript theme={null}
    process.on('SIGTERM', async () => {
      await instance.client?.logout('Shutting down');
      await instance.client?.ws?.close();
      process.exit(0);
    });
    ```
  </Step>
</Steps>

## 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

<Warning>
  Multiple simultaneous connections with the same WhatsApp number will cause disconnections.
</Warning>

### 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:**

```bash theme={null}
GET /instance/connectionState/:instanceName
```

Common causes:

| StatusReason | Cause                 | Solution                     |
| ------------ | --------------------- | ---------------------------- |
| 401          | Logged out manually   | Re-authenticate with QR code |
| 403          | Number banned         | Use different number         |
| 428          | Connection timeout    | Check network/firewall       |
| 500          | WhatsApp server error | Wait and retry               |

### Session Not Persisting

Verify storage configuration:

```typescript theme={null}
// Check logs for auth state provider
this.logger.info('Using auth state provider: Prisma/Redis/Provider');
```

Ensure database or Redis is accessible:

```bash theme={null}
# Test database connection
POST /instance/create
# Check logs for connection errors
```

### Instance Not Found

Query instance existence:

```bash theme={null}
GET /instance/fetchInstances?instanceName=customer-support
```

If missing, recreate:

```bash theme={null}
POST /instance/create
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Baileys Connection" icon="qrcode" href="/whatsapp/baileys">
    Learn Baileys-specific connection details
  </Card>

  <Card title="Business API" icon="building" href="/whatsapp/business-api">
    Understand Business API connection flow
  </Card>

  <Card title="Webhooks" icon="webhook" href="/events/webhooks">
    Configure connection event webhooks
  </Card>

  <Card title="Instance Management" icon="server" href="/api/instance/create">
    Create and manage instances
  </Card>
</CardGroup>
