Claude Code Plugins

Community-maintained marketplace

Feedback

Comprehensive skill for Evolution API - open-source WhatsApp integration platform with multi-service chatbot and automation support

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name evolution-api
description Comprehensive skill for Evolution API - open-source WhatsApp integration platform with multi-service chatbot and automation support
version 1.0.0

Evolution API Skill

Expert assistance for building WhatsApp integrations and multi-channel messaging automation using Evolution API - an open-source platform for WhatsApp, chatbots, and business communication.

When to Use This Skill

This skill should be used when:

  • Building WhatsApp integrations and chatbots
  • Creating automated messaging systems
  • Integrating WhatsApp with business applications
  • Setting up multi-channel customer service platforms
  • Implementing chatbot flows with Typebot, Chatwoot, or Dify
  • Connecting WhatsApp to CRM systems
  • Building AI-powered conversational applications
  • Setting up webhook-based message handling
  • Implementing event-driven messaging architectures
  • Managing WhatsApp Business API connections
  • Integrating with OpenAI for intelligent responses
  • Setting up message queuing with RabbitMQ, Kafka, or SQS
  • Storing media files in S3 or MinIO
  • Questions about Evolution API configuration and deployment
  • Troubleshooting WhatsApp connection issues

Overview

What is Evolution API?

Evolution API is an open-source WhatsApp integration platform that:

  • Provides RESTful API for WhatsApp messaging
  • Supports both Baileys (free) and Official WhatsApp Business API
  • Integrates with multiple chatbot and automation platforms
  • Offers comprehensive webhook and event system
  • Enables business messaging automation
  • Completely free and self-hosted

Evolution from CodeChat:

"Originally built as a WhatsApp control API using the Baileys library based on CodeChat, the platform has evolved significantly."

Key Features

Messaging Capabilities:

  • Send and receive WhatsApp messages
  • Media support (images, videos, audio, documents)
  • Group management and operations
  • Contact management
  • Message history and search
  • Read receipts and status updates

Integration Ecosystem:

  • Typebot: Visual chatbot builder
  • Chatwoot: Customer service platform
  • Dify: AI agent management
  • OpenAI: AI-powered responses and audio transcription
  • Flowise: Low-code AI workflow builder
  • N8N: Workflow automation

Technical Features:

  • RESTful API with comprehensive endpoints
  • Webhook system for real-time events
  • WebSocket support for live updates
  • Message queue integration (RabbitMQ, Kafka, SQS)
  • Database persistence (PostgreSQL, MySQL)
  • Redis caching for performance
  • S3/MinIO for media storage
  • Docker deployment ready

Installation

Prerequisites

# Node.js 18+ or Docker
node --version  # v18.0.0 or higher

# Database (optional but recommended)
# PostgreSQL 12+ or MySQL 8+

# Redis (optional, for caching)
# Redis 6+

Installation Methods

Option 1: Docker (Recommended)

# Clone the repository
git clone https://github.com/EvolutionAPI/evolution-api.git
cd evolution-api

# Create environment file
cp .env.example .env

# Edit environment variables
nano .env

# Start with Docker Compose
docker-compose up -d

# Check logs
docker-compose logs -f evolution-api

Docker Compose Example:

version: '3.8'

services:
  evolution-api:
    image: atendai/evolution-api:latest
    container_name: evolution-api
    ports:
      - "8080:8080"
    environment:
      - SERVER_URL=https://your-domain.com
      - DATABASE_ENABLED=true
      - DATABASE_PROVIDER=postgresql
      - DATABASE_CONNECTION_URI=postgresql://user:pass@postgres:5432/evolution
      - AUTHENTICATION_API_KEY=your-secret-key-here
    volumes:
      - evolution_instances:/evolution/instances
    restart: unless-stopped

  postgres:
    image: postgres:15
    container_name: postgres
    environment:
      - POSTGRES_USER=evolution
      - POSTGRES_PASSWORD=your-db-password
      - POSTGRES_DB=evolution
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped

volumes:
  evolution_instances:
  postgres_data:
  redis_data:

Option 2: NVM (Node Version Manager)

