Skip to content

Sending messages ​

All requests need x-api-key: <app key> and a JSON body. Sending returns 409 NOT_READY until the app status is ready.

Text ​

bash
curl -X POST http://localhost:3000/api/messages \
  -H "x-api-key: $APP_KEY" -H "Content-Type: application/json" \
  -d '{"to":"15557654321","text":"Hello!","replyTo":"<messageId>"}'

replyTo is optional and quotes an earlier message. Text is limited to 65,536 characters.

Media ​

From a URL:

json
{ "to": "15557654321", "mediaUrl": "https://example.com/invoice.pdf", "caption": "Your invoice" }

Or inline as base64:

json
{
  "to": "15557654321",
  "media": { "data": "<base64>", "mimetype": "application/pdf", "filename": "invoice.pdf" }
}

Request bodies can be up to 25 MB. If a proxy rejects large sends, raise its body-size limit.

Check a number first ​

bash
curl -s http://localhost:3000/api/numbers/15557654321 -H "x-api-key: $APP_KEY"
# {"number":"15557654321","registered":true,"chatId":"15557654321@c.us"}

Send results ​

status: "sent" means WhatsApp accepted the message and returned a messageId. For contacts WhatsApp addresses by @lid, the gateway reads the id from the chat's message list and waits up to SEND_CONFIRM_WAIT_MS (default 5 seconds).

If you get status: "unconfirmed" with messageId: null, no id could be found but the message may still arrive. Do not resend automatically.

Delivery receipts ​

Outbound messages move through sent, delivered, read (or error). GET /api/messages includes status per message, and each change is sent to your webhook as a message.status event.

Reading the message log ​

GET /api/messages returns oldest first. Query parameters: limit (up to 200), before (a message id, page back with nextBefore), q (search), direction (in or out), chatId. Download media with GET /api/messages/:messageId/media (?format=json for base64).

The log is pruned after MESSAGE_RETENTION_DAYS (default 7).

Released under the Apache-2.0 License.