Sendmako Documentation
Sendmako lets you send and receive WhatsApp messages programmatically. Connect your WhatsApp number via QR code, then use any HTTP client to send messages, manage sessions, receive real-time events via webhooks, and decrypt incoming media files.
5
Session endpoints
8
Message types
4
Webhook events
REST
JSON API
Base URL
All API requests use the following base URL:
All requests and responses use application/json unless stated otherwise (decrypt-media returns binary).
Authentication
All requests must include your API key in the Authorization header.
Header
Authorization: Bearer wsa_your_api_key_here
Generate and manage your API keys in the Dashboard → API Keys page.
Errors & Responses
Sendmako uses standard HTTP status codes. All errors include a message field.
| Code | Meaning |
|---|---|
| 200 | OK — request succeeded |
| 201 | Created — resource created |
| 400 | Bad Request — missing or invalid fields |
| 401 | Unauthorized — invalid or missing API key |
| 403 | Forbidden — plan limit reached |
| 404 | Not Found — resource does not exist |
| 422 | Unprocessable — valid request but operation failed |
| 503 | Service Unavailable — WhatsApp service unreachable |
Error response
{
"success": false,
"message": "No WhatsApp session found. Connect a number first."
}
Sessions
/api/whatsapp/sessions/
List All Sessions
Returns all WhatsApp sessions for the authenticated user with their current live status.
curl -X GET "https://sendmako.com/api/whatsapp/sessions/" \ -H "Authorization: Bearer wsa_your_api_key"
import requests
r = requests.get(
"https://sendmako.com/api/whatsapp/sessions/",
headers={"Authorization": "Bearer wsa_your_api_key"}
)
print(r.json())
const r = await fetch("https://sendmako.com/api/whatsapp/sessions/", {
headers: { "Authorization": "Bearer wsa_your_api_key" }
});
console.log(await r.json());
["Authorization: Bearer wsa_your_api_key"],
CURLOPT_RETURNTRANSFER => true,
]);
print_r(json_decode(curl_exec($ch), true));
Response
[
{
"id": 1,
"session_id": "user_1",
"session_name": "Personal",
"status": "connected",
"phone_number": "22241857975",
"qr": null
}
]
/api/whatsapp/sessions/
Create Session
Creates a new WhatsApp session slot. After creation, poll the session status endpoint until status = qr_ready, then display the QR code for scanning. Limited by your subscription plan.
curl -X POST "https://sendmako.com/api/whatsapp/sessions/" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"session_name": "Business"}'
r = requests.post(
"https://sendmako.com/api/whatsapp/sessions/",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"session_name": "Business"}
)
print(r.json())
const r = await fetch("https://sendmako.com/api/whatsapp/sessions/", {
method: "POST",
headers: {"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body: JSON.stringify({session_name: "Business"})
});
console.log(await r.json());
$ch = curl_init("https://sendmako.com/api/whatsapp/sessions/");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(["session_name" => "Business"]),
CURLOPT_HTTPHEADER => ["Authorization: Bearer wsa_your_api_key","Content-Type: application/json"],
CURLOPT_RETURNTRANSFER => true,
]);
print_r(json_decode(curl_exec($ch), true));
Response 201
{
"success": true,
"id": 2,
"session_id": "user_1_2",
"session_name": "Business",
"status": "connecting"
}
/api/whatsapp/sessions/{session_id}/
Session Status & QR Code
Returns the live status of a session. When status = qr_ready, the response includes a base64 QR code image to display for scanning.
curl -X GET "https://sendmako.com/api/whatsapp/sessions/user_1/" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get(
"https://sendmako.com/api/whatsapp/sessions/user_1/",
headers={"Authorization": "Bearer wsa_your_api_key"}
)
print(r.json())
const r = await fetch("https://sendmako.com/api/whatsapp/sessions/user_1/", {
headers: { "Authorization": "Bearer wsa_your_api_key" }
});
console.log(await r.json());
$ch = curl_init("https://sendmako.com/api/whatsapp/sessions/user_1/");
curl_setopt_array($ch,[CURLOPT_HTTPHEADER=>["Authorization: Bearer wsa_your_api_key"],CURLOPT_RETURNTRANSFER=>true]);
print_r(json_decode(curl_exec($ch),true));
When connected
{"status": "connected", "qr": null}
When QR ready
{"status": "qr_ready", "qr": "data:image/png;base64,iVBO..."}
/api/whatsapp/sessions/{session_id}/
Rename Session
Updates the display name of a session.
curl -X PATCH "https://sendmako.com/api/whatsapp/sessions/user_1/" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"session_name": "My Business Line"}'
r = requests.patch(
"https://sendmako.com/api/whatsapp/sessions/user_1/",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"session_name": "My Business Line"}
)
await fetch("https://sendmako.com/api/whatsapp/sessions/user_1/", {
method: "PATCH",
headers: {"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body: JSON.stringify({session_name: "My Business Line"})
});
$ch = curl_init("https://sendmako.com/api/whatsapp/sessions/user_1/");
curl_setopt_array($ch,[CURLOPT_CUSTOMREQUEST=>"PATCH",
CURLOPT_POSTFIELDS=>json_encode(["session_name"=>"My Business Line"]),
CURLOPT_HTTPHEADER=>["Authorization: Bearer wsa_your_api_key","Content-Type: application/json"],
CURLOPT_RETURNTRANSFER=>true]);
print_r(json_decode(curl_exec($ch),true));
Response
{"success": true, "session_name": "My Business Line"}
/api/whatsapp/sessions/{session_id}/
Delete Session
Disconnects and permanently removes a WhatsApp session. The number will need to reconnect via QR code to be used again.
curl -X DELETE "https://sendmako.com/api/whatsapp/sessions/user_1/" \ -H "Authorization: Bearer wsa_your_api_key"
requests.delete("https://sendmako.com/api/whatsapp/sessions/user_1/",
headers={"Authorization": "Bearer wsa_your_api_key"})
await fetch("https://sendmako.com/api/whatsapp/sessions/user_1/", {
method: "DELETE",
headers: {"Authorization": "Bearer wsa_your_api_key"}
});
$ch = curl_init("https://sendmako.com/api/whatsapp/sessions/user_1/");
curl_setopt_array($ch,[CURLOPT_CUSTOMREQUEST=>"DELETE",
CURLOPT_HTTPHEADER=>["Authorization: Bearer wsa_your_api_key"],
CURLOPT_RETURNTRANSFER=>true]);
print_r(json_decode(curl_exec($ch),true));
Response
{"success": true}
Messages
/api/send-message
Send Text Message
Sends a plain text message to a WhatsApp number.
textcurl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "22241857975",
"type": "text",
"text": "Hello from Sendmako!"
}'
import requests
r = requests.post(
"https://sendmako.com/api/send-message",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"to": "22241857975", "type": "text", "text": "Hello from Sendmako!"}
)
print(r.json())
const r = await fetch("https://sendmako.com/api/send-message", {
method: "POST",
headers: {
"Authorization": "Bearer wsa_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
to: "22241857975",
type: "text",
text: "Hello from Sendmako!"
})
});
console.log(await r.json());
true,
CURLOPT_POSTFIELDS => json_encode([
"to" => "22241857975",
"type" => "text",
"text" => "Hello from Sendmako!"
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer wsa_your_api_key",
"Content-Type: application/json"
],
CURLOPT_RETURNTRANSFER => true,
]);
print_r(json_decode(curl_exec($ch), true));
Response
{"success": true}
/api/send-message
Send Image Message
Sends an image from a public URL. Max file size: 16 MB.
imagecurl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "22241857975",
"type": "image",
"imageUrl": "https://example.com/photo.jpg",
"caption": "Check this out!"
}'
r = requests.post(
"https://sendmako.com/api/send-message",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={
"to": "22241857975", "type": "image",
"imageUrl": "https://example.com/photo.jpg",
"caption": "Check this out!"
}
)
await fetch("https://sendmako.com/api/send-message", {
method: "POST",
headers: {"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body: JSON.stringify({
to: "22241857975", type: "image",
imageUrl: "https://example.com/photo.jpg",
caption: "Check this out!"
})
});
$data = ["to"=>"22241857975","type"=>"image",
"imageUrl"=>"https://example.com/photo.jpg","caption"=>"Check this out!"];
// ... curl setup same as text example ...
/api/send-messageSend Video Message
Sends a video from a public URL. Max file size: 50 MB.
videocurl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"to":"22241857975","type":"video","videoUrl":"https://example.com/clip.mp4","caption":"Watch this!"}'
r = requests.post("https://sendmako.com/api/send-message",
headers={"Authorization":"Bearer wsa_your_api_key"},
json={"to":"22241857975","type":"video","videoUrl":"https://example.com/clip.mp4"})
await fetch("https://sendmako.com/api/send-message",{method:"POST",
headers:{"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body:JSON.stringify({to:"22241857975",type:"video",videoUrl:"https://example.com/clip.mp4"})});
$data=["to"=>"22241857975","type"=>"video","videoUrl"=>"https://example.com/clip.mp4"];
/api/send-messageSend Audio Message
Sends an audio file. Set voiceNote: true to render as a WhatsApp voice note with waveform. Max: 15 MB.
audiocurl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"to":"22241857975","type":"audio","audioUrl":"https://example.com/audio.mp3","voiceNote":false}'
r = requests.post("https://sendmako.com/api/send-message",
headers={"Authorization":"Bearer wsa_your_api_key"},
json={"to":"22241857975","type":"audio","audioUrl":"https://example.com/audio.mp3","voiceNote":False})
await fetch("https://sendmako.com/api/send-message",{method:"POST",
headers:{"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body:JSON.stringify({to:"22241857975",type:"audio",audioUrl:"https://example.com/audio.mp3",voiceNote:false})});
$data=["to"=>"22241857975","type"=>"audio","audioUrl"=>"https://example.com/audio.mp3","voiceNote"=>false];
/api/send-messageSend Document
Sends a document file (PDF, DOCX, XLSX, etc.). Max file size: 70 MB.
documentcurl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "22241857975",
"type": "document",
"documentUrl": "https://example.com/invoice.pdf",
"filename": "invoice.pdf",
"mimetype": "application/pdf"
}'
r = requests.post("https://sendmako.com/api/send-message",
headers={"Authorization":"Bearer wsa_your_api_key"},
json={"to":"22241857975","type":"document",
"documentUrl":"https://example.com/invoice.pdf",
"filename":"invoice.pdf","mimetype":"application/pdf"})
await fetch("https://sendmako.com/api/send-message",{method:"POST",
headers:{"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body:JSON.stringify({to:"22241857975",type:"document",
documentUrl:"https://example.com/invoice.pdf",
filename:"invoice.pdf",mimetype:"application/pdf"})});
$data=["to"=>"22241857975","type"=>"document",
"documentUrl"=>"https://example.com/invoice.pdf",
"filename"=>"invoice.pdf","mimetype"=>"application/pdf"];
/api/send-messageSend Location
Sends a GPS location pin that opens in maps.
locationcurl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"to":"22241857975","type":"location","latitude":14.6928,"longitude":-17.4467}'
r = requests.post("https://sendmako.com/api/send-message",
headers={"Authorization":"Bearer wsa_your_api_key"},
json={"to":"22241857975","type":"location","latitude":14.6928,"longitude":-17.4467})
await fetch("https://sendmako.com/api/send-message",{method:"POST",
headers:{"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body:JSON.stringify({to:"22241857975",type:"location",latitude:14.6928,longitude:-17.4467})});
$data=["to"=>"22241857975","type"=>"location","latitude"=>14.6928,"longitude"=>-17.4467];
/api/send-bulkBulk Send
Send the same message to up to 100 recipients in a single request. A 500ms delay is applied between sends to respect WhatsApp rate limits.
curl -X POST "https://sendmako.com/api/send-bulk" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recipients": ["22241857975", "221781234567", "237691234567"],
"type": "text",
"text": "Hello everyone!"
}'
r = requests.post(
"https://sendmako.com/api/send-bulk",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={
"recipients": ["22241857975", "221781234567", "237691234567"],
"type": "text",
"text": "Hello everyone!"
}
)
print(r.json())
const r = await fetch("https://sendmako.com/api/send-bulk", {
method: "POST",
headers: {"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body: JSON.stringify({
recipients: ["22241857975","221781234567","237691234567"],
type: "text",
text: "Hello everyone!"
})
});
console.log(await r.json());
$data = [
"recipients" => ["22241857975","221781234567","237691234567"],
"type" => "text",
"text" => "Hello everyone!"
];
$ch = curl_init("https://sendmako.com/api/send-bulk");
curl_setopt_array($ch,[CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode($data),
CURLOPT_HTTPHEADER=>["Authorization: Bearer wsa_your_api_key","Content-Type: application/json"],
CURLOPT_RETURNTRANSFER=>true]);
print_r(json_decode(curl_exec($ch),true));
Response
{
"success": true,
"summary": {"total": 3, "sent": 3, "failed": 0},
"results": [
{"to": "22241857975", "success": true},
{"to": "221781234567", "success": true},
{"to": "237691234567", "success": true}
]
}
/api/decrypt-mediaDecrypt Media File
Downloads and decrypts an encrypted WhatsApp media file using the mediaKey received in a webhook payload. Returns the raw decrypted binary with the correct Content-Type header — save it directly as .jpg, .mp4, .mp3, etc.
data.media.urldata.media.mediaKeydata.media.mimetypedata.media.directPathdata.media.fileEncSha256curl -X POST "https://sendmako.com/api/decrypt-media" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://mmg.whatsapp.net/v/t62.7118-24/...",
"mediaKey": "tE5cFixjaflyXbwRha8IdwovYHzrjAQ4mz16uhNcR6o=",
"mimetype": "image/jpeg",
"directPath": "/v/t62.7118-24/...",
"fileEncSha256": "Dhg75NZE9fSYDm1P6ovnCs7bNXHzWgSbSRPq4Uj7CIc="
}' \
--output data
r = requests.post(
"https://sendmako.com/api/decrypt-media",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={
"url": "https://mmg.whatsapp.net/v/...",
"mediaKey": "tE5cFixjaflyXbwRha8IdwovYHzrjAQ4mz16uhNcR6o=",
"mimetype": "image/jpeg",
"directPath": "/v/t62.7118-24/...",
"fileEncSha256": "Dhg75NZE9fSYDm1P6ovnCs7bNX..."
}
)
with open("image.jpg", "wb") as f:
f.write(r.content)
const r = await fetch("https://sendmako.com/api/decrypt-media", {
method: "POST",
headers: {"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body: JSON.stringify({
url: "https://mmg.whatsapp.net/v/...",
mediaKey: "tE5cFixjaflyXbwRha8IdwovYHzrjAQ4mz16uhNcR6o=",
mimetype: "image/jpeg",
directPath: "/v/t62.7118-24/...",
fileEncSha256: "Dhg75NZE9fSYDm1P6ovnCs7bNX..."
})
});
const blob = await r.blob();
// blob is the decrypted image — save or display it
$ch = curl_init("https://sendmako.com/api/decrypt-media");
$data = [
"url" => "https://mmg.whatsapp.net/v/...",
"mediaKey" => "tE5cFixjaflyXbwRha8IdwovYHzrjAQ4mz16uhNcR6o=",
"mimetype" => "image/jpeg",
"directPath" => "/v/t62.7118-24/...",
"fileEncSha256" => "Dhg75NZE9fSYDm1P6ovnCs7bNX..."
];
curl_setopt_array($ch,[CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode($data),
CURLOPT_HTTPHEADER=>["Authorization: Bearer wsa_your_api_key","Content-Type: application/json"],
CURLOPT_RETURNTRANSFER=>true]);
file_put_contents("image.jpg", curl_exec($ch));
Response
Binary file with Content-Type: image/jpeg (or appropriate MIME type). Use --output data with cURL or write r.content to a file in Python.
Contacts
/api/whatsapp/contacts/Get All Contacts
Returns all contacts synced from your connected WhatsApp number. Contacts are loaded automatically when the session connects.
curl -X GET "https://sendmako.com/api/whatsapp/contacts/" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get("https://sendmako.com/api/whatsapp/contacts/",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
const r = await fetch("https://sendmako.com/api/whatsapp/contacts/", {
headers: {"Authorization": "Bearer wsa_your_api_key"}
});
console.log(await r.json());
$ch = curl_init("https://sendmako.com/api/whatsapp/contacts/");
curl_setopt_array($ch,[CURLOPT_HTTPHEADER=>["Authorization: Bearer wsa_your_api_key"],CURLOPT_RETURNTRANSFER=>true]);
print_r(json_decode(curl_exec($ch),true));
Response
{
"success": true,
"contacts": [
{"id": "22241857975@s.whatsapp.net", "phone": "22241857975", "name": "Alassane Diallo"},
{"id": "221781234567@s.whatsapp.net", "phone": "221781234567", "name": "Fatou Ndiaye"}
]
}
Groups
/api/groupsList All Groups
Returns all WhatsApp groups the connected account is a member of.
curl -X GET "https://sendmako.com/api/groups" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get("https://sendmako.com/api/groups",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
const r = await fetch("https://sendmako.com/api/groups", {
headers: {"Authorization": "Bearer wsa_your_api_key"}
});
console.log(await r.json());
Response
{
"success": true,
"groups": [
{
"id": "120363XXXXXXXXXX@g.us",
"subject": "Team Sendmako",
"subjectOwner": "22241857975@s.whatsapp.net",
"creation": 1711209600,
"desc": "Official team group",
"owner": "22241857975@s.whatsapp.net",
"participants": [...]
}
]
}
/api/groupsCreate a New Group
Creates a new WhatsApp group with a name and initial list of participants.
["22241857975"])curl -X POST "https://sendmako.com/api/groups" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name":"Team Sendmako","participants":["22241857975","221781234567"]}'
r = requests.post("https://sendmako.com/api/groups",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"name": "Team Sendmako", "participants": ["22241857975", "221781234567"]})
print(r.json())
const r = await fetch("https://sendmako.com/api/groups", {
method: "POST",
headers: {"Authorization":"Bearer wsa_your_api_key","Content-Type":"application/json"},
body: JSON.stringify({name:"Team Sendmako",participants:["22241857975","221781234567"]})
});
console.log(await r.json());
Response
{"success": true, "group": {"id": "120363XXXXXXXXXX@g.us", "subject": "Team Sendmako", ...}}
/api/send-messageSend Group Message / Message with Mentions
Send a message to a group by passing the group JID (120363XXXXXXXXXX@g.us) as the to field. For mentions, add a mentions array of phone numbers.
curl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "120363XXXXXXXXXX@g.us",
"type": "text",
"text": "Hello group!"
}'
curl -X POST "https://sendmako.com/api/send-message" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "120363XXXXXXXXXX@g.us",
"type": "text",
"text": "@22241857975 check this out!",
"mentions": ["22241857975"]
}'
r = requests.post("https://sendmako.com/api/send-message",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={
"to": "120363XXXXXXXXXX@g.us",
"type": "text",
"text": "@22241857975 check this out!",
"mentions": ["22241857975"]
})
print(r.json())
/api/groups/{groupJid}/metadataGet Group Metadata
Returns subject, description, creation date, owner, and participant list for a group.
curl "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/metadata" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get("https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/metadata",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
Response
{
"success": true,
"metadata": {
"id": "120363XXXXXXXXXX@g.us",
"subject": "Team Sendmako",
"creation": 1711209600,
"owner": "22241857975@s.whatsapp.net",
"desc": "Official team group",
"participants": [
{"id": "22241857975@s.whatsapp.net", "admin": "superadmin"},
{"id": "221781234567@s.whatsapp.net", "admin": null}
]
}
}
/api/groups/{groupJid}/participantsGet Group Participants
Returns the list of participants for a specific group. If the list is empty, the initial sync may still be in progress.
curl "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/participants" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get("https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/participants",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
Response
{
"success": true,
"participants": [
{"id": "22241857975@s.whatsapp.net", "admin": "superadmin"},
{"id": "221781234567@s.whatsapp.net", "admin": null}
]
}
/api/groups/{groupJid}/participants/addAdd Group Participants
Adds one or more participants to a group. Requires admin privileges.
["22241857975"])curl -X POST "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/participants/add" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"participants":["22241857975","221781234567"]}'
r = requests.post(
"https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/participants/add",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"participants": ["22241857975", "221781234567"]})
print(r.json())
/api/groups/{groupJid}/participants/removeRemove Group Participants
Removes one or more participants from a group. Requires admin privileges.
curl -X POST "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/participants/remove" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"participants":["221781234567"]}'
r = requests.post(
"https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/participants/remove",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"participants": ["221781234567"]})
print(r.json())
/api/groups/{groupJid}/participants/updatePromote / Demote Participants
Promotes participants to admin or demotes them. Requires admin privileges.
"promote" or "demote"curl -X PUT "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/participants/update" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"participants":["221781234567"],"action":"promote"}'
r = requests.put(
"https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/participants/update",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"participants": ["221781234567"], "action": "promote"})
print(r.json())
/api/groups/{groupJid}/settingsUpdate Group Settings
Updates group subject, description, announce mode (only admins can send), or restrict mode (only admins can edit group info). Requires admin privileges.
true = only admins can send messagestrue = only admins can edit group infocurl -X PUT "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/settings" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"subject":"New Name","description":"Updated desc","announce":true}'
r = requests.put(
"https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/settings",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"subject": "New Name", "description": "Updated desc", "announce": True})
print(r.json())
/api/groups/{groupJid}/invite-linkGet Group Invite Link
Retrieves the invite link for a specific group. Requires admin privileges.
curl "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/invite-link" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get("https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/invite-link",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
Response
{"success": true, "invite_code": "AbCdEfGhIjKlMn", "invite_link": "https://chat.whatsapp.com/AbCdEfGhIjKlMn"}
/api/groups/invite/{inviteCode}Get Group Invite Info
Retrieves metadata for a group from its invite code without joining it.
curl "https://sendmako.com/api/groups/invite/AbCdEfGhIjKlMn" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get("https://sendmako.com/api/groups/invite/AbCdEfGhIjKlMn",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
/api/groups/invite/acceptAccept Group Invite
Join a group using an invite code.
curl -X POST "https://sendmako.com/api/groups/invite/accept" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"inviteCode":"AbCdEfGhIjKlMn"}'
r = requests.post("https://sendmako.com/api/groups/invite/accept",
headers={"Authorization": "Bearer wsa_your_api_key"},
json={"inviteCode": "AbCdEfGhIjKlMn"})
print(r.json())
/api/groups/{groupJid}/pictureGet Group Profile Picture
Returns the URL of the group's profile picture. Returns null if no picture is set.
curl "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/picture" \ -H "Authorization: Bearer wsa_your_api_key"
r = requests.get("https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/picture",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
Response
{"success": true, "picture_url": "https://pps.whatsapp.net/v/..."}
/api/groups/{groupJid}/leaveLeave Group
Leave a specific WhatsApp group.
curl -X POST "https://sendmako.com/api/groups/120363XXXXXXXXXX%40g.us/leave" \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{}'
r = requests.post("https://sendmako.com/api/groups/120363XXXXXXXXXX@g.us/leave",
headers={"Authorization": "Bearer wsa_your_api_key"})
print(r.json())
Response
{"success": true}
Webhooks
Webhook Setup & Signature Verification
Configure your webhook URL in Dashboard → Webhooks. Sendmako sends a signed HTTP POST to your URL for every event.
Verifying Signatures
Every request includes X-Sendmako-Signature: sha256=<hmac>. Verify it to ensure the request is genuine and not forged.
import hmac, hashlib
def verify_signature(payload_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), payload_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)
# Django/Flask usage:
# sig = request.headers.get("X-Sendmako-Signature", "")
# if not verify_signature(request.body, sig, "your_webhook_secret"):
# return HttpResponse(status=403)
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
// Express usage:
// app.post('/webhook', (req, res) => {
// const sig = req.headers['x-sendmako-signature'];
// if (!verifySignature(JSON.stringify(req.body), sig, 'your_secret')) {
// return res.sendStatus(403);
// }
// });
function verifySignature(string $payload, string $signature, string $secret): bool {
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
return hash_equals($expected, $signature);
}
// Usage:
// $payload = file_get_contents('php://input');
// $sig = $_SERVER['HTTP_X_SENDMAKO_SIGNATURE'] ?? '';
// if (!verifySignature($payload, $sig, 'your_webhook_secret')) {
// http_response_code(403); exit;
// }
Webhook Events Reference
All events use the same envelope. The data object varies per event.
Common envelope
{
"event": "message.received",
"timestamp": "2026-03-23T17:00:00Z",
"session_id": "user_1",
"data": { ... }
}
Fired when a new incoming message arrives on your number.
{
"event": "message.received",
"timestamp": "2026-03-23T17:00:00Z",
"session_id": "user_1",
"data": {
"message_id": "3EB043CFB548568C7532C1",
"from": "22241857975",
"sender_name": "Alassane Diallo",
"type": "conversation",
"body": "Hello!",
"timestamp": 1711209600,
// For media messages (imageMessage, videoMessage, audioMessage, documentMessage):
"media": {
"url": "https://mmg.whatsapp.net/v/...",
"mimetype": "image/jpeg",
"mediaKey": "tE5cFixjaflyXbwRha8IdwovYHzrjAQ4mz16uhNcR6o=",
"fileEncSha256": "Dhg75NZE9fSYDm1P6ovnCs7bNXHzWgSbSRPq4Uj7CIc=",
"directPath": "/v/t62.7118-24/...",
"fileSize": "122866",
"width": 905,
"height": 1280,
"duration": 30
}
}
}
Fired when a sent message is delivered or read by the recipient.
{
"event": "message.status",
"timestamp": "2026-03-23T17:01:00Z",
"session_id": "user_1",
"data": {
"message_id": "3EB043CFB548568C7532C1",
"to": "22241857975",
"status": "delivered" // "delivered" or "read"
}
}
Fired when a WhatsApp number successfully connects after QR scan.
{
"event": "session.connected",
"timestamp": "2026-03-23T17:00:00Z",
"session_id": "user_1",
"data": {
"phone_number": "22241857975"
}
}
Fired when a session drops — either by logout or connection loss.
{
"event": "session.disconnected",
"timestamp": "2026-03-23T17:05:00Z",
"session_id": "user_1",
"data": {
"reason": "logged_out" // "logged_out" or "connection_lost"
}
}
