An HTTP wrapper around Baileys for sending WhatsApp messages programmatically. Useful for alert pipelines, internal notifications, and automation.
This documentation is served by the API itself. Use the URL you opened this page on as your base URL — every endpoint below is relative to it.
Every endpoint except /docs requires an X-API-Key header. Requests without a valid key return 401.
X-API-Key: <your-api-key>
If you don't know the API key, it's the API_KEY value in the .env file on the host running this service.
to fieldThe recipient address accepts any of these formats:
+ — e.g. 918217643269. Auto-suffixed to @s.whatsapp.net.120363012345678901@g.us. Discover these via GET /groups.918217643269@s.whatsapp.net. Useful if you've already done the lookup./healthLiveness check. Reports whether the WhatsApp socket is currently open and ready to send.
Response
{"ok": true, "ready": true}
If ready: false, the service is up but WhatsApp isn't connected yet — wait a few seconds and retry, or check the host's process logs.
/groupsReturns every WhatsApp group the linked account is a participant in, with the JIDs you need to send to them.
Response
{
"ok": true,
"count": 2,
"groups": [
{
"jid": "120363012345678901@g.us",
"subject": "Alerts Team",
"participants": 5,
"isAdmin": false
}
]
}
Workflow: add the linked WhatsApp account to a group from your phone, call this endpoint, copy the JID for the group you want, and use it as to in /send.
Returns 503 if the WhatsApp socket isn't open yet.
/groups/joinJoins a WhatsApp group via its invite link. Returns the group's JID so you can immediately use it as to in /send.
Request body — pass either of these:
{"inviteLink": "https://chat.whatsapp.com/AbCdEf1234567"}
or just the code:
{"inviteCode": "AbCdEf1234567"}
Success response
{
"ok": true,
"jid": "120363012345678901@g.us",
"subject": "Alerts Team",
"participants": 5,
"alreadyMember": false
}
Notes:
alreadyMember: true. Safe to call idempotently to resolve a JID from any invite link.alreadyMember stays false; the group will only appear in /groups once approved.503 if WhatsApp isn't connected, 400 for a malformed link, 500 if both the join and the fallback lookup fail (revoked link, expired, etc.)./sendSend a message. The body must include to plus exactly one of: message, imageUrl, videoUrl, audioUrl, or documentUrl.
Success response
{
"ok": true,
"id": "3EB0...",
"to": "918217643269@s.whatsapp.net"
}
{
"to": "918217643269",
"message": "Revenue dropped 10% in the last hour."
}
{
"to": "918217643269",
"imageUrl": "https://example.com/chart.png",
"caption": "Revenue trend — last 24h"
}
{
"to": "918217643269",
"videoUrl": "https://example.com/clip.mp4",
"caption": "Incident replay"
}
{
"to": "918217643269",
"audioUrl": "https://example.com/sound.m4a",
"mimetype": "audio/mp4"
}
{
"to": "918217643269",
"audioUrl": "https://example.com/voice.ogg",
"voiceNote": true
}
For a true PTT waveform, the file must be Opus-in-Ogg. Pre-convert with ffmpeg -i input.mp3 -c:a libopus -b:a 32k output.ogg. Other formats will arrive as a generic audio attachment.
{
"to": "918217643269",
"documentUrl": "https://example.com/report.pdf",
"filename": "Monthly Report.pdf",
"mimetype": "application/pdf",
"caption": "October numbers"
}
filename is what the recipient sees when they save it. If omitted, it's derived from the URL. mimetype is auto-detected for common extensions, but pass it explicitly for reliability (e.g. application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for .xlsx).
Health check
curl <base-url>/health -H "X-API-Key: <your-api-key>"
List groups
curl <base-url>/groups -H "X-API-Key: <your-api-key>"
Send a text message
curl -X POST <base-url>/send \
-H "Content-Type: application/json" \
-H "X-API-Key: <your-api-key>" \
-d '{"to":"918217643269","message":"hello from baileys"}'
Send a PDF to a group
curl -X POST <base-url>/send \
-H "Content-Type: application/json" \
-H "X-API-Key: <your-api-key>" \
-d '{
"to":"120363012345678901@g.us",
"documentUrl":"https://example.com/report.pdf",
"filename":"Weekly Report.pdf",
"mimetype":"application/pdf",
"caption":"This week’s numbers"
}'
| Code | Meaning |
|---|---|
200 | Request succeeded |
400 | Invalid body — missing required fields, multiple media types specified, etc. |
401 | Missing or wrong X-API-Key header |
500 | Internal / Baileys error — see error field in response body |
503 | WhatsApp socket isn't open yet — check /health |
Built with @whiskeysockets/baileys + Express. Source on the host: index.js.