Detailed Guide • All requests require your provided API key
All endpoints require authentication via the header:
x-api-key: YOUR_PROVIDED_API_KEY
Base URL: http://your-server-url:3000/api (replace with your actual server URL)
Endpoint: GET /login
Poll this endpoint to check authentication status or retrieve the QR code (as text string) for scanning.
{ "loggedIn": true } – Session is authenticated and ready.{ "loggedIn": false, "qr": "data:image/png;base64,..." } – QR code data (use in QR generator).curl -H "x-api-key: YOUR_PROVIDED_API_KEY" http://your-server-url:3000/api/login
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
</head>
<body>
<h2>WhatsApp QR Login</h2>
<div id="status">Loading...</div>
<div id="qrCanvas" style="margin:20px auto; text-align:center;"></div>
<script>
const apiKey = "YOUR_PROVIDED_API_KEY"; // ← change
const baseUrl = "http://your-server-url:3000/api"; // ← change
function poll() {
fetch(`${baseUrl}/login`, {
headers: { "x-api-key": apiKey }
})
.then(r => r.json())
.then(data => {
if (data.loggedIn) {
document.getElementById("status").innerHTML = "<strong style='color:green'>✓ Authenticated! Ready to use.</strong>";
document.getElementById("qrCanvas").innerHTML = "";
} else if (data.qr) {
document.getElementById("status").innerHTML = "Scan QR below with WhatsApp:";
document.getElementById("qrCanvas").innerHTML = "";
new QRCode("qrCanvas", {
text: data.qr,
width: 320,
height: 320
});
setTimeout(poll, 4000);
} else {
document.getElementById("status").innerHTML = "Waiting for QR...";
setTimeout(poll, 3000);
}
})
.catch(err => {
document.getElementById("status").innerHTML = "Error: " + err;
});
}
poll();
setInterval(poll, 15000);
</script>
</body>
</html>
Endpoint: POST /send
Send text messages or media files (images, videos, documents, etc.). At least one of text or filePath must be provided.
| Parameter | Type | Required | Description |
|---|---|---|---|
| to | string or array of strings | Yes | Recipient identifier. Flexible matching: • Phone number (digits only, e.g. "15551234567") • Saved contact name (exact or partial) • Full chat ID (e.g. "15551234567@c.us" or group ID) • Comma-separated string or array for multiple attempts |
| text | string | Optional* | Message body or media caption |
| filePath | string | Optional* | Full server-side path to media file (must exist on server) |
* One of text or filePath is required.
The API tries identifiers in this order:
If multiple matches, returns 409 with suggestions. If none, returns 400 error.
{
"success": true,
"messageId": "true_15551234567@c.us_ABCDEF1234567890",
"resolvedUsing": "John Doe",
"resolvedTo": {
"id": "15551234567@c.us",
"name": "John Doe"
}
}
curl -X POST http://your-server-url:3000/api/send \
-H "x-api-key: YOUR_PROVIDED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "15551234567",
"text": "Hello from API!"
}'
curl -X POST http://your-server-url:3000/api/send \
-H "x-api-key: YOUR_PROVIDED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": ["John Doe", "15551234567"],
"text": "Check this photo",
"filePath": "/path/on/server/photo.jpg"
}'
fetch('http://your-server-url:3000/api/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_PROVIDED_API_KEY'
},
body: JSON.stringify({
to: '15551234567',
text: 'Test message'
})
})
.then(r => r.json())
.then(console.log);
Endpoint: GET /get-contacts
Retrieve list of contacts with flexible field selection, filtering, and pagination.
| Parameter | Type | Default | Description |
|---|---|---|---|
| fields | string | All allowed | Comma-separated: id, phone, number, name, pushname, shortName, isMyContact, isBusiness, isEnterprise, verifiedName, about, profilePicUrl |
| filters | string | None | Format: field:operator:value (multiple separated by comma) Operators: contains, startswith, endswith, equals, notequals, exists, notexists |
| limit | integer | All | Maximum results |
| offset | integer | 0 | Pagination offset |
name:contains:john,isMyContact:equals:trueisBusiness:exists:truecurl -H "x-api-key: YOUR_PROVIDED_API_KEY" \
"http://your-server-url:3000/api/get-contacts?fields=id,phone,name,profilePicUrl&filters=name:contains:friend&limit=50"
Endpoint: POST /get-messages
Retrieve recent messages from a specific chat (individual, group, or channel).
| Parameter | Type | Default | Description |
|---|---|---|---|
| identifier | string | Required | Chat identifier |
| identifierType | string | "name" | "name" (saved name), "phone" (digits), "chatId" (full ID) |
| exact | boolean | false | For name type: require exact match |
| limit | integer | 50 | 1–500 messages (newest first from WhatsApp, returned oldest→newest) |
curl -X POST http://your-server-url:3000/api/get-messages \
-H "x-api-key: YOUR_PROVIDED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"identifier": "John Doe",
"identifierType": "name",
"limit": 100
}'
If a webhook URL is configured for your API key, the server will POST JSON events in real-time:
qr_generated – with QR datamessage – incoming/outgoing (includes base64 media if present)message_ack – delivery/read receiptsclient_ready, authenticated, disconnected, etc.Useful for building real-time dashboards or processing incoming messages.