WhatsApp REST API Documentation
Complete reference for the Wasaas REST API. Base URL: https://wasaas.org/api/v1
Using a client library? There are setup guides for the WhatsApp API for Node.js, for PHP and for Laravel. For sending to many recipients at once, see the WhatsApp bulk messaging API.
Contents
Base URL
https://wasaas.org/api/v1Auth Header
Authorization: Bearer wsa_…Quick Start
Send your first WhatsApp message in 3 steps.
Connect a WhatsApp session
Go to Sessions → click Add Session → scan the QR code with your WhatsApp app. Once connected, copy the Session ID shown in the sessions table.
Create an API key
Go to API Keys → click New Key → copy the key (it starts with wsa_). Store it securely — it won't be shown again.
Send a message
curl -X POST https://wasaas.org/api/v1/messages \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"session_id": "customer-5-1",
"to": "966501234567",
"message": "Hello from Wasaas!"
}'{ "success": true, "to": "966501234567", "status": "sent" }What is a Session ID?
A Session ID is the unique identifier for a connected WhatsApp number in your account. Every WhatsApp number you connect through Wasaas gets its own session with a unique ID. You use this ID in every API call to specify which WhatsApp number should send or receive messages.
Session ID Format
WHERE TO FIND YOUR SESSION ID
- 1. Open the Sessions page in your dashboard
- 2. Each connected WhatsApp number shows its Session ID in the table
- 3. Or call
GET /api/v1/sessionswith your API key — it returns all session IDs
Get Session IDs via API
curl https://wasaas.org/api/v1/sessions \
-H "Authorization: Bearer wsa_your_api_key"Response
[
{
"session_id": "customer-5-1",
"phone": "+966501234567",
"status": "connected",
"created_at": "2026-05-01T10:00:00.000Z"
},
{
"session_id": "customer-5-2",
"phone": "+201012345678",
"status": "connected",
"created_at": "2026-05-10T09:00:00.000Z"
}
]Authentication
Every API request must include your API key in the Authorization header as a Bearer token. Create API keys on the API Keys page.
Authorization: Bearer wsa_your_api_key_here| Header | Value | Required |
|---|---|---|
| Authorization | Bearer wsa_your_api_key | Yes |
| Content-Type | application/json | Yes (POST requests) |
Keep your API key secret. Never include it in client-side JavaScript, mobile apps, or public repositories. If a key is compromised, delete it and create a new one immediately.
Sessions API
https://wasaas.org/api/v1/sessionsReturns all WhatsApp sessions (connected numbers) for your account. Use this to discover available session_id values before sending messages.
curl https://wasaas.org/api/v1/sessions \
-H "Authorization: Bearer wsa_your_api_key"Response
[
{
"session_id": "customer-5-1",
"phone": "+966501234567",
"status": "connected",
"created_at": "2026-05-01T10:00:00.000Z"
}
]Session Status Values
| Status | Meaning | Can Send? |
|---|---|---|
| connected | Session is active and authenticated | ✅ Yes |
| qr_pending | Waiting for QR code scan | ❌ No |
| disconnected | Session lost connection — rescan QR to reconnect | ❌ No |
| not_started | Session exists but never connected | ❌ No |
| error | Session encountered an error | ❌ No |
Send Text Message
https://wasaas.org/api/v1/messagesSend a plain text message to any WhatsApp number. The session must have status connected.
Request Body
{
"session_id": "customer-5-1",
"to": "966501234567",
"message": "Hello from Wasaas!"
}| Field | Type | Required | Description |
|---|---|---|---|
| session_id | string | Yes | Your WhatsApp session ID (e.g. customer-5-1) — get it from GET /api/v1/sessions |
| to | string | Yes | Recipient phone number — digits only, include country code (e.g. 966501234567 for Saudi Arabia) |
| message | string | Yes | Text content of the message (max 4096 characters) |
Phone number format
Use digits only with country code. No spaces, dashes, or + prefix. Examples: 966501234567 (Saudi Arabia), 201012345678 (Egypt), 12125551234 (USA)
Code Examples
curl -X POST https://wasaas.org/api/v1/messages \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"session_id": "customer-5-1",
"to": "966501234567",
"message": "Hello from Wasaas!"
}'Response
{ "success": true, "to": "966501234567", "status": "sent" }Send Image
https://wasaas.org/api/v1/messages/imageSend an image to a WhatsApp number via a public URL. Supports JPEG, PNG, GIF, and WebP.
Request Body
{
"session_id": "customer-5-1",
"to": "966501234567",
"image_url": "https://example.com/photo.jpg",
"caption": "Check out this photo!"
}| Field | Type | Required | Description |
|---|---|---|---|
| session_id | string | Yes | Your WhatsApp session ID |
| to | string | Yes | Recipient phone number (digits + country code) |
| image_url | string | Yes | Publicly accessible URL of the image (JPEG, PNG, GIF, WebP) |
| caption | string | Optional | Caption text shown below the image |
Examples
curl -X POST https://wasaas.org/api/v1/messages/image \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"session_id": "customer-5-1",
"to": "966501234567",
"image_url": "https://example.com/photo.jpg",
"caption": "Check this out!"
}'Response
{ "success": true, "to": "966501234567", "status": "sent" }Send Document
https://wasaas.org/api/v1/messages/documentSend a file (PDF, Word, Excel, etc.) as a Base64-encoded string.
Request Body
{
"session_id": "customer-5-1",
"to": "966501234567",
"base64": "JVBERi0xLjQKJeLjz9MK...",
"filename": "invoice.pdf",
"mime": "application/pdf",
"caption": "Your invoice is attached"
}| Field | Type | Required | Description |
|---|---|---|---|
| session_id | string | Yes | Your WhatsApp session ID |
| to | string | Yes | Recipient phone number |
| base64 | string | Yes | File content encoded as Base64 |
| filename | string | Yes | Name of the file as it appears in WhatsApp (e.g. invoice.pdf) |
| mime | string | Yes | MIME type of the file (e.g. application/pdf, application/vnd.ms-excel) |
| caption | string | Optional | Optional caption below the document |
Common MIME Types
| File Type | MIME Type |
|---|---|
| application/pdf | |
| Word (.docx) | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| Excel (.xlsx) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| Plain text | text/plain |
Example
# Convert a file to base64 and send it
BASE64=$(base64 -w 0 invoice.pdf)
curl -X POST https://wasaas.org/api/v1/messages/document \
-H "Authorization: Bearer wsa_your_api_key" \
-H "Content-Type: application/json" \
-d "{
\"session_id\": \"customer-5-1\",
\"to\": \"966501234567\",
\"base64\": \"$BASE64\",
\"filename\": \"invoice.pdf\",
\"mime\": \"application/pdf\",
\"caption\": \"Your invoice\"
}"Response
{ "success": true, "to": "966501234567", "status": "sent" }Send Bulk Messages
https://wasaas.org/api/v1/messages/bulkSend one message to many recipients in a single call — up to 500 per request. Messages are sent sequentially with a randomised pause between each one, which is what keeps a campaign from looking like automated spam to WhatsApp. Because the request waits for every send to finish, expect it to stay open for a while on long lists.
Request Body
{
"session_id": "customer-5-1",
"recipients": ["966501234567", "201012345678"],
"message": "Our new collection is live!",
"min_delay": 3,
"max_delay": 8
}min_delay and max_delay are seconds between sends (1–300, defaulting to 3 and 8). min_delay must not exceed max_delay. Each recipient counts against your plan's monthly message quota; if the quota runs out mid-run, the remaining recipients come back as failed rather than silently stopping.
Pacing guidance, quota behaviour and practical batch sizing are covered on the WhatsApp bulk messaging API page.
Response
{
"sent": 1,
"failed": 1,
"results": [
{ "to": "966501234567", "status": "sent" },
{ "to": "201012345678", "status": "failed", "error": "Message quota exceeded" }
]
}Check WhatsApp Number
https://wasaas.org/api/v1/check-numberVerify whether a phone number has an active WhatsApp account before sending. Useful to clean contact lists.
Request Body
{
"session_id": "customer-5-1",
"phone": "966501234567"
}Response
{ "has_whatsapp": true, "reason": "registered" }
// or
{ "has_whatsapp": false, "reason": "not_registered" }This body is returned as-is from the WhatsApp service, so treat has_whatsapp as the field to branch on and reason as informational.
Chatbot Flows — Incoming Webhook
https://wasaas.org/api/v1/incomingThis endpoint is called by your WhatsApp service when a contact sends a message. It runs the chatbot flow engine: matches the message to a trigger keyword, starts a conversation, and sends the first reply automatically. On each subsequent reply, it advances to the next step and saves the full conversation history.
Trigger matching, conversation stepping and the inbound direction are explained on the WhatsApp chatbot API page. To create, edit and publish the flows and steps themselves via API — not just receive this webhook — see the WhatsApp chatbot flow API.
Configure your flows first on the Chatbot Flows page, then point your WhatsApp service to this URL. Full conversation history is viewable on the Conversations page.
Request Body
{
"session_id": "customer-5-1",
"from": "966501234567",
"body": "hi"
}| Field | Type | Description |
|---|---|---|
| session_id | string | The WhatsApp session that received the message |
| from | string | Sender's phone number (digits only, with country code) |
| body | string | The text content of the incoming message |
Flow Engine Behavior
| Scenario | What happens |
|---|---|
| Message matches a flow trigger | New conversation created → Step 1 sent → conversation status: active |
| Contact replies to active conversation | Step 2 sent → current_step advances → { success: true } |
| Contact sends last step's reply | Final step sent → conversation status: completed |
| Message matches trigger = "any" | Any incoming message from a new contact starts the flow |
| No matching trigger found | Message ignored → { success: true, matched: false } |
Example — millisave_js integration
// In your WhatsApp service, add to client.on('message', ...):
const fetch = require('node-fetch');
client.on('message', async (msg) => {
if (msg.fromMe) return;
await fetch('https://wasaas.org/api/v1/incoming', {
method: 'POST',
headers: {
'Authorization': 'Bearer wsa_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
session_id: companyId, // e.g. "customer-5-1"
from: msg.from.replace('@c.us', ''),
body: msg.body,
}),
});
});Response
// Flow triggered
{ "success": true, "matched": true, "flow": "Welcome Flow" }
// No matching flow
{ "success": true, "matched": false }
// Conversation advanced
{ "success": true }Rate Limits
Limits apply per billing cycle and reset on the first day of each cycle.
| Plan | Messages / mo | API Calls / mo | Sessions |
|---|---|---|---|
| Starter | 5,000 | 5,000 | 2 |
| Business | 20,000 | 20,000 | 5 |
| Enterprise | Unlimited | Unlimited | Unlimited |
When a limit is reached the API returns 429 Too Many Requests. Upgrade your plan from the Billing page.
Error Codes
| HTTP Code | Error | Fix |
|---|---|---|
| 401 | Invalid or missing API key | Check the Authorization header starts with Bearer wsa_... |
| 400 | Validation error — invalid request body | Check all required fields are present and correct types |
| 404 | Session not found | Verify the session_id exists via GET /api/v1/sessions |
| 429 | Quota exceeded for your plan | Upgrade your plan or wait for the next billing cycle |
| 500 | WhatsApp failed to deliver the message | Check session status is 'connected'. Rescan QR if needed |
Error Response Shape
{
"error": "Session not found",
"detail": "No session with ID customer-5-1 belongs to your account"
}