# Install NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# Reload shell
source ~/.bashrc

# Install Node.js 18+
nvm install 18
nvm use 18

# Clone repository
git clone https://github.com/EvolutionAPI/evolution-api.git
cd evolution-api

# Install dependencies
npm install

# Copy environment file
cp .env.example .env

# Edit configuration
nano .env

# Build
npm run build

# Start production
npm run start:prod

# Or development mode
npm run start:dev

Option 3: PM2 (Process Manager)

# After NVM installation above

# Install PM2 globally
npm install -g pm2

# Start with PM2
pm2 start dist/src/main.js --name evolution-api

# Save PM2 configuration
pm2 save

# Setup auto-restart on boot
pm2 startup

Configuration

Essential Environment Variables

# Server Configuration
SERVER_TYPE=http                    # or https
SERVER_PORT=8080
SERVER_URL=https://your-domain.com  # For webhooks

# Authentication
AUTHENTICATION_API_KEY=your-secret-api-key-here
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true

# Database (Recommended for production)
DATABASE_ENABLED=true
DATABASE_PROVIDER=postgresql        # or mysql
DATABASE_CONNECTION_URI=postgresql://user:pass@localhost:5432/evolution?schema=public
DATABASE_CONNECTION_CLIENT_NAME=evolution_instance

# Data Persistence
DATABASE_SAVE_DATA_INSTANCE=true
DATABASE_SAVE_DATA_NEW_MESSAGE=true
DATABASE_SAVE_MESSAGE_UPDATE=true
DATABASE_SAVE_DATA_CONTACTS=true
DATABASE_SAVE_DATA_CHATS=true

# Redis Cache (Optional but recommended)
CACHE_REDIS_ENABLED=true
CACHE_REDIS_URI=redis://localhost:6379/6
CACHE_REDIS_PREFIX_KEY=evolution

# CORS
CORS_ORIGIN=*
CORS_METHODS=GET,POST,PUT,DELETE
CORS_CREDENTIALS=true

# Logging
LOG_LEVEL=INFO                      # ERROR, WARN, DEBUG, INFO, LOG, VERBOSE
LOG_COLOR=true
LOG_BAILEYS=error                   # fatal, error, warn, info, debug, trace

# Instance Management
DEL_INSTANCE=false                  # Auto-delete after X minutes (false = never)

# Language
LANGUAGE=en                         # or pt, es, etc.

WhatsApp Configuration

# Session Configuration
CONFIG_SESSION_PHONE_CLIENT=Evolution API
CONFIG_SESSION_PHONE_NAME=Chrome

# QR Code Settings
QRCODE_LIMIT=30                     # Seconds before regeneration
QRCODE_COLOR=#175197               # QR code color

# WhatsApp Business API (Official)
WA_BUSINESS_TOKEN_WEBHOOK=evolution
WA_BUSINESS_URL=https://graph.facebook.com
WA_BUSINESS_VERSION=v20.0
WA_BUSINESS_LANGUAGE=en_US

Webhook Configuration

# Global Webhook
WEBHOOK_GLOBAL_ENABLED=true
WEBHOOK_GLOBAL_URL=https://your-webhook-endpoint.com/webhook
WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=true

# Event-specific webhooks
WEBHOOK_EVENTS_APPLICATION_STARTUP=true
WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=true
WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true
WEBHOOK_EVENTS_CONTACTS_SET=true
WEBHOOK_EVENTS_CONTACTS_UPSERT=true
WEBHOOK_EVENTS_CONTACTS_UPDATE=true
WEBHOOK_EVENTS_PRESENCE_UPDATE=true
WEBHOOK_EVENTS_CHATS_SET=true
WEBHOOK_EVENTS_CHATS_UPSERT=true
WEBHOOK_EVENTS_CHATS_UPDATE=true
WEBHOOK_EVENTS_CHATS_DELETE=true
WEBHOOK_EVENTS_GROUPS_UPSERT=true
WEBHOOK_EVENTS_GROUPS_UPDATE=true
WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_CALL=true
WEBHOOK_EVENTS_TYPEBOT_START=true
WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=true
WEBHOOK_EVENTS_ERRORS=true
WEBHOOK_EVENTS_ERRORS_WEBHOOK=true

