WhatsApp automation for growing businesses
whatsapp.cubicsofts.ae
API documentation

Build on a plain HTTP API

One endpoint sends text, images and documents, immediately or on a schedule. Any language that can make an HTTP request can use it — there is no SDK to install.

API key auth GET or POST JSON responses Signed webhooks
Base URL
https://whatsapp.cubicsofts.ae/api

Authentication

Every request carries your api_key as a query or form parameter. There is no Authorization header and no token exchange.

Your API key can send messages from your WhatsApp number. Keep it server-side — never ship it in a mobile app, a browser bundle, or a public repository. If it leaks, revoke it from the dashboard and issue a new one.
1

Create an instance

Add a WhatsApp number in the dashboard.

2

Scan the QR code

Link the number from WhatsApp on your phone.

3

Copy your key

Shown once at creation. Store it somewhere safe.

GET | POST /api/send

Send a text message

The default message type. Delivers a plain text WhatsApp message from your connected number.

Parameters

NameTypeRequiredDescription
api_key string <span class="cs-pill cs-pill-failed">Yes</span> Your instance API key. Sent as a query or form parameter, not a header.
mobile string <span class="cs-pill cs-pill-failed">Yes</span> Recipient in international format without a leading +, e.g. 971501234567. Local formats with a leading 0 are rejected — we cannot guess the country.
message string <span class="cs-pill cs-pill-failed">Yes</span> The message body.
priority number <span class="cs-pill cs-pill-queued">No</span> Queue priority, 0 (most urgent) to 300. Defaults to 10. Values of 40 and above also delay the message by that many seconds.
reference string <span class="cs-pill cs-pill-queued">No</span> Your own identifier. Stored with the message and echoed back in every webhook for this message.

Example request

curl -X POST 'https://whatsapp.cubicsofts.ae/api/send' \
  --data-urlencode 'api_key=YOUR_API_KEY' \
  --data-urlencode 'mobile=971501234567' \
  --data-urlencode 'message=Your order has shipped'

Response

200 OK
{
  "success": "true",
  "message_id": "3f9a1c2e-7b64-4f1a-9d0e-5c8a2b41d7e3",
  "totalprice": "1",
  "remaincredit": "998",
  "results": [
    {
      "status": "queued"
    }
  ]
}
Error
{
  "success": "false",
  "results": [
    {
      "error": "Invalid API KEY!"
    }
  ]
}
GET | POST /api/send

Send an image

Set type=1 and supply either a publicly reachable url or an uploaded file. Supported: jpg, jpeg, png, gif, webp, bmp. Maximum 3 MB.

The URL must be reachable from our servers. Links behind a login or a firewall will fail.

Parameters

NameTypeRequiredDescription
api_key string <span class="cs-pill cs-pill-failed">Yes</span> Your instance API key. Sent as a query or form parameter, not a header.
mobile string <span class="cs-pill cs-pill-failed">Yes</span> Recipient number.
type number <span class="cs-pill cs-pill-failed">Yes</span> Set to 1 for an image.
url string <span class="cs-pill cs-pill-queued">No</span> Public URL of the image. Required unless you upload a file.
file file <span class="cs-pill cs-pill-queued">No</span> Multipart file upload. Use instead of url.
caption string <span class="cs-pill cs-pill-queued">No</span> Caption shown under the image.
priority number <span class="cs-pill cs-pill-queued">No</span> Queue priority, 0–300.

Example request

curl -X POST 'https://whatsapp.cubicsofts.ae/api/send' \
  --data-urlencode 'api_key=YOUR_API_KEY' \
  --data-urlencode 'mobile=971501234567' \
  --data-urlencode 'type=1' \
  --data-urlencode 'url=https://example.com/receipt.jpg' \
  --data-urlencode 'caption=Your receipt'

Response

200 OK
{
  "success": "true",
  "message_id": "8c2d5e10-45ab-4c3f-91b7-2ea6f0c9d114",
  "remaincredit": "997",
  "results": [
    {
      "status": "queued"
    }
  ]
}
GET | POST /api/send

Send a document

Set type=2 for a document. Most common extensions are supported — pdf, docx, xlsx, csv, pptx, zip. Maximum 3 MB.

Parameters

NameTypeRequiredDescription
api_key string <span class="cs-pill cs-pill-failed">Yes</span> Your instance API key. Sent as a query or form parameter, not a header.
mobile string <span class="cs-pill cs-pill-failed">Yes</span> Recipient number.
type number <span class="cs-pill cs-pill-failed">Yes</span> Set to 2 for a document.
url string <span class="cs-pill cs-pill-queued">No</span> Public URL of the document.
file file <span class="cs-pill cs-pill-queued">No</span> Multipart file upload.
filename string <span class="cs-pill cs-pill-queued">No</span> Name the recipient sees. Defaults to the name in the URL.
priority number <span class="cs-pill cs-pill-queued">No</span> Queue priority, 0–300.

Example request

curl -X POST 'https://whatsapp.cubicsofts.ae/api/send' \
  --data-urlencode 'api_key=YOUR_API_KEY' \
  --data-urlencode 'mobile=971501234567' \
  --data-urlencode 'type=2' \
  --data-urlencode 'url=https://example.com/invoice-4521.pdf' \
  --data-urlencode 'filename=invoice-4521.pdf'

Response

200 OK
{
  "success": "true",
  "message_id": "b1e77a3c-90d4-4a15-8f22-6c0b9e3d5a48",
  "remaincredit": "996",
  "results": [
    {
      "status": "queued"
    }
  ]
}
GET | POST /api/send

Schedule a message

Add schedule=1 and a datetime to hold the message until a specific moment. A scheduled time overrides any delay implied by priority.

A datetime in the past sends immediately rather than failing, which is usually what you want for a near-miss schedule.

Parameters

NameTypeRequiredDescription
api_key string <span class="cs-pill cs-pill-failed">Yes</span> Your instance API key. Sent as a query or form parameter, not a header.
mobile string <span class="cs-pill cs-pill-failed">Yes</span> Recipient number.
message string <span class="cs-pill cs-pill-failed">Yes</span> The message body.
schedule number <span class="cs-pill cs-pill-failed">Yes</span> Set to 1 to schedule.
datetime string <span class="cs-pill cs-pill-failed">Yes</span> When to send, as YYYY-MM-DD HH:MM:SS or an ISO 8601 timestamp. Interpreted as UTC unless an offset is given.

Example request

curl -X POST 'https://whatsapp.cubicsofts.ae/api/send' \
  --data-urlencode 'api_key=YOUR_API_KEY' \
  --data-urlencode 'mobile=971501234567' \
  --data-urlencode 'message=Reminder: your appointment is tomorrow at 10:00' \
  --data-urlencode 'schedule=1' \
  --data-urlencode 'datetime=2026-09-15 09:00:00'

Response

200 OK
{
  "success": "true",
  "message_id": "d4c8f2a6-1b39-4e7d-a05c-83f1b6e2c907",
  "results": [
    {
      "status": "scheduled",
      "send_at": "2026-09-15T09:00:00Z"
    }
  ]
}
GET /api/status

Check instance status

Returns whether your WhatsApp number is currently connected. Useful as a pre-flight check before a batch, and as a monitoring endpoint.

Parameters

NameTypeRequiredDescription
api_key string <span class="cs-pill cs-pill-failed">Yes</span> Your instance API key. Sent as a query or form parameter, not a header.

Example request

curl "https://whatsapp.cubicsofts.ae/api/status?api_key=YOUR_API_KEY"

Response

200 OK
{
  "success": "true",
  "results": [
    {
      "status": "connected",
      "phone_number": "971501234567",
      "connected_at": "2026-08-28T11:04:22Z",
      "messages_today": 42,
      "daily_limit": 250
    }
  ]
}
GET /api/messages

Query delivery reports

Look up the status of messages you have sent, by id or over a date range. This is the delivery report, in API form.

Parameters

NameTypeRequiredDescription
api_key string <span class="cs-pill cs-pill-failed">Yes</span> Your instance API key. Sent as a query or form parameter, not a header.
message_id string <span class="cs-pill cs-pill-queued">No</span> Fetch one message. Omit to list.
status string <span class="cs-pill cs-pill-queued">No</span> Filter: queued, sent, delivered, read, failed.
from string <span class="cs-pill cs-pill-queued">No</span> Start of range, YYYY-MM-DD.
to string <span class="cs-pill cs-pill-queued">No</span> End of range, YYYY-MM-DD.
limit number <span class="cs-pill cs-pill-queued">No</span> Rows to return, 1–200. Default 50.

Example request

curl "https://whatsapp.cubicsofts.ae/api/messages?api_key=YOUR_API_KEY&status=failed&limit=20"

Response

200 OK
{
  "success": "true",
  "count": 1,
  "results": [
    {
      "message_id": "3f9a1c2e-7b64-4f1a-9d0e-5c8a2b41d7e3",
      "mobile": "971501234567",
      "status": "delivered",
      "sent_at": "2026-08-29T08:15:02Z",
      "delivered_at": "2026-08-29T08:15:04Z",
      "reference": "order-4521"
    }
  ]
}
POST /api/v1/integrations/orders/YOUR_SECRET

Trigger order confirmation (Next.js / Custom)

Direct REST endpoint to trigger an automated WhatsApp order confirmation from Next.js server actions, API routes, or backend systems.

WooCommerce and Shopify webhooks are also fully supported with zero code by pasting your template delivery URL into their webhook settings.
Placeholders in your message template (like {{customer_name}}, {{order_id}}, {{items}}) are dynamically replaced in real time.

Parameters

NameTypeRequiredDescription
phone string <span class="cs-pill cs-pill-failed">Yes</span> Customer mobile number (with or without international prefix).
customerName string <span class="cs-pill cs-pill-queued">No</span> Customer full name (replaces {{customer_name}}).
orderId string <span class="cs-pill cs-pill-failed">Yes</span> Order reference number (replaces {{order_id}}).
orderTotal string <span class="cs-pill cs-pill-queued">No</span> Total order amount (replaces {{order_total}}).
currency string <span class="cs-pill cs-pill-queued">No</span> Currency code, e.g. AED, USD, PKR (replaces {{currency}}).
items string <span class="cs-pill cs-pill-queued">No</span> Summary of order items, e.g. "2x T-Shirt" (replaces {{items}}).
storeName string <span class="cs-pill cs-pill-queued">No</span> Store display name (replaces {{store_name}}).
shippingAddress string <span class="cs-pill cs-pill-queued">No</span> Customer shipping address (replaces {{shipping_address}}).

Example request

curl -X POST 'https://whatsapp.cubicsofts.ae/api/v1/integrations/orders/YOUR_SECRET' \
  --data-urlencode 'phone=971501234567' \
  --data-urlencode 'customerName=John Doe' \
  --data-urlencode 'orderId=ORD-1092' \
  --data-urlencode 'orderTotal=199.00' \
  --data-urlencode 'currency=AED' \
  --data-urlencode 'items=1x Wireless Headphones' \
  --data-urlencode 'storeName=ElectroStore' \
  --data-urlencode 'shippingAddress=Downtown Dubai, UAE'

Response

200 OK
{
  "success": true,
  "status": "sent",
  "orderId": "ORD-1092",
  "recipient": "971501234567",
  "messageUuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

Webhooks

Register an endpoint in the dashboard and we POST JSON to it when something happens. Failed deliveries are retried with exponential backoff.

Events

EventFires when
message.sent The message left the gateway and WhatsApp accepted it.
message.delivered The recipient's device acknowledged receipt.
message.read The recipient opened the chat, if read receipts are on.
message.failed Delivery failed. The payload carries the reason.
message.received A customer sent you a message.
instance.connected Your number finished linking.
instance.disconnected The session dropped. Usually transient.
instance.qr A new QR code is waiting to be scanned.

Verifying the signature

Each request carries an X-Signature header: the HMAC-SHA256 of the raw request body, keyed with your webhook secret, hex encoded. Compare it in constant time before trusting the payload.

verify.js
const crypto = require('crypto');

function isValid(rawBody, headerSignature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(headerSignature || '');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Hash the raw body bytes, not a re-serialised object. Re-encoding JSON changes key order and whitespace, and the signature will never match.

Errors

Failures return the HTTP status alongside a consistent JSON envelope, so you can branch on either.

Error envelope
{
  "success": "false",
  "results": [{ "error": "Invalid API KEY!" }]
}
StatusMessageWhat it means
401 Invalid API KEY! The key is wrong, revoked, or missing.
400 '05012345' is not a valid international phone number. The mobile parameter was not in international format.
402 Insufficient credit. Please top up your balance. Your balance reached zero.
409 WhatsApp number is not connected. The instance is disconnected or logged out. Re-scan the QR code.
429 Daily sending limit reached for this instance. You hit the cap that protects your number. It resets at 00:00 UTC.
429 Too many requests. You exceeded the per-key request rate. Back off and retry.
503 Messaging engine unavailable. A transient platform problem. Retry with backoff.

Rate limits and sending caps

Two separate limits apply, and they exist for different reasons.

Request rate

Protects the platform. Exceeding it returns 429 with a Retry-After header. Back off and retry — the queue means you rarely need to burst.

Daily send cap

Protects your number. Each instance has a daily cap and a minimum gap between sends. WhatsApp bans numbers that behave like bulk senders, and that number is yours, not ours.

This gateway drives a normal WhatsApp session rather than the official Cloud API. That is what lets you keep your existing number with no Meta approval — but it also means WhatsApp's ordinary anti-spam rules apply to you in full. Message people who expect to hear from you, honour opt-outs, and stay inside your cap.