Use when deploying, connecting, troubleshooting, or managing Evolution API WhatsApp instances on ECS Fargate. Triggers on QR code generation, WhatsApp session conflicts, webhook JWT errors, instance lifecycle operations, or environment isolation for WhatsApp services.
Operational guide for Evolution API v2.3.7 on ECS Fargate with WhatsApp Baileys integration. Covers instance lifecycle, session management, environment isolation, and troubleshooting.
Core constraint: WhatsApp allows only ONE active Baileys connection per phone number. Two instances with the same number = continuous conflict/replaced loop every ~2 seconds.
| Operation | Endpoint | Method |
|---|---|---|
| List instances | /instance/fetchInstances | GET |
| Create instance | /instance/create | POST |
| Connect (QR) | /instance/connect/{name} | GET |
| Connection state | /instance/connectionState/{name} | GET |
| Logout | /instance/logout/{name} |
| DELETE |
| Delete instance | /instance/delete/{name} | DELETE |
| Set webhook | /webhook/set/{name} | POST |
All endpoints require header: apikey: $AUTHENTICATION_API_KEY
Container is BusyBox-based: no curl/wget. Use node -e for everything.
# Template for all ECS exec commands
aws ecs execute-command \
--cluster "$CLUSTER" \
--task "$TASK_ID" \
--container EvolutionService \
--interactive \
--command 'node -e "...script..."'
Get task ID:
TASK_ID=$(aws ecs list-tasks --cluster "$CLUSTER" --service-name EvolutionService \
--query 'taskArns[0]' --output text | awk -F/ '{print $NF}')
ECS exec output gotchas:
Starting session... and Cannot perform start session: EOF noisegrep or tail to extract useful data// Body for POST /instance/create
{
instanceName: 'alinhou-production',
integration: 'WHATSAPP-BAILEYS',
qrcode: true,
rejectCall: false,
groupsIgnore: true,
alwaysOnline: false,
readMessages: false,
readStatus: false,
syncFullHistory: false,
webhook: {
url: 'https://lambda-url/api/v1/webhook/evolution',
byEvents: true,
base64: false,
events: ['MESSAGES_UPSERT'],
headers: { jwt_key: 'YOUR_WEBHOOK_SECRET' } // MUST have a value
}
}
// POST /webhook/set/{instanceName}
// MUST wrap in "webhook" property
{
webhook: {
enabled: true,
url: 'https://lambda-url/api/v1/webhook/evolution',
webhookByEvents: true,
webhookBase64: false,
events: ['MESSAGES_UPSERT'],
headers: { jwt_key: 'YOUR_WEBHOOK_SECRET' }
}
}
/instance/connect/{name} - returns { code, base64, pairingCode }code field is the raw QR data string (~240 chars)npx qrcode -o /tmp/qr.png "$CODE" or use require('qrcode').toDataURL()/mnt/c/Users/{user}/Downloads/Never try to pipe base64 image data through ECS exec - it gets truncated and corrupted.
WhatsApp Baileys protocol enforces single connection per phone number. Staging + production competing = session conflict loop.
| Component | Staging | Production |
|---|---|---|
WHATSAPP_MOCK | 'true' | 'false' |
EVOLUTION_INSTANCE_NAME | alinhou-staging | alinhou-production |
| ECS scaling | { min: 0, max: 0 } | { min: 1, max: 1 } |
| Evolution DB | /evolution | /evolution_prod |
| Outage checker | Returns mock stub | Real Evolution calls |
In SST infra:
WHATSAPP_MOCK: $app.stage === 'production' ? 'false' : 'true',
EVOLUTION_INSTANCE_NAME: `alinhou-${$app.stage}`,