Integration Configurations

Typebot:

TYPEBOT_API_VERSION=latest          # or specific version

Chatwoot:

CHATWOOT_ENABLED=true
CHATWOOT_MESSAGE_READ=true
CHATWOOT_MESSAGE_DELETE=true
CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://...
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true

OpenAI:

OPENAI_ENABLED=true

Dify:

DIFY_ENABLED=true

RabbitMQ:

RABBITMQ_ENABLED=true
RABBITMQ_URI=amqp://user:pass@localhost:5672
RABBITMQ_EXCHANGE_NAME=evolution_exchange
RABBITMQ_GLOBAL_ENABLED=true

AWS SQS:

SQS_ENABLED=true
SQS_ACCESS_KEY_ID=your-access-key
SQS_SECRET_ACCESS_KEY=your-secret-key
SQS_ACCOUNT_ID=123456789
SQS_REGION=us-east-1

S3/MinIO Storage:

S3_ENABLED=true
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
S3_BUCKET=evolution
S3_ENDPOINT=s3.amazonaws.com        # or minio endpoint
S3_PORT=443
S3_USE_SSL=true

WebSocket:

WEBSOCKET_ENABLED=true
WEBSOCKET_GLOBAL_EVENTS=false

Quick Start

1. Create Instance

# Using cURL
curl -X POST https://your-domain.com/instance/create \
  -H "apikey: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceName": "my-whatsapp-bot",
    "qrcode": true,
    "integration": "WHATSAPP-BAILEYS"
  }'

# Response includes QR code
{
  "instance": {
    "instanceName": "my-whatsapp-bot",
    "status": "created"
  },
  "qrcode": {
    "code": "data:image/png;base64,...",
    "base64": "..."
  }
}

2. Connect WhatsApp

Scan the QR code with WhatsApp on your phone:

  1. Open WhatsApp
  2. Go to Settings > Linked Devices
  3. Click "Link a Device"
  4. Scan the QR code from the API response

3. Check Connection Status

curl -X GET https://your-domain.com/instance/connectionState/my-whatsapp-bot \
  -H "apikey: your-api-key"

# Response
{
  "instance": {
    "instanceName": "my-whatsapp-bot",
    "state": "open"
  }
}

4. Send Message

curl -X POST https://your-domain.com/message/sendText/my-whatsapp-bot \
  -H "apikey: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "number": "5511999999999",
    "text": "Hello from Evolution API!"
  }'

API Endpoints

Instance Management

# Create instance
POST /instance/create
{
  "instanceName": "bot-name",
  "qrcode": true,
  "integration": "WHATSAPP-BAILEYS"  # or WHATSAPP-BUSINESS
}

# List instances
GET /instance/fetchInstances

# Get instance info
GET /instance/connectionState/{instanceName}

# Restart instance
PUT /instance/restart/{instanceName}

# Logout instance
DELETE /instance/logout/{instanceName}

# Delete instance
DELETE /instance/delete/{instanceName}

Messaging

Text Messages:

POST /message/sendText/{instanceName}
{
  "number": "5511999999999",
  "text": "Your message here"
}

Media Messages:

# Image
POST /message/sendMedia/{instanceName}
{
  "number": "5511999999999",
  "mediatype": "image",
  "media": "https://example.com/image.jpg",  # or base64
  "caption": "Image caption"
}

# Video
POST /message/sendMedia/{instanceName}
{
  "number": "5511999999999",
  "mediatype": "video",
  "media": "https://example.com/video.mp4",
  "caption": "Video caption"
}

# Audio
POST /message/sendWhatsAppAudio/{instanceName}
{
  "number": "5511999999999",
  "audio": "https://example.com/audio.mp3"  # or base64
}

# Document
POST /message/sendMedia/{instanceName}
{
  "number": "5511999999999",
  "mediatype": "document",
  "media": "https://example.com/file.pdf",
  "fileName": "document.pdf"
}

Advanced Messages:

