wago-api

WhatsApp REST API — native protocol, multi-session, production-ready.
- 129 REST endpoints — messaging, groups, communities, channels, privacy, business
- Multi-session — run hundreds of WhatsApp accounts in a single instance
- 32MB Docker image — single Go binary, zero external dependencies
- Production-ready — auto-reconnect, webhook retry, rate limiting, SSRF protection, request tracing
Quick Start
git clone https://github.com/arktnld/wago-api && cd wago-api
docker compose up
Start a session and scan the QR code:
curl localhost:3000/session/start/main
curl localhost:3000/session/qr/main/image --output qr.png
Send a message:
curl -X POST localhost:3000/client/sendMessage/main \
-H 'Content-Type: application/json' \
-d '{"chatId":"5511999999999@s.whatsapp.net","text":"Hello from wago-api!"}'
{"success":true,"messageId":"3EB0F85AB813A2BB26F73D","timestamp":1777744034}
Features
Messaging
Send text, images, videos, audio, and documents. Reply, forward, edit, and delete messages. Send reactions, create polls, and star messages. Upload media via URL or base64.
Groups
Create and manage groups. Add, remove, promote, and demote participants. Generate and revoke invite links. Set group name, description, photo, and permissions. Approve or reject membership requests.
Communities
Create WhatsApp Communities. Link and unlink sub-groups. List all sub-groups and participants. Control join approval mode and member add permissions.
Channels (Newsletters)
Create, follow, and unfollow channels. Send messages and fetch message history. Send reactions, mute/unmute, and mark as viewed.
Access contact list and profile pictures. Subscribe to online/offline status. Send typing and recording indicators. Block and unblock contacts. Generate and resolve contact QR links.
Privacy
10 granular privacy settings: last seen, profile photo, about, status, groups, read receipts, online status, calls, messages, and stickers. Set disappearing messages globally or per-chat.
Business
Fetch verified business profiles and resolve wa.me message links. List official WhatsApp bots with their commands and prompts.
Calls
Reject incoming voice and video calls programmatically.
Labels
Create, edit, and delete labels with custom colors. Assign labels to chats and individual messages.
Infrastructure
- Auto-reconnect with error tracking
- Webhooks with 3x retry and exponential backoff
- WebSocket real-time event stream
- Per-IP rate limiting with auto-cleanup
- CORS headers for browser access
- API key authentication (header-only)
- Request tracing via
X-Request-Id
- SSRF protection on media URL fetches
- SQLite session persistence with WAL mode
- Parallel session restore on startup
Architecture
┌──────────┐ REST ┌──────────┐ Native Protocol ┌──────────────────┐
│ Your App ├──────────────►│ wago-api ├──────────────────────►│ WhatsApp Servers │
└──────────┘ └────┬─────┘ └──────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌────────┐ ┌──────────┐
│ Webhooks │ │ WS │ │ SQLite │
│ (retry) │ │ events │ │ sessions │
└──────────┘ └────────┘ └──────────┘
API Reference
129 REST endpoints across 12 categories: Session, Message, Client, Chat, Contact, Group, Channel, Community, Privacy, Business, Call, and Advanced.
Interactive API Documentation (Swagger UI)
Or access locally at http://localhost:3000/api-docs when running the server.
Events
Events are delivered via webhooks (HTTP POST) and/or WebSocket.
| Event |
Trigger |
ready |
Session connected |
disconnected |
Session disconnected |
logged_out |
Session logged out |
temporary_ban |
Account temporarily banned |
connect_failure |
Connection attempt failed |
stream_replaced |
Session replaced by another device |
qr |
New QR code generated |
authenticated |
QR scanned successfully |
message |
Message received |
message_create |
Message sent by this session |
message_ack |
Message delivery/read receipt |
presence |
Contact typing/recording state |
group_update |
Group metadata changed |
group_join |
Added to a group |
call |
Incoming call |
contact_changed |
Contact name changed |
blocklist |
Block list updated |
blocklist_change |
Contact blocked/unblocked |
chat_archived |
Chat archived/unarchived |
chat_muted |
Chat muted/unmuted |
chat_pinned |
Chat pinned/unpinned |
chat_removed |
Chat deleted |
message_starred |
Message starred/unstarred |
message_revoke_me |
Message deleted for me |
unread_count |
Chat read state changed |
label_edit |
Label created/edited/deleted |
label_association_chat |
Label assigned to chat |
label_association_message |
Label assigned to message |
history_sync |
Message history synced |
identity_change |
Contact security code changed |
newsletter_message |
Channel message received |
newsletter_join |
Joined a channel |
newsletter_leave |
Left a channel |
newsletter_mute_change |
Channel mute state changed |
picture |
Profile picture changed |
Webhook payload example:
{
"sessionId": "main",
"event": "message",
"data": {
"id": "3EB0F85AB813A2BB26F73D",
"chat": "5511999999999@s.whatsapp.net",
"sender": "5511999999999@s.whatsapp.net",
"pushName": "John",
"body": "Hello!",
"type": "text",
"timestamp": 1777744034,
"isGroup": false,
"isFromMe": false
}
}
Webhook URL pattern: {BASE_WEBHOOK_URL}/{sessionId}/{event}
Failed webhooks are retried 3 times with exponential backoff (1s, 2s, 4s).
Configuration
| Variable |
Default |
Description |
PORT |
3000 |
HTTP server port |
API_KEY |
(empty) |
API key for authentication (header X-Api-Key) |
BASE_WEBHOOK_URL |
(empty) |
Base URL for webhook callbacks |
ENABLE_WEBHOOK |
true |
Enable webhook delivery |
ENABLE_WEBSOCKET |
false |
Enable WebSocket event stream |
AUTO_START_SESSIONS |
true |
Restore sessions on startup |
SESSIONS_PATH |
./sessions |
Path for session database files |
SET_MESSAGES_AS_SEEN |
false |
Auto-mark incoming messages as read |
LOG_LEVEL |
info |
Log level: trace, debug, info, warn, error |
RATE_LIMIT_MAX |
1000 |
Max requests per window per IP |
RATE_LIMIT_WINDOW_MS |
1000 |
Rate limit window in milliseconds |
DISABLED_CALLBACKS |
(empty) |
Pipe-separated list of disabled events |
Docker
docker pull arktnld/wago-api:latest
services:
api:
image: arktnld/wago-api:latest
ports:
- "3000:3000"
volumes:
- ./sessions:/app/sessions
environment:
- API_KEY=your-secret-key
- BASE_WEBHOOK_URL=https://your-server.com/webhook
restart: unless-stopped
- Image size: 32MB
- Built-in healthcheck:
GET /ping every 30s
- Session data persisted in
/app/sessions volume
Build from Source
git clone https://github.com/arktnld/wago-api
cd wago-api
CGO_ENABLED=1 go build -ldflags="-s -w" -o wago-api .
./wago-api
Requires Go 1.25+ and a C compiler (for SQLite).
Security
- Authentication — API key via
X-Api-Key header (query parameter intentionally disabled to prevent key leakage in logs)
- SSRF Protection — Media URL fetches validate against private IPs, loopback addresses, and cloud metadata endpoints
- Rate Limiting — Per-IP token bucket with automatic stale entry cleanup
- Request Tracing — Every response includes
X-Request-Id header for debugging
Roadmap
- OpenAPI/Swagger spec
- Prometheus
/metrics endpoint
- Admin web dashboard
- Multi-arch Docker images (ARM64)
- End-to-end test suite
Credits
Built on whatsmeow by tulir. API design inspired by wwebjs-api.
License
MIT