Send and receive WhatsApp messages from any application, automation tool, or AI agent using our REST API and MCP (Model Context Protocol) server. Now with programmatic account provisioning — spin up new WhatsApp accounts on demand from code or directly from an AI agent.
The WhatsApp API is a standalone product — you do NOT need a GoHighLevel (GHL) subscription to use it. You can also use it alongside GHL if you have both plans.
| Product | What it does | Messages | Requires GHL? |
|---|---|---|---|
| GHL Integration (Sub Accounts) | Connects WhatsApp to GoHighLevel CRM | Unlimited per sub-account | Yes |
| WhatsApp API (this product) | REST API + MCP for any app or AI agent. Provision accounts and sessions programmatically. | Based on your API plan | No |
If you have both a GHL subscription and an API plan, you can use the same WhatsApp sessions for both — GHL handles CRM sync while the API gives you programmatic access.
You can now create and manage WhatsApp accounts entirely through the API — no dashboard required. This turns the product into a true WhatsApp-as-a-Service backend: build your own SaaS, onboarding flow, or multi-tenant app on top of our infrastructure.
The provisioning flow is three calls:
POST /api/v1/locations — create an API account (workspace) to hold sessionsPOST /api/v1/sessions — create a WhatsApp device inside that account, which starts generating a QRGET /api/v1/sessions/:id/qr — poll until the QR is ready, show it to the end user, and watch the status flip to connected after they scancurl -X POST https://panel.wasndr.com/api/v1/locations \
-H "Authorization: Bearer wsndr_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Corp" }'
curl -X POST https://panel.wasndr.com/api/v1/sessions \
-H "Authorization: Bearer wsndr_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "locationUuid": "location-uuid-from-previous-call", "name": "Main Device" }'
curl https://panel.wasndr.com/api/v1/sessions/YOUR_SESSION_ID/qr \
-H "Authorization: Bearer wsndr_your_key_here"
The QR endpoint returns a base64 image (data:image/png;base64,...) and a status field that moves through starting → qr_ready → connected. Poll every 2–3 seconds while showing the QR to your user, and stop when status === 'connected'.
API-provisioned sessions count against your plan's session limit. Archive an account with DELETE /api/v1/locations/:uuid to free slots; remove a single device with DELETE /api/v1/sessions/:id.
AI agents can create and manage accounts over MCP, but scanning a QR and wiring a physical phone is a human-only step, so session provisioning is REST-only.
| Capability | MCP | REST |
|---|---|---|
| Create / list / archive API accounts | ✅ | ✅ |
| Create session, get QR, delete session | — | ✅ |
| Send messages, manage groups, read history | ✅ | ✅ |
| API key management | — | ✅ |
Go to the API page in your dashboard and click Activate Free Trial. You'll get:
wsndr_) — save it immediately, it's shown only onceTwo ways to connect a session:
Option A — Dashboard (fastest for a single number)
GET /api/v1/sessions to find your session IDOption B — API (for multi-tenant apps and programmatic onboarding)
Use the three-call provisioning flow above (POST /locations → POST /sessions → GET /sessions/:id/qr). This is what you want if you're building a product where each of your users brings their own WhatsApp number.
curl -X POST https://panel.wasndr.com/api/v1/messages/send \
-H "Authorization: Bearer wsndr_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "your-session-id",
"phone": "14155551234",
"text": "Hello from the API!"
}'
Add this to your MCP configuration:
{
"mcpServers": {
"wasndr-whatsapp": {
"url": "https://panel.wasndr.com/mcp",
"headers": {
"Authorization": "Bearer wsndr_your_key_here"
}
}
}
}
Your AI agent can then use tools like send_whatsapp_message, list_groups, check_whatsapp_number, create_api_account, and more.
All requests use Bearer Token authentication:
Authorization: Bearer wsndr_your_api_keywsndr_ prefixScopes on your key control what it can do: messages:send, messages:read, groups:read, groups:write, sessions:read, sessions:write. Provisioning endpoints require sessions:write (included by default on new keys).
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/messages/send |
Send a text message |
| POST | /api/v1/messages/send-media |
Send image, video, audio, or document |
| POST | /api/v1/messages/send-group |
Send text to a group |
| POST | /api/v1/messages/send-group-media |
Send media to a group |
| POST | /api/v1/messages/send-poll |
Send a poll |
| GET | /api/v1/messages/history |
Get message history, filterable by contact/date/text (Standard+) |
| GET | /api/v1/attachments |
List received media files (Standard+) |
Message history filtering — GET /api/v1/messages/history accepts these query params in addition to sessionId, limit, and offset:
remoteJid — filter to a single contact or group JID (e.g. 14155551234@s.whatsapp.net or 120363...@g.us)startDate, endDate — ISO date strings, e.g. 2026-04-01T00:00:00Zsearch — case-insensitive substring search over message text (walks conversation, extendedTextMessage, media captions, button/list replies; recurses into ephemeral/view-once wrappers)Each returned message now includes a flattened text field so you don't have to walk the raw Baileys shape yourself. Search runs against the current page — paginate with offset to search deeper.
curl "https://panel.wasndr.com/api/v1/messages/history?sessionId=SID&remoteJid=14155551234@s.whatsapp.net&search=invoice&limit=50" \
-H "Authorization: Bearer wsndr_your_key"
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/groups |
List all groups |
| GET | /api/v1/groups/:groupJid |
Get group info |
| GET | /api/v1/groups/:groupJid/participants |
List group participants |
| GET | /api/v1/groups/:groupJid/export-members |
Export members list |
| GET | /api/v1/groups/:groupJid/invite-code |
Get group invite link |
| POST | /api/v1/groups/create |
Create a new group |
| PUT | /api/v1/groups/:groupJid/subject |
Update group name |
| PUT | /api/v1/groups/:groupJid/description |
Update group description |
| POST | /api/v1/groups/:groupJid/participants/add |
Add participants |
| POST | /api/v1/groups/:groupJid/participants/remove |
Remove participants |
| POST | /api/v1/groups/:groupJid/leave |
Leave a group |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/locations |
Create a new API account to hold sessions |
| GET | /api/v1/locations |
List your API accounts |
| DELETE | /api/v1/locations/:uuid |
Archive an account and stop its sessions |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/sessions |
List your WhatsApp sessions |
| POST | /api/v1/sessions |
Create a new session (starts QR generation) |
| GET | /api/v1/sessions/:id/qr |
Get QR code + current connection status |
| GET | /api/v1/sessions/:id/status |
Check connection status (lightweight) |
| DELETE | /api/v1/sessions/:id |
Delete a session and free its slot |
Session status values: starting, qr_ready, reconnecting, connected, disconnected.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/check-number |
Verify if a phone number is on WhatsApp |
| GET | /api/v1/usage |
Check your API usage and limits |
| GET | /api/v1/account |
Get your account info and plan details |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/keys |
Create a new API key |
| GET | /api/v1/keys |
List your API keys |
| DELETE | /api/v1/keys/:uuid |
Revoke an API key |
| GET | /api/v1/mcp-config |
Get your MCP configuration snippet |
The MCP server at https://panel.wasndr.com/mcp exposes WhatsApp capabilities as tools that AI agents can use directly.
Messaging
send_whatsapp_message — Send a text messagesend_whatsapp_media — Send an image, video, audio, or documentsend_group_message — Send a text message to a groupsend_group_media — Send media to a groupsend_poll — Create a pollcheck_whatsapp_number — Verify whether a phone number is on WhatsAppget_message_history — Read recent conversation history (supports remoteJid, startDate, endDate, search)Groups
list_groups — List all groups on a sessionget_group_info — Get metadata for one groupget_group_participants — List a group's membersexport_group_members — Export the full member listcreate_group — Create a new groupadd_group_participants — Add membersremove_group_participants — Remove membersAPI Accounts (Provisioning)
create_api_account — Create a new API account (workspace) for a customer or tenantlist_api_accounts — List your API accountsarchive_api_account — Archive an account and free its session slotsSessions & Account
list_sessions — List sessions on the account and their connection statusget_session_status — Check a single session's connection statusget_usage — Current message usage for the billing periodSession creation, QR scanning, and session deletion are REST-only — an AI agent can create the account, but a human still needs to scan the QR from the REST
GET /sessions/:id/qrendpoint to finish connecting a device.
| Plan | Messages/mo | Sessions | Rate Limit | Price |
|---|---|---|---|---|
| Free Trial | 50 | 1 | 5/min | Free |
| Lite | 3,000 | 1 | 10/min | $19/mo |
| Standard | 9,000 | 2 | 30/min | $49/mo |
| Advanced | 40,000 | 10 | 100/min | $149/mo |
| Enterprise | 200,000 | 50 | 300/min | $499/mo |
Message history, group data, and attachment endpoints require the Standard plan or higher. Upgrade anytime from the API page in your dashboard.
End-to-end flow for onboarding a customer's WhatsApp number through your own app:
const API = 'https://panel.wasndr.com/api/v1';
const headers = {
'Authorization': 'Bearer wsndr_your_key_here',
'Content-Type': 'application/json',
};
// 1. Create an API account for this customer
const loc = await fetch(`${API}/locations`, {
method: 'POST',
headers,
body: JSON.stringify({ name: 'Acme Corp' }),
}).then(r => r.json());
// 2. Create a session — this starts QR generation
const session = await fetch(`${API}/sessions`, {
method: 'POST',
headers,
body: JSON.stringify({
locationUuid: loc.data.locationUuid,
name: 'Main Device',
}),
}).then(r => r.json());
const sessionId = session.data.sessionId;
// 3. Poll for the QR, show it to the user, wait for scan
while (true) {
const { data } = await fetch(`${API}/sessions/${sessionId}/qr`, { headers })
.then(r => r.json());
if (data.status === 'connected') {
console.log('Connected!', data.phone);
break;
}
if (data.qr) {
// Render data.qr (a base64 PNG data URL) in your UI
renderQrToUser(data.qr);
}
await new Promise(r => setTimeout(r, 2500));
}
const response = await fetch('https://panel.wasndr.com/api/v1/messages/send', {
method: 'POST',
headers: {
'Authorization': 'Bearer wsndr_your_key_here',
'Content-Type': 'application/json',
},
body: JSON.stringify({
sessionId: 'your-session-id',
phone: '14155551234',
text: 'Hello from Node.js!',
}),
});
const data = await response.json();
console.log(data);
curl -X POST https://panel.wasndr.com/api/v1/messages/send-media \
-H "Authorization: Bearer wsndr_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "your-session-id",
"phone": "14155551234",
"mediaUrl": "https://example.com/image.jpg",
"caption": "Check this out!",
"mediaType": "image"
}'
Use this to find your session IDs:
curl https://panel.wasndr.com/api/v1/sessions \
-H "Authorization: Bearer wsndr_your_key_here"
Returns your connected WhatsApp sessions with their IDs and connection status.