# Location
POST /message/sendLocation/{instanceName}
{
  "number": "5511999999999",
  "latitude": "-23.550520",
  "longitude": "-46.633308",
  "name": "Location Name",
  "address": "Address details"
}

# Contact
POST /message/sendContact/{instanceName}
{
  "number": "5511999999999",
  "contact": [{
    "fullName": "John Doe",
    "wuid": "5511888888888",
    "phoneNumber": "+55 11 98888-8888"
  }]
}

# List Message (Interactive)
POST /message/sendList/{instanceName}
{
  "number": "5511999999999",
  "title": "Choose an option",
  "description": "Select one option below",
  "buttonText": "Options",
  "footerText": "Footer text",
  "sections": [{
    "title": "Section 1",
    "rows": [{
      "title": "Option 1",
      "description": "Description 1",
      "rowId": "opt1"
    }]
  }]
}

# Button Message
POST /message/sendButtons/{instanceName}
{
  "number": "5511999999999",
  "title": "Button Message",
  "description": "Choose an action",
  "buttons": [{
    "type": "replyButton",
    "displayText": "Button 1",
    "id": "btn1"
  }],
  "footerText": "Footer"
}

Groups

# Create group
POST /group/create/{instanceName}
{
  "subject": "Group Name",
  "participants": ["5511999999999", "5511888888888"]
}

# Update group info
PUT /group/updateGroupPicture/{instanceName}
{
  "groupJid": "groupid@g.us",
  "image": "base64-image-data"
}

# Add participants
POST /group/updateParticipant/{instanceName}
{
  "groupJid": "groupid@g.us",
  "action": "add",  # or remove, promote, demote
  "participants": ["5511999999999"]
}

# Leave group
DELETE /group/leaveGroup/{instanceName}
{
  "groupJid": "groupid@g.us"
}

Contacts & Profile

# Get profile picture
GET /chat/profilePic/{instanceName}?number=5511999999999

# Get contacts
GET /chat/findContacts/{instanceName}?id=5511999999999

# Update profile name
PUT /chat/updateProfileName/{instanceName}
{
  "name": "My Bot Name"
}

# Update profile status
PUT /chat/updateProfileStatus/{instanceName}
{
  "status": "Available 24/7"
}

# Update profile picture
PUT /chat/updateProfilePicture/{instanceName}
{
  "picture": "base64-image-data"
}

Webhooks

# Set instance webhook
POST /webhook/set/{instanceName}
{
  "url": "https://your-webhook.com/endpoint",
  "webhook_by_events": true,
  "webhook_base64": false,
  "events": [
    "QRCODE_UPDATED",
    "MESSAGES_UPSERT",
    "MESSAGES_UPDATE",
    "SEND_MESSAGE",
    "CONNECTION_UPDATE"
  ]
}

# Get webhook info
GET /webhook/find/{instanceName}

Integration Examples

Typebot Integration

# Set Typebot on instance
POST /typebot/set/{instanceName}
{
  "enabled": true,
  "url": "https://typebot.io",
  "typebot": "typebot-flow-id",
  "expire": 20,           # Minutes of inactivity
  "keywordFinish": "exit",
  "delayMessage": 1000,
  "unknownMessage": "I didn't understand",
  "listeningFromMe": false
}

# Start Typebot session
POST /typebot/start/{instanceName}
{
  "url": "https://typebot.io",
  "typebot": "flow-id",
  "remoteJid": "5511999999999@s.whatsapp.net",
  "startSession": true,
  "variables": [{
    "name": "userName",
    "value": "John"
  }]
}

# Change Typebot status
POST /typebot/changeStatus/{instanceName}
{
  "remoteJid": "5511999999999@s.whatsapp.net",
  "status": "paused"  # or closed
}

Chatwoot Integration

# Enable Chatwoot
POST /chatwoot/set/{instanceName}
{
  "enabled": true,
  "accountId": "123",
  "token": "chatwoot-api-token",
  "url": "https://app.chatwoot.com",
  "signMsg": true,
  "reopenConversation": true,
  "conversationPending": false
}

OpenAI Integration

