description

API Documentation

WA Bot Server

arrow_back Dashboard

WA Bot Server API

Complete REST API reference. All endpoints accept and return JSON. All /api/* routes require a valid Bearer token.

Base URL http://localhost:3000

shield Authentication

All /api/* endpoints require authentication. Include your token in every request:

Authorization: Bearer <your-token>

๐Ÿ“Œ Get your token by calling POST /auth/register or POST /auth/login.

๐Ÿ“Œ Tokens are long-lived โ€” they never expire unless you reset your password.

๐Ÿ“Œ Resetting your password generates a new token, invalidating all old sessions.

๐Ÿ“Œ Each user has isolated data โ€” messages, webhooks, stats, and WhatsApp sessions are fully separated.

POST /auth/register Create a new account โ–ถ

Request Body

ParamTypeDescription
emailstringRequiredYour email address
passwordstringRequiredMin 6 characters

Example

curl -X POST http://localhost:3000/auth/register \ -H "Content-Type: application/json" \ -d '{ "email": "you@example.com", "password": "secret123" }'

Response

{ "success": true, "token": "a1b2c3d4e5f6...", "user": { "id": "uuid-here", "email": "you@example.com" } }
POST /auth/login Sign in and get token โ–ถ

Request Body

ParamTypeDescription
emailstringRequiredYour email address
passwordstringRequiredYour password

Example

curl -X POST http://localhost:3000/auth/login \ -H "Content-Type: application/json" \ -d '{ "email": "you@example.com", "password": "secret123" }'
GET /auth/me Get current user info (requires token) โ–ถ

Example

curl http://localhost:3000/auth/me \ -H "Authorization: Bearer YOUR_TOKEN"

Response

{ "id": "uuid", "email": "you@example.com" }
POST /auth/forgot-password Request OTP (logged to server console) โ–ถ

Request Body

{ "email": "you@example.com" }

๐Ÿ’ก The 6-digit OTP will appear in your server console. Valid for 15 minutes. Max 5 attempts.

POST /auth/reset-password Reset password with OTP โ–ถ

Request Body

{ "email": "you@example.com", "otp": "123456", "newPassword": "newSecret123" }

โš ๏ธ Resets your token โ€” all existing sessions are invalidated. You'll receive a new token in the response.

POST /api/send-message Send a message to a phone number โ–ถ

Request Body

ParamTypeDescription
numberstringRequiredPhone number with country code (e.g. 254712345678)
messagestringRequiredThe message text to send

Example

curl -X POST http://localhost:3000/api/send-message \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "number": "254712345678", "message": "Hello from the bot!" }'
POST /api/send-group-message Send a message to a group โ–ถ

Example

curl -X POST http://localhost:3000/api/send-group-message \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "groupId": "120363012345@g.us", "message": "Hello group!" }'
GET /api/messages Get recent message log โ–ถ

Example

curl http://localhost:3000/api/messages?limit=10 \ -H "Authorization: Bearer YOUR_TOKEN"
GET /api/groups List all joined groups โ–ถ

Example

curl http://localhost:3000/api/groups \ -H "Authorization: Bearer YOUR_TOKEN"
POST /api/join-group Join group via invite link โ–ถ

Example

curl -X POST http://localhost:3000/api/join-group \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "inviteLink": "https://chat.whatsapp.com/ABC123" }'
POST /api/leave-group Leave a group โ–ถ

Example

curl -X POST http://localhost:3000/api/leave-group \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "groupId": "120363012345@g.us" }'
POST /api/add-to-group Add participants to a group โ–ถ

Example

curl -X POST http://localhost:3000/api/add-to-group \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "groupId": "120363012345@g.us", "participants": ["254712345678"] }'
GET /api/hooks List registered webhooks โ–ถ

Example

curl http://localhost:3000/api/hooks \ -H "Authorization: Bearer YOUR_TOKEN"
POST /api/hooks/register Register a webhook URL โ–ถ

Example

curl -X POST http://localhost:3000/api/hooks/register \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "url": "https://example.com/webhook", "name": "My App" }'

Webhook Payload

When a message is received, the following JSON is POSTed to your URL:

{ "id": "false_254712345678@c.us_3EB0...", "from": "254712345678@c.us", "body": "Hello!", "timestamp": "2026-02-23T12:00:00.000Z", "type": "received", "contactName": "John", "isGroup": false }
DELETE /api/hooks/unregister Remove a webhook โ–ถ

Example

curl -X DELETE http://localhost:3000/api/hooks/unregister \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "id": "m1abc12" }'
GET /api/status Bot connection status + QR code โ–ถ

Example

curl http://localhost:3000/api/status \ -H "Authorization: Bearer YOUR_TOKEN"

Response

{ "status": "ready", // "disconnected" | "qr" | "initializing" | "ready" "qr": null, // base64 data URL when status is "qr" "info": { "pushname": "My Bot", "phone": "254712345678", "platform": "android" } }
GET /api/stats Dashboard statistics โ–ถ

Example

curl http://localhost:3000/api/stats \ -H "Authorization: Bearer YOUR_TOKEN"

Response

{ "messagesSent": 42, "messagesReceived": 128, "groupsJoined": 3, "groupsLeft": 1, "webhookCount": 2 }

๐Ÿ“ฅ Inbox & Conversations

A WhatsApp/email-style view built from the message log: messages are grouped by conversation, with each conversation's most recent message surfaced, newest first. chat is a contact or group JID (e.g. 12345@s.whatsapp.net or 12345-67890@g.us).

GET/api/inbox?enrich=true&limit= โ€” conversation list + last message; enrich adds profile picture, name & about/topic
GET/api/conversation?chat=&limit= โ€” messages of one conversation (oldest first)
GET/api/conversation/actions?chat= โ€” actions available for the contact/group
POST/api/conversation/actionchat, action, …params

Actions โ€” contacts: block, unblock, subscribe_presence. Groups: exit, set_name, set_description, set_photo, announce, lock, invite_link, add/remove/promote/demote.

curl -X POST http://localhost:3000/api/conversation/action \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{"chat":"12345-67890@g.us","action":"set_name","name":"New group name"}'

Realtime new messages still arrive over the WebSocket (message events); these endpoints serve the cached history and the conversation list.

๐Ÿ“Ž Media & Rich Messages

Media fields (image/video/audio/...) accept an https:// URL, a data: URI, or a raw base64 string. to accepts a phone number or a full JID.

POST/api/send-imageto, image, caption
POST/api/send-videoto, video, caption, gifPlayback
POST/api/send-audioto, audio, ptt (voice note)
POST/api/send-documentto, document, filename, caption, mimetype
POST/api/send-stickerto, sticker (WebP)
POST/api/send-locationto, latitude, longitude, name, address
POST/api/send-contactto, displayName, phone or vcard
POST/api/send-pollto, name, options[], selectableCount
curl -X POST http://localhost:3000/api/send-image \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{"to":"254712345678","image":"https://picsum.photos/600","caption":"Hi ๐Ÿ‘‹"}'

โœ๏ธ Message Actions & Presence

For reactions / deletes on someone else's message, pass participant (group sender) and fromMe:false.

POST/api/reply-messageto, messageId, participant, text, quotedText
POST/api/send-reactionto, messageId, emoji, fromMe (empty emoji removes)
POST/api/edit-messageto, messageId, newText
POST/api/revoke-messageto, messageId, participant, fromMe (delete for everyone)
POST/api/mark-readchat, sender, messageIds[]
POST/api/presencepresence: available / unavailable
POST/api/chat-presenceto, state: composing/paused, media
POST/api/subscribe-presencejid

๐Ÿ‘ฅ Group & Community Management

GET/api/group-info?groupId=
POST/api/create-groupname, participants[]
POST/api/group/participantsgroupId, action (add/remove/promote/demote), participants[]
POST/api/group/namegroupId, name
POST/api/group/topicgroupId, topic
POST/api/group/photogroupId, image (empty removes)
POST/api/group/announcegroupId, announce
POST/api/group/lockedgroupId, locked
GET/api/group/invite-link?groupId=&reset=
GET/api/group/info-from-link?link=
GET/api/group/join-requests?groupId=
POST/api/group/join-requestsgroupId, action (approve/reject), participants[]
POST/api/group/member-add-modegroupId, mode
POST/api/group/disappearinggroupId, seconds
GET/api/group/subgroups?communityId=
POST/api/group/link ยท /api/group/unlinkparent, child

๐Ÿ“‡ Contacts, Profile & Privacy

POST/api/check-numbernumbers[] โ†’ is on WhatsApp
GET/api/user-info?jids= (csv) โ†’ status, picture id, devices
GET/api/profile-picture?jid=&preview=
GET/api/business-profile?jid=
GET/api/user-devices?jids= (csv)
GET/api/contactslocal contact cache
GET/api/blocklistlist blocked users
POST/api/block ยท /api/unblockjid
GET/api/privacy-settingsread privacy settings
POST/api/set-statusstatus (your "about" text)

๐Ÿ“ฐ Channels (Newsletters)

GET/api/newslettersfollowed channels
GET/api/newsletter/info?jid=
GET/api/newsletter/info-from-invite?key=
POST/api/newsletter/createname, description
POST/api/newsletter/follow ยท /unfollowjid
POST/api/newsletter/mutejid, mute

โฌ‡๏ธ Download Media from Chats

Incoming media (image/video/audio/document/sticker) is cached in memory as it arrives. Download it by message id; the response is a base64 dataUri you can preview or save. Only recently received media is available (cache is bounded and cleared on restart).

GET/api/download-media?messageId= โ†’ { mediaType, mimetype, filename, size, dataUri }
curl http://localhost:3000/api/download-media?messageId=ABCD1234 \
  -H "Authorization: Bearer YOUR_TOKEN"

๐Ÿ”Œ Realtime WebSocket

Connect to /ws for a live push stream instead of polling. Authenticate with a Bearer header, a ?token= query param, or the wa_token cookie. Every frame is a JSON envelope { event, data, timestamp }; a status snapshot is sent on connect.

Events: status, pair_success, message, receipt, presence, chat_presence, group_info, joined_group, picture, call.

const ws = new WebSocket(`ws://localhost:3000/ws?token=${'$'}{token}`);
ws.onmessage = (e) => {
  const { event, data, timestamp } = JSON.parse(e.data);
  console.log(event, data); // status | message | receipt | presence | ...
};