● REST API · WhatsApp Messaging

WASender
API Reference

A queued WhatsApp messaging backend. Send text, images, PDFs, bills, gym notifications, and OTPs — all processed in FIFO order to respect provider rate limits.

Base URL: https://whatsapp.microace.cloud
Protocol: HTTPS ¡ REST
Auth: Bearer Token

Introduction

All messaging requests are accepted immediately (HTTP 202) and placed in a FIFO queue. Messages are dispatched sequentially with a configurable delay between sends to prevent rate-limiting by the WhatsApp provider.

Queue Delay
5,000ms
Between consecutive sends
Send Timeout
20,000ms
Per provider request
Max File Size
50 MB
PDF and image uploads
OTP TTL
300s
5 max verification attempts

API Keys

All endpoints accept an API key either via the apiKey field in the request body, or via the server environment variable WASENDER_API_KEY. The body field takes precedence.

💡
If your server is pre-configured with the environment variable, you can omit apiKey from all requests. Per-request keys are useful when routing to multiple WASender accounts.
Example — body-level key
{
  "to": "919876543210",
  "message": "Hello!",
  "apiKey": "wsk_your_api_key_here"
}

Queue System

Every message endpoint returns HTTP 202 immediately with a job object. Track your job's progress using the /queue/jobs/:jobId endpoint.

Job Lifecycle

Status flow
queued  →  processing  →  completed
                              ↘  failed

202 Response Shape (all messaging endpoints)

JSON — 202 Accepted
{
  "success": true,
  "queued": true,
  "message": "Request accepted and added to the FIFO queue",
  "job": {
    "id": "3f7c1a2b-...",
    "route": "/send-message",
    "to": "919876543210",
    "status": "queued",
    "createdAt": "2025-01-15T10:30:00.000Z",
    "jobsAhead": 2,
    "estimatedWaitMs": 10000
  },
  "queue": {
    "processing": true,
    "totalInSystem": 3,
    "delayMsBetweenMessages": 5000,
    "statusEndpoint": "/queue/jobs/3f7c1a2b-..."
  }
}

Error Handling

Validation errors return synchronously before queuing. Provider errors are captured in the job object after processing.

Status Meaning When
200 OK OTP verification success, health/queue reads
202 Accepted Message accepted into queue
400 Bad Request Missing or invalid fields, expired/wrong OTP
409 Conflict OTP already queued for this number
429 Too Many Requests OTP rate limit (60s cooldown)
500 Server Error Missing API key, internal failure

Messaging

POST
/send-message
Send a custom text message, optionally with an image or document URL
â–ļ
â„šī¸
Content-Type: application/x-www-form-urlencoded or application/json. No file uploads on this endpoint.

Parameters

FieldTypeRequiredDescription
to string REQUIRED Recipient phone number (digits only, 7–15 chars). Include country code, no +.
message string REQUIRED Text body of the message. Also accepted as text.
imageUrl string OPTIONAL A valid HTTP(S) URL to an image to attach.
documentUrl string OPTIONAL A valid HTTP(S) URL to a document to send.
fileName string OPTIONAL Display name for the document. Auto-guessed from URL if omitted.
apiKey string OPTIONAL WASender API key. Falls back to server env var.

Request Example

cURL
curl -X POST https://whatsapp.microace.cloud/send-message   -H "Content-Type: application/json"   -d '{
    "to": "919876543210",
    "message": "Hello from WASender!",
    "imageUrl": "https://example.com/banner.jpg"
  }'
{
  "success": true,
  "queued": true,
  "job": { "id": "...", "status": "queued", "jobsAhead": 0 }
}
{ "error": ""message" is required" }
POST
/send-bill
Send a branded bill/receipt message with a hosted image to a customer
â–ļ
🧾
The message text is auto-generated in the Taste 'N' Bite brand voice. A static banner image is automatically attached from the server config.

Parameters

FieldTypeRequiredDescription
to string REQUIRED Customer phone number.
name string REQUIRED Customer's first name, used in the greeting.
url string REQUIRED Public URL to the bill/invoice PDF or page.
caption string OPTIONAL Extra text prepended to the auto-generated bill message.
apiKey string OPTIONAL WASender API key.

Request Example

cURL
curl -X POST https://whatsapp.microace.cloud/send-bill   -H "Content-Type: application/json"   -d '{
    "to": "919876543210",
    "name": "Priya",
    "url": "https://bills.example.com/inv-4521.pdf"
  }'
{
  "success": true,
  "queued": true,
  "preview": { "imageUrl": "https://i.ibb.co/..." },
  "job": { "id": "...", "status": "queued" }
}
{ "error": "Missing required fields: to, name, url" }
POST
/send-gym
Send a gym birthday message with optional custom image and/or PDF document
â–ļ
â„šī¸
Content-Type: multipart/form-data (supports file uploads). Fields: image (jpeg/png/gif/webp) and document (PDF).

Parameters

FieldTypeRequiredDescription
to string REQUIRED Recipient phone number.
name string REQUIRED Member's name for the birthday message greeting.
message string OPTIONAL Custom message text. If omitted, a default birthday message is used. Also accepted as text.
image file OPTIONAL Image file (jpeg/jpg/png/gif/webp). If omitted, default gym image is used.
document file OPTIONAL PDF document to attach (e.g. membership card, diet plan).
apiKey string OPTIONAL WASender API key.

Request Example

cURL — with file upload
curl -X POST https://whatsapp.microace.cloud/send-gym   -F "to=919876543210"   -F "name=Rahul"   -F "image=@/path/to/birthday.jpg"   -F "document=@/path/to/membership.pdf"
{
  "success": true,
  "queued": true,
  "files": {
    "imageUrl": "https://whatsapp.microace.cloud/uploads/birthday-...",
    "documentUrl": "https://whatsapp.microace.cloud/uploads/membership-..."
  },
  "job": { "id": "...", "status": "queued" }
}
{ "error": "Missing required fields: to and name" }

PDF Sending

POST
/send-pdf
Upload a PDF, store it on the server, and send it with a message
â–ļ
âš ī¸
Content-Type: Must be multipart/form-data. Only the first uploaded PDF is used; additional files are discarded. Max 50MB.

Parameters

FieldTypeRequiredDescription
to string REQUIRED Recipient phone number.
message string REQUIRED Caption/message sent alongside the PDF.
[any field] file REQUIRED A PDF file in any field. Only PDFs accepted.
apiKey string OPTIONAL WASender API key.

Request Example

cURL
curl -X POST https://whatsapp.microace.cloud/send-pdf   -F "to=919876543210"   -F "message=Please find your report attached."   -F "file=@/path/to/report.pdf"
{
  "success": true,
  "queued": true,
  "uploaded": {
    "fileName": "report.pdf",
    "fileUrl": "https://whatsapp.microace.cloud/uploads/report-..."
  },
  "ignoredFiles": 0,
  "link": "https://whatsapp.microace.cloud/uploads/report-...",
  "job": { "id": "...", "status": "queued" }
}
{ "error": "A PDF file is required." }
POST
/send-gym-pdf
Upload and send a PDF document — simplified gym-specific variant with optional caption
â–ļ

Parameters

FieldTypeRequiredDescription
to string REQUIRED Recipient phone number.
pdf / file / document file REQUIRED PDF file. Accepted in any of these field names.
message string OPTIONAL Text caption sent with the PDF. Also accepted as text.
apiKey string OPTIONAL WASender API key.

Request Example

cURL
curl -X POST https://whatsapp.microace.cloud/send-gym-pdf   -F "to=919876543210"   -F "message=Your diet plan for this month!"   -F "pdf=@/path/to/diet-plan.pdf"
{
  "success": true,
  "queued": true,
  "fileUrl": "https://whatsapp.microace.cloud/uploads/diet-plan-...",
  "link": "https://whatsapp.microace.cloud/uploads/diet-plan-...",
  "job": { "id": "...", "status": "queued" }
}

One-Time Passwords

POST
/send-otp
Generate and send a 6-digit OTP via WhatsApp (60s rate limit per number)
â–ļ
OTP Length
6 digits
Cryptographically random
Expiry
300s
5 min ¡ 5 max attempts

Parameters

FieldTypeRequiredDescription
to string REQUIRED Phone number to deliver the OTP to.
apiKey string OPTIONAL WASender API key.

Request Example

cURL
curl -X POST https://whatsapp.microace.cloud/send-otp   -H "Content-Type: application/json"   -d '{ "to": "919876543210" }'
{
  "success": true,
  "queued": true,
  "job": { "id": "...", "status": "queued", "route": "/send-otp" }
}
{ "error": "An OTP request for this number is already queued or processing" }
{
  "error": "Rate limit",
  "message": "Wait 42 seconds"
}
POST
/verify-otp
Verify an OTP submitted by the user — synchronous, no queue
â–ļ
🔐
After 5 failed attempts, the OTP is invalidated and a new one must be requested. OTPs also auto-expire after 300 seconds.

Parameters

FieldTypeRequiredDescription
to string REQUIRED Phone number the OTP was sent to.
otp string REQUIRED The 6-digit OTP entered by the user.

Request Example

cURL
curl -X POST https://whatsapp.microace.cloud/verify-otp   -H "Content-Type: application/json"   -d '{ "to": "919876543210", "otp": "482910" }'
{ "success": true, "message": "OTP verified" }
{
  "success": false,
  "message": "Invalid OTP. 4 attempt(s) left."
}
{ "success": false, "message": "OTP expired" }

Health & Queue

GET
/health
Server health check — returns queue state and active OTP count
â–ļ

Response

JSON — 200 OK
{
  "success": true,
  "status": "ok",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "queue": {
    "processing": false,
    "coolingDown": true,
    "cooldownRemainingMs": 2400,
    "pendingCount": 1,
    "delayMsBetweenMessages": 5000
  },
  "otp": {
    "activeEntries": 2
  }
}
GET
/queue
Full queue inspection — active job, pending jobs, and last 20 completed jobs
â–ļ

Response

JSON — 200 OK
{
  "success": true,
  "queue": {
    "processing": true,
    "activeJob": { "id": "...", "status": "processing", "to": "91..." },
    "pendingCount": 2,
    "trackedJobs": 14
  },
  "pendingJobs": [ /* job objects */ ],
  "recentJobs": [ /* last 20 completed/failed */ ]
}
GET
/queue/jobs/:jobId
Poll the status of a specific queued or completed job by its ID
â–ļ

Path Parameters

ParamTypeDescription
jobId string UUID returned when the message was queued.
{
  "success": true,
  "job": {
    "id": "3f7c1a2b-...",
    "route": "/send-message",
    "to": "919876543210",
    "status": "completed",
    "createdAt": "2025-01-15T10:30:00.000Z",
    "startedAt": "2025-01-15T10:30:05.000Z",
    "completedAt": "2025-01-15T10:30:05.800Z",
    "jobsAhead": null,
    "providerStatus": 200,
    "providerData": { /* WASender response */ },
    "error": null
  }
}
{ "error": "Job not found" }