# Set OpenAI
POST /openai/set/{instanceName}
{
  "enabled": true,
  "apiKey": "sk-...",
  "model": "gpt-4o",
  "maxTokens": 2000,
  "temperature": 0.7,
  "systemMessages": [{
    "role": "system",
    "content": "You are a helpful assistant."
  }],
  "assistantMessages": [{
    "role": "assistant",
    "content": "How can I help you?"
  }]
}

Dify Integration

# Set Dify
POST /dify/set/{instanceName}
{
  "enabled": true,
  "apiUrl": "https://api.dify.ai/v1",
  "apiKey": "app-...",
  "botType": "chatbot",  # or agent, workflow
  "expire": 20,
  "keywordFinish": "exit"
}

Webhook Handling

Webhook Structure

// Example webhook payload
{
  "event": "messages.upsert",
  "instance": "my-whatsapp-bot",
  "data": {
    "key": {
      "remoteJid": "5511999999999@s.whatsapp.net",
      "fromMe": false,
      "id": "BAE5F4...",
      "participant": null
    },
    "pushName": "John Doe",
    "message": {
      "conversation": "Hello, how are you?"
    },
    "messageType": "conversation",
    "messageTimestamp": 1234567890,
    "instanceId": "instance-uuid",
    "source": "android"
  },
  "destination": "https://your-webhook.com/endpoint",
  "date_time": "2024-01-01T12:00:00.000Z",
  "server_url": "https://your-evolution-api.com",
  "apikey": "your-api-key"
}

Node.js Webhook Handler

const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook', async (req, res) => {
  const { event, instance, data } = req.body;

  console.log(`Received event: ${event} from instance: ${instance}`);

  // Handle different events
  switch (event) {
    case 'messages.upsert':
      // New message received
      const message = data.message?.conversation ||
                     data.message?.extendedTextMessage?.text || '';
      const from = data.key.remoteJid;
      const fromMe = data.key.fromMe;

      if (!fromMe && message) {
        console.log(`Message from ${from}: ${message}`);

        // Process message and send response
        await sendResponse(instance, from, message);
      }
      break;

    case 'connection.update':
      // Connection status changed
      console.log('Connection status:', data);
      break;

    case 'qrcode.updated':
      // New QR code generated
      console.log('QR Code updated:', data.qrcode);
      break;

    default:
      console.log('Unhandled event:', event);
  }

  // Always respond 200 OK
  res.sendStatus(200);
});

async function sendResponse(instance, to, originalMessage) {
  const response = await fetch(`https://your-api.com/message/sendText/${instance}`, {
    method: 'POST',
    headers: {
      'apikey': 'your-api-key',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      number: to.replace('@s.whatsapp.net', ''),
      text: `You said: ${originalMessage}`
    })
  });

  return response.json();
}

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

Python Webhook Handler

from flask import Flask, request
import requests

app = Flask(__name__)

API_URL = "https://your-evolution-api.com"
API_KEY = "your-api-key"

@app.route('/webhook', methods=['POST'])
def webhook():
    data = request.json
    event = data.get('event')
    instance = data.get('instance')
    event_data = data.get('data')

    print(f"Received event: {event} from instance: {instance}")

    if event == 'messages.upsert':
        handle_message(instance, event_data)
    elif event == 'connection.update':
        handle_connection(event_data)
    elif event == 'qrcode.updated':
        handle_qrcode(event_data)

    return '', 200

def handle_message(instance, data):
    from_me = data['key'].get('fromMe', False)

    if from_me:
        return

    message = (data.get('message', {}).get('conversation') or
              data.get('message', {}).get('extendedTextMessage', {}).get('text') or '')

    remote_jid = data['key']['remoteJid']
    number = remote_jid.replace('@s.whatsapp.net', '')

    print(f"Message from {number}: {message}")

    # Send response
    send_message(instance, number, f"You said: {message}")

def send_message(instance, number, text):
    url = f"{API_URL}/message/sendText/{instance}"
    headers = {
        'apikey': API_KEY,
        'Content-Type': 'application/json'
    }
    payload = {
        'number': number,
        'text': text
    }

    response = requests.post(url, json=payload, headers=headers)
    return response.json()

