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.

Quick Start

Send your first WhatsApp message in 3 steps.

1

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.

Session ID example: customer-5-1
2

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.

API key example: wsa_a1b2c3d4e5f6...
3

Send a message

bash
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!"
  }'
json
{ "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

customer-5-1
Fixed prefix
Your customer ID (from dashboard)
Session number (1st, 2nd… session)

WHERE TO FIND YOUR SESSION ID

  1. 1. Open the Sessions page in your dashboard
  2. 2. Each connected WhatsApp number shows its Session ID in the table
  3. 3. Or call GET /api/v1/sessions with your API key — it returns all session IDs

Get Session IDs via API

bash
curl https://wasaas.org/api/v1/sessions \
  -H "Authorization: Bearer wsa_your_api_key"

Response

json
[
  {
    "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.

http
Authorization: Bearer wsa_your_api_key_here
HeaderValueRequired
AuthorizationBearer wsa_your_api_keyYes
Content-Typeapplication/jsonYes (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

GEThttps://wasaas.org/api/v1/sessions

Returns all WhatsApp sessions (connected numbers) for your account. Use this to discover available session_id values before sending messages.

bash
curl https://wasaas.org/api/v1/sessions \
  -H "Authorization: Bearer wsa_your_api_key"

Response

json
[
  {
    "session_id": "customer-5-1",
    "phone": "+966501234567",
    "status": "connected",
    "created_at": "2026-05-01T10:00:00.000Z"
  }
]

Session Status Values

StatusMeaningCan Send?
connectedSession is active and authenticated✅ Yes
qr_pendingWaiting for QR code scan❌ No
disconnectedSession lost connection — rescan QR to reconnect❌ No
not_startedSession exists but never connected❌ No
errorSession encountered an error❌ No

Send Text Message

POSThttps://wasaas.org/api/v1/messages

Send a plain text message to any WhatsApp number. The session must have status connected.

Request Body

json
{
  "session_id": "customer-5-1",
  "to": "966501234567",
  "message": "Hello from Wasaas!"
}
FieldTypeRequiredDescription
session_idstringYesYour WhatsApp session ID (e.g. customer-5-1) — get it from GET /api/v1/sessions
tostringYesRecipient phone number — digits only, include country code (e.g. 966501234567 for Saudi Arabia)
messagestringYesText 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

bash
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

json
{ "success": true, "to": "966501234567", "status": "sent" }

Send Image

POSThttps://wasaas.org/api/v1/messages/image

Send an image to a WhatsApp number via a public URL. Supports JPEG, PNG, GIF, and WebP.

Request Body

json
{
  "session_id": "customer-5-1",
  "to": "966501234567",
  "image_url": "https://example.com/photo.jpg",
  "caption": "Check out this photo!"
}
FieldTypeRequiredDescription
session_idstringYesYour WhatsApp session ID
tostringYesRecipient phone number (digits + country code)
image_urlstringYesPublicly accessible URL of the image (JPEG, PNG, GIF, WebP)
captionstringOptionalCaption text shown below the image

Examples

bash
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

json
{ "success": true, "to": "966501234567", "status": "sent" }

Send Document

POSThttps://wasaas.org/api/v1/messages/document

Send a file (PDF, Word, Excel, etc.) as a Base64-encoded string.

Request Body

json
{
  "session_id": "customer-5-1",
  "to": "966501234567",
  "base64": "JVBERi0xLjQKJeLjz9MK...",
  "filename": "invoice.pdf",
  "mime": "application/pdf",
  "caption": "Your invoice is attached"
}
FieldTypeRequiredDescription
session_idstringYesYour WhatsApp session ID
tostringYesRecipient phone number
base64stringYesFile content encoded as Base64
filenamestringYesName of the file as it appears in WhatsApp (e.g. invoice.pdf)
mimestringYesMIME type of the file (e.g. application/pdf, application/vnd.ms-excel)
captionstringOptionalOptional caption below the document

Common MIME Types

File TypeMIME Type
PDFapplication/pdf
Word (.docx)application/vnd.openxmlformats-officedocument.wordprocessingml.document
Excel (.xlsx)application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Plain texttext/plain

Example

bash
# 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

json
{ "success": true, "to": "966501234567", "status": "sent" }

Send Bulk Messages

POSThttps://wasaas.org/api/v1/messages/bulk

Send 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

json
{
  "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

json
{
  "sent": 1,
  "failed": 1,
  "results": [
    { "to": "966501234567", "status": "sent" },
    { "to": "201012345678", "status": "failed", "error": "Message quota exceeded" }
  ]
}

Check WhatsApp Number

POSThttps://wasaas.org/api/v1/check-number

Verify whether a phone number has an active WhatsApp account before sending. Useful to clean contact lists.

Request Body

json
{
  "session_id": "customer-5-1",
  "phone": "966501234567"
}

Response

json
{ "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

POSThttps://wasaas.org/api/v1/incoming

This 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

json
{
  "session_id": "customer-5-1",
  "from": "966501234567",
  "body": "hi"
}
FieldTypeDescription
session_idstringThe WhatsApp session that received the message
fromstringSender's phone number (digits only, with country code)
bodystringThe text content of the incoming message

Flow Engine Behavior

ScenarioWhat happens
Message matches a flow triggerNew conversation created → Step 1 sent → conversation status: active
Contact replies to active conversationStep 2 sent → current_step advances → { success: true }
Contact sends last step's replyFinal step sent → conversation status: completed
Message matches trigger = "any"Any incoming message from a new contact starts the flow
No matching trigger foundMessage ignored → { success: true, matched: false }

Example — millisave_js integration

javascript
// 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

json
// 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.

PlanMessages / moAPI Calls / moSessions
Starter5,0005,0002
Business20,00020,0005
EnterpriseUnlimitedUnlimitedUnlimited

When a limit is reached the API returns 429 Too Many Requests. Upgrade your plan from the Billing page.

Error Codes

HTTP CodeErrorFix
401Invalid or missing API keyCheck the Authorization header starts with Bearer wsa_...
400Validation error — invalid request bodyCheck all required fields are present and correct types
404Session not foundVerify the session_id exists via GET /api/v1/sessions
429Quota exceeded for your planUpgrade your plan or wait for the next billing cycle
500WhatsApp failed to deliver the messageCheck session status is 'connected'. Rescan QR if needed

Error Response Shape

json
{
  "error": "Session not found",
  "detail": "No session with ID customer-5-1 belongs to your account"
}