Skip to content

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 swagger plugin Generated: 2026-01-04

The WhatsApp Web Server provides REST endpoints for managing WhatsApp Web.js connections. It uses Elysia with WAHA API abstraction for cross-provider compatibility.

All endpoints require authentication via one of:

  • WorkOS JWT: Bearer token from WorkOS AuthKit
  • API Key: For internal/webhook calls (WAHA-protected endpoints)
MiddlewarePurpose
requireAuthValidates WorkOS JWT, injects user context
requireSingleAccountProtectedAccount-scoped auth + single-account enforcement
requireWahaProtectedAPI key auth for WAHA callbacks
/api/whatsapp

Start WhatsApp Web.js client session.

Auth: requireSingleAccountProtected Params:

  • phoneNumber (path): WhatsApp phone number

Response:

{
success: boolean
message: string
}

Stop and destroy client session.

Auth: requireSingleAccountProtected Params:

  • phoneNumber (path): WhatsApp phone number

Response:

{
success: boolean
message: string
}

Get QR code for authentication.

Auth: requireSingleAccountProtected Params:

  • phoneNumber (path): WhatsApp phone number

Response:

{
qrCode: string // Base64 QR image or data URL
}

Get current connection state.

Auth: requireSingleAccountProtected Response:

{
state: 'CONNECTED' | 'DISCONNECTED' | 'AUTHENTICATING' | 'CONFLICT'
}

Restart client session.

Auth: requireSingleAccountProtected

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
}

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

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
}

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

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

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

Receive incoming message events (WAHA callback).

Auth: requireWahaProtected

Receive connection state change events.

Auth: requireWahaProtected

{
error: string
code?: string
statusCode: number
}
HTTPCodeDescription
400BAD_REQUESTInvalid input
401UNAUTHORIZEDMissing/invalid auth
403FORBIDDENNot allowed for this account
404NOT_FOUNDClient/chat/contact not found
409CLIENT_NOT_READYWhatsApp client not connected
500INTERNAL_ERRORServer error

The server abstracts WhatsApp Web.js behind the WAHA API interface:

packages/waha-api/src/api.ts
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.

Interactive API docs available at:

  • Swagger UI: /api/whatsapp/swagger
  • OpenAPI JSON: /api/whatsapp/swagger/json