def handle_connection(data):
    print(f"Connection update: {data}")

def handle_qrcode(data):
    print(f"QR Code updated")

if __name__ == '__main__':
    app.run(port=3000)

Advanced Use Cases

1. AI-Powered Customer Service Bot

const OpenAI = require('openai');
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

async function handleCustomerMessage(instance, from, message) {
  // Get conversation history from database
  const history = await getConversationHistory(from);

  // Get AI response
  const completion = await openai.chat.completions.create({
    model: "gpt-4o",
    messages: [
      { role: "system", content: "You are a helpful customer service agent." },
      ...history,
      { role: "user", content: message }
    ]
  });

  const aiResponse = completion.choices[0].message.content;

  // Save to history
  await saveToHistory(from, message, aiResponse);

  // Send response
  await sendMessage(instance, from, aiResponse);
}

2. Group Management Bot

async function handleGroupCommand(instance, groupJid, command, sender) {
  const isAdmin = await checkIfAdmin(instance, groupJid, sender);

  if (!isAdmin) {
    await sendMessage(instance, groupJid, "Only admins can use this command");
    return;
  }

  switch (command) {
    case '/welcome':
      await setWelcomeMessage(groupJid);
      break;
    case '/rules':
      await sendGroupRules(instance, groupJid);
      break;
    case '/ban':
      const userToRemove = extractUserFromCommand(command);
      await removeParticipant(instance, groupJid, userToRemove);
      break;
  }
}

3. Broadcast System

async function sendBroadcast(instance, recipients, message) {
  const results = [];

  for (const recipient of recipients) {
    try {
      await sendMessage(instance, recipient, message);
      results.push({ recipient, status: 'sent' });

      // Delay to avoid rate limiting
      await delay(1000);
    } catch (error) {
      results.push({ recipient, status: 'failed', error: error.message });
    }
  }

  return results;
}

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

4. Media Downloader Bot

async function handleMediaMessage(instance, data) {
  const messageType = data.messageType;

  if (['imageMessage', 'videoMessage', 'documentMessage'].includes(messageType)) {
    // Download media
    const media = data.message[messageType];
    const buffer = await downloadMedia(instance, data.key.id);

    // Upload to S3
    const s3Url = await uploadToS3(buffer, media.mimetype);

    // Save to database
    await saveMediaReference({
      messageId: data.key.id,
      type: messageType,
      url: s3Url,
      from: data.key.remoteJid,
      timestamp: data.messageTimestamp
    });
  }
}

Production Best Practices

1. Security

# Use strong API key
AUTHENTICATION_API_KEY=$(openssl rand -hex 32)

# Enable HTTPS
SERVER_TYPE=https

# Restrict CORS
CORS_ORIGIN=https://your-frontend.com
CORS_CREDENTIALS=true

# Use environment-specific configs
# .env.production, .env.staging, .env.development

2. High Availability

# docker-compose.yml with replicas
services:
  evolution-api:
    image: atendai/evolution-api:latest
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
        max_attempts: 3
    environment:
      - DATABASE_ENABLED=true
      - CACHE_REDIS_ENABLED=true

  # Load balancer
  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - evolution-api

3. Monitoring

# Enable detailed logging
LOG_LEVEL=DEBUG
LOG_COLOR=true
LOG_BAILEYS=info

# Use external monitoring
# - Prometheus for metrics
# - Grafana for dashboards
# - Sentry for error tracking

# Health check endpoint
curl https://your-api.com/health

4. Backup Strategy

# Database backups
pg_dump -h localhost -U evolution evolution > backup_$(date +%Y%m%d).sql

# Instance data backup
tar -czf instances_backup_$(date +%Y%m%d).tar.gz /evolution/instances/

# Automated backups with cron
0 2 * * * /scripts/backup.sh

5. Rate Limiting

// Implement rate limiting in webhook handler
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: 'Too many requests, please try again later.'
});

app.use('/webhook', limiter);

Troubleshooting

Common Issues

QR Code Not Generating

# Check instance status
curl -X GET https://your-api.com/instance/connectionState/instance-name \
  -H "apikey: your-api-key"

