API Contracts - WhatsApp Web Server (REST)
API Contracts - WhatsApp Web Server (REST)
Section titled “API Contracts - WhatsApp Web Server (REST)”Part: whatsapp-web-server Framework: Elysia (Bun-native) OpenAPI: Auto-generated via
swaggerplugin Generated: 2026-01-04
Overview
Section titled “Overview”The WhatsApp Web Server provides REST endpoints for managing WhatsApp Web.js connections. It uses Elysia with WAHA API abstraction for cross-provider compatibility.
Authentication
Section titled “Authentication”All endpoints require authentication via one of:
- WorkOS JWT: Bearer token from WorkOS AuthKit
- API Key: For internal/webhook calls (WAHA-protected endpoints)
Auth Middleware
Section titled “Auth Middleware”| Middleware | Purpose |
|---|---|
requireAuth | Validates WorkOS JWT, injects user context |
requireSingleAccountProtected | Account-scoped auth + single-account enforcement |
requireWahaProtected | API key auth for WAHA callbacks |
Base URL
Section titled “Base URL”/api/whatsappEndpoints
Section titled “Endpoints”Client Management
Section titled “Client Management”POST /api/whatsapp/:phoneNumber/start
Section titled “POST /api/whatsapp/:phoneNumber/start”Start WhatsApp Web.js client session.
Auth: requireSingleAccountProtected
Params:
phoneNumber(path): WhatsApp phone number
Response:
{ success: boolean message: string}POST /api/whatsapp/:phoneNumber/stop
Section titled “POST /api/whatsapp/:phoneNumber/stop”Stop and destroy client session.
Auth: requireSingleAccountProtected
Params:
phoneNumber(path): WhatsApp phone number
Response:
{ success: boolean message: string}GET /api/whatsapp/:phoneNumber/qr
Section titled “GET /api/whatsapp/:phoneNumber/qr”Get QR code for authentication.
Auth: requireSingleAccountProtected
Params:
phoneNumber(path): WhatsApp phone number
Response:
{ qrCode: string // Base64 QR image or data URL}GET /api/whatsapp/:phoneNumber/state
Section titled “GET /api/whatsapp/:phoneNumber/state”Get current connection state.
Auth: requireSingleAccountProtected
Response:
{ state: 'CONNECTED' | 'DISCONNECTED' | 'AUTHENTICATING' | 'CONFLICT'}POST /api/whatsapp/:phoneNumber/restart
Section titled “POST /api/whatsapp/:phoneNumber/restart”Restart client session.
Auth: requireSingleAccountProtected
Messaging
Section titled “Messaging”POST /api/whatsapp/:phoneNumber/send-text
Section titled “POST /api/whatsapp/:phoneNumber/send-text”Send text message.
Auth: requireSingleAccountProtected
Body:
{ chatId: string // WhatsApp JID (e.g., "5511999999999@c.us") text: string // Message content quotedMsgId?: string}Response:
{ messageId: string timestamp: number}POST /api/whatsapp/:phoneNumber/send-image
Section titled “POST /api/whatsapp/:phoneNumber/send-image”Send image with optional caption.
Auth: requireSingleAccountProtected
Body:
{ chatId: string imageUrl: string // URL or base64 caption?: string quotedMsgId?: string}POST /api/whatsapp/:phoneNumber/send-file
Section titled “POST /api/whatsapp/:phoneNumber/send-file”Send document/file.
Auth: requireSingleAccountProtected
Body:
{ chatId: string fileUrl: string filename?: string caption?: string}POST /api/whatsapp/:phoneNumber/send-video
Section titled “POST /api/whatsapp/:phoneNumber/send-video”Send video message.
Auth: requireSingleAccountProtected
POST /api/whatsapp/:phoneNumber/send-voice
Section titled “POST /api/whatsapp/:phoneNumber/send-voice”Send voice note (PTT).
Auth: requireSingleAccountProtected
POST /api/whatsapp/:phoneNumber/send-audio
Section titled “POST /api/whatsapp/:phoneNumber/send-audio”Send audio file.
Auth: requireSingleAccountProtected
Conversations
Section titled “Conversations”GET /api/whatsapp/:phoneNumber/chats
Section titled “GET /api/whatsapp/:phoneNumber/chats”Get all chats with pagination.
Auth: requireSingleAccountProtected
Query:
{ page?: number limit?: number archived?: boolean}Response:
{ chats: Array<{ id: string name: string isGroup: boolean unreadCount: number lastMessage?: { body: string timestamp: number } }> total: number page: number hasMore: boolean}GET /api/whatsapp/:phoneNumber/chat/:chatId
Section titled “GET /api/whatsapp/:phoneNumber/chat/:chatId”Get single chat details.
Auth: requireSingleAccountProtected
GET /api/whatsapp/:phoneNumber/messages/:chatId
Section titled “GET /api/whatsapp/:phoneNumber/messages/:chatId”Get messages from chat.
Auth: requireSingleAccountProtected
Query:
{ page?: number limit?: number // Default: 50 before?: string // Message ID cursor}Contacts
Section titled “Contacts”GET /api/whatsapp/:phoneNumber/contacts
Section titled “GET /api/whatsapp/:phoneNumber/contacts”Get all contacts.
Auth: requireSingleAccountProtected
GET /api/whatsapp/:phoneNumber/contact/:contactId
Section titled “GET /api/whatsapp/:phoneNumber/contact/:contactId”Get contact details.
Auth: requireSingleAccountProtected
GET /api/whatsapp/:phoneNumber/contact/:contactId/profile-picture
Section titled “GET /api/whatsapp/:phoneNumber/contact/:contactId/profile-picture”Get contact’s profile picture URL.
Auth: requireSingleAccountProtected
POST /api/whatsapp/:phoneNumber/contact/block
Section titled “POST /api/whatsapp/:phoneNumber/contact/block”Block a contact.
Auth: requireSingleAccountProtected
POST /api/whatsapp/:phoneNumber/contact/unblock
Section titled “POST /api/whatsapp/:phoneNumber/contact/unblock”Unblock a contact.
Auth: requireSingleAccountProtected
Groups
Section titled “Groups”POST /api/whatsapp/:phoneNumber/group/create
Section titled “POST /api/whatsapp/:phoneNumber/group/create”Create new group.
Auth: requireSingleAccountProtected
Body:
{ name: string participants: string[] // Array of WhatsApp JIDs}GET /api/whatsapp/:phoneNumber/group/:groupId
Section titled “GET /api/whatsapp/:phoneNumber/group/:groupId”Get group info.
Auth: requireSingleAccountProtected
PUT /api/whatsapp/:phoneNumber/group/:groupId
Section titled “PUT /api/whatsapp/:phoneNumber/group/:groupId”Update group settings.
Auth: requireSingleAccountProtected
POST /api/whatsapp/:phoneNumber/group/:groupId/leave
Section titled “POST /api/whatsapp/:phoneNumber/group/:groupId/leave”Leave group.
Auth: requireSingleAccountProtected
POST /api/whatsapp/:phoneNumber/group/:groupId/participants/add
Section titled “POST /api/whatsapp/:phoneNumber/group/:groupId/participants/add”Add participants to group.
Auth: requireSingleAccountProtected
POST /api/whatsapp/:phoneNumber/group/:groupId/participants/remove
Section titled “POST /api/whatsapp/:phoneNumber/group/:groupId/participants/remove”Remove participants from group.
Auth: requireSingleAccountProtected
Profile
Section titled “Profile”GET /api/whatsapp/:phoneNumber/profile
Section titled “GET /api/whatsapp/:phoneNumber/profile”Get current user’s profile.
Auth: requireSingleAccountProtected
PUT /api/whatsapp/:phoneNumber/profile/name
Section titled “PUT /api/whatsapp/:phoneNumber/profile/name”Update profile name.
Auth: requireSingleAccountProtected
PUT /api/whatsapp/:phoneNumber/profile/status
Section titled “PUT /api/whatsapp/:phoneNumber/profile/status”Update profile status.
Auth: requireSingleAccountProtected
PUT /api/whatsapp/:phoneNumber/profile/picture
Section titled “PUT /api/whatsapp/:phoneNumber/profile/picture”Update profile picture.
Auth: requireSingleAccountProtected
Webhooks (Internal)
Section titled “Webhooks (Internal)”POST /api/whatsapp/webhook/message
Section titled “POST /api/whatsapp/webhook/message”Receive incoming message events (WAHA callback).
Auth: requireWahaProtected
POST /api/whatsapp/webhook/state-change
Section titled “POST /api/whatsapp/webhook/state-change”Receive connection state change events.
Auth: requireWahaProtected
Error Responses
Section titled “Error Responses”{ error: string code?: string statusCode: number}Common Error Codes
Section titled “Common Error Codes”| HTTP | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid input |
| 401 | UNAUTHORIZED | Missing/invalid auth |
| 403 | FORBIDDEN | Not allowed for this account |
| 404 | NOT_FOUND | Client/chat/contact not found |
| 409 | CLIENT_NOT_READY | WhatsApp client not connected |
| 500 | INTERNAL_ERROR | Server error |
WAHA API Integration
Section titled “WAHA API Integration”The server abstracts WhatsApp Web.js behind the WAHA API interface:
class WahaApi { startSession(phoneNumber: string): Promise<void> stopSession(phoneNumber: string): Promise<void> getQR(phoneNumber: string): Promise<string> sendText(phoneNumber: string, chatId: string, text: string): Promise<MessageId> // ... more methods}This allows future migration to official WAHA server or alternative backends.
OpenAPI Documentation
Section titled “OpenAPI Documentation”Interactive API docs available at:
- Swagger UI:
/api/whatsapp/swagger - OpenAPI JSON:
/api/whatsapp/swagger/json