Learn-skills.dev evolution-api
Comprehensive skill for Evolution API - open-source WhatsApp integration platform with multi-service chatbot and automation support
git clone https://github.com/NeverSight/learn-skills.dev
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/aeonbridge/ab-anthropic-claude-skills/evolution-api" ~/.claude/skills/neversight-learn-skills-dev-evolution-api && rm -rf "$T"
data/skills-md/aeonbridge/ab-anthropic-claude-skills/evolution-api/SKILL.mdEvolution 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:
- Open WhatsApp
- Go to Settings > Linked Devices
- Click "Link a Device"
- 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 management/instance/*
- Send messages/message/*
- Chat and contact operations/chat/*
- Group management/group/*
- Webhook configuration/webhook/*
- Typebot integration/typebot/*
- Chatwoot integration/chatwoot/*
- OpenAI integration/openai/*
- Dify integration/dify/*
Resources
Official Links
- Documentation: https://doc.evolution-api.com/
- GitHub: https://github.com/EvolutionAPI/evolution-api
- Website: https://evolution-api.com
Community
- GitHub Discussions: https://github.com/EvolutionAPI/evolution-api/discussions
- Issues: https://github.com/EvolutionAPI/evolution-api/issues
Integration Partners
- Typebot: https://typebot.io
- Chatwoot: https://chatwoot.com
- Dify: https://dify.ai
- N8N: https://n8n.io
- Flowise: https://flowiseai.com
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.