# Restart instance
curl -X PUT https://your-api.com/instance/restart/instance-name \
  -H "apikey: your-api-key"

# Check logs
docker-compose logs -f evolution-api

Messages Not Sending

# Verify connection
GET /instance/connectionState/{instanceName}

# Check if number is valid
# Format: Country code + number (no +, no spaces)
# Example: 5511999999999

# Verify API key
curl -X GET https://your-api.com/instance/fetchInstances \
  -H "apikey: your-api-key"

Webhook Not Receiving Events

# Verify webhook configuration
GET /webhook/find/{instanceName}

# Test webhook endpoint
curl -X POST https://your-webhook.com/endpoint \
  -H "Content-Type: application/json" \
  -d '{"test": "data"}'

# Check webhook URL is publicly accessible
# Use ngrok for local development:
ngrok http 3000

Database Connection Errors

# Test database connection
psql "postgresql://user:pass@localhost:5432/evolution"

# Check environment variables
echo $DATABASE_CONNECTION_URI

# Verify database exists
psql -l | grep evolution

# Run migrations if needed
npm run migration:run

Instance Disconnects Frequently

# Enable keep-alive
# Check mobile connection
# Verify phone battery saver is off
# Check WhatsApp version is up to date

# Increase session timeout
CONFIG_SESSION_PHONE_CLIENT=Evolution API
QRCODE_LIMIT=60  # Increase timeout

Performance Optimization

1. Enable Caching

# Redis cache
CACHE_REDIS_ENABLED=true
CACHE_REDIS_URI=redis://localhost:6379/6
CACHE_REDIS_SAVE_INSTANCES=true

2. Database Optimization

# Index frequently queried fields
CREATE INDEX idx_messages_instance ON messages(instanceId);
CREATE INDEX idx_messages_jid ON messages(remoteJid);
CREATE INDEX idx_messages_timestamp ON messages(messageTimestamp);

# Partition large tables
# Clean old messages periodically
DELETE FROM messages WHERE messageTimestamp < NOW() - INTERVAL '90 days';

3. Media Storage

# Use S3 for media files
S3_ENABLED=true
S3_BUCKET=evolution-media

# Don't save media in database
DATABASE_SAVE_DATA_NEW_MESSAGE=false

4. Message Queue

# Use RabbitMQ for high volume
RABBITMQ_ENABLED=true
RABBITMQ_URI=amqp://localhost:5672

# Or SQS for AWS deployments
SQS_ENABLED=true

Migration Guide

From WhatsApp Web.js

// WhatsApp Web.js
const { Client } = require('whatsapp-web.js');
const client = new Client();

client.on('message', msg => {
  if (msg.body === 'ping') {
    msg.reply('pong');
  }
});

client.initialize();

// Evolution API equivalent
app.post('/webhook', (req, res) => {
  const { event, data } = req.body;

  if (event === 'messages.upsert') {
    const message = data.message?.conversation;

    if (message === 'ping') {
      sendMessage(data.instance, data.key.remoteJid, 'pong');
    }
  }

  res.sendStatus(200);
});

From Baileys Directly

Evolution API is built on Baileys, so migration is straightforward. Instead of managing Baileys directly, use Evolution API's REST endpoints.

API Reference Summary

Base URL Structure

https://your-domain.com/{endpoint}/{instanceName}

Authentication

# All requests require API key header
apikey: your-api-key

Main Endpoint Categories

  • /instance/* - Instance management
  • /message/* - Send messages
  • /chat/* - Chat and contact operations
  • /group/* - Group management
  • /webhook/* - Webhook configuration
  • /typebot/* - Typebot integration
  • /chatwoot/* - Chatwoot integration
  • /openai/* - OpenAI integration
  • /dify/* - Dify integration

Resources

Official Links

Community

Integration Partners

License

Evolution API is licensed under Apache License 2.0 with specific requirements regarding branding notifications in implementations.


Note: This skill provides comprehensive guidance for building WhatsApp integrations with Evolution API. Always ensure compliance with WhatsApp's Terms of Service and local regulations when deploying messaging solutions.