Appearance
Tenant API
Header: x-api-key: <app key>. These endpoints act on the one WhatsApp number linked to that app.
Status and pairing
GET /api/status
json
{ "appId": "app_9f2c...", "status": "ready", "info": { "phone": "15551234567", "pushname": "Support" } }status is one of starting, qr, pairing, authenticated, ready, disconnected, auth_failure, error.
GET /api/qr
Returns { "status": "qr", "qr": "data:image/png;base64,..." }, 202 while the QR is not available yet, or { "status": "ready", "qr": null } once connected.
POST /api/pairing-code
Body { "phoneNumber": "15551234567" }. Returns { "appId", "pairingCode": "ABCDEFGH", "expiresIn": 180 }. Missing number: 400 BAD_PHONE.
DELETE /api/pairing-code
Cancels phone pairing and returns to QR mode.
POST /api/logout
Logs out the WhatsApp account and wipes the stored session. Returns { "ok": true, "status": "..." }.
Messages
POST /api/messages
Rate limited. Returns 201.
| Field | Type | Notes |
|---|---|---|
to | string, required | Phone number, @c.us, @lid or @g.us id |
text | string, required | Up to 65,536 characters |
replyTo | string | messageId to quote |
json
{ "messageId": "true_15557654321@c.us_3EB0...", "to": "15557654321@c.us", "status": "sent" }status may be "unconfirmed" with messageId: null. See Sending messages.
POST /api/messages/media
Rate limited. Returns 201.
| Field | Type | Notes |
|---|---|---|
to | string, required | As above |
mediaUrl | string | URL to fetch. Use this or media. |
media | object | { data (base64), mimetype, filename } |
caption | string | |
filename | string | |
replyTo | string |
GET /api/messages
| Query | Meaning |
|---|---|
limit | Up to 200 |
before | Message id; page back using nextBefore |
q | Search text |
direction | in or out |
chatId | Only one chat |
Returns { "messages": [...], "nextBefore": "<id>" | null }, oldest first. Outbound messages include status (pending, sent, delivered, read, error).
GET /api/messages/:messageId/media
Binary download with the original Content-Type. Add ?format=json for { mimetype, data, filename } with base64 data. 404 NO_MEDIA if the message has none.
GET /api/numbers/:number
json
{ "number": "15557654321", "registered": true, "chatId": "15557654321@c.us" }An unregistered number answers 422 NOT_REGISTERED.