Server-side · v1

WhatsApp Business API

Send WhatsApp template messages and bulk campaigns, manage your templates, reply free-form inside the 24-hour customer-service window, and read your number’s health — all over plain HTTPS with your server credentials. It’s the same engine that powers the QuickAuth dashboard, exposed as a clean REST API for your backend.

When to use this

Use this API to drive WhatsApp from your own systems — fire an order update from your backend, sync a template from CI, or blast a campaign to a segment your CRM built. For the OTP / login flow, use the Auth REST API or an SDK instead.

Base URL

https://api.quickauth.in/v1/whatsapp

All endpoints accept and return application/json.

Authentication

Every request is authenticated server-to-server with your client credentials — the same pair you use for the Auth and Marketing APIs. Never expose these in a browser or mobile app.

HeaderValue
X-Client-Idqa_client_***
X-Client-Secretqa_secret_***
Content-Typeapplication/json

Find both keys in Dashboard → Settings → API keys. A missing or wrong pair returns 401.

How WhatsApp sending works

WhatsApp doesn’t let you send arbitrary text to a customer out of the blue — business-initiated messages must use a pre-approved template. The lifecycle is always the same:

  1. Create a template once (POST /templates) and wait for it to reach APPROVED.
  2. Send it to one recipient (POST /messages) or many (POST /campaigns), filling its variables per recipient.
  3. Once a customer replies, a 24-hour window opens in which you can send free-form text with no template (POST /messages/session).

Template categories

CategoryUse forApproval path
UTILITYOrder updates, appointment reminders, receiptsReviewed via QuickAuth’s whitelisting queue, then Meta
MARKETINGPromotions, offers, re-engagementSubmitted to Meta directly
AUTHENTICATIONOTP / login codesSubmitted to Meta directly

Variables

Put numbered placeholders {{1}}, {{2}} … in your template body. At send time you pass a variables map of name → value per recipient — QuickAuth substitutes them before delivery. Declare each variable’s name and an example when you create the template so Meta can review it.

Billing & limits

  • Template sends are billed per your plan — prepaid credits are debited on send; postpaid WhatsApp marketing accrues to your monthly invoice.
  • A session (free-form) message costs one WhatsApp credit.
  • A single /campaigns call takes up to 100 recipients. For larger lists, page your audience and call it repeatedly.

Quickstart — send your first message

Assuming you already have an APPROVED template named order_shipped with two variables:

curl https://api.quickauth.in/v1/whatsapp/messages \
  -H "Content-Type: application/json" \
  -H "X-Client-Id: qa_client_***" \
  -H "X-Client-Secret: qa_secret_***" \
  -d '{
    "templateId": "order_shipped",
    "to": "919876543210",
    "variables": { "name": "Asha", "tracking": "BLX-4471" }
  }'

Sends are asynchronous

You get a campaignId and status back immediately — actual delivery happens in the background. Track progress with the delivery webhooks, or poll the campaign. A single message is just a one-recipient campaign under the hood, which is why the response shape is shared.

Templates

POST/v1/whatsapp/templates

Create a template

Submits a new template for approval. UTILITY (or uncategorised) templates enter QuickAuth’s whitelisting queue; MARKETING and AUTHENTICATION go to Meta directly. Returns immediately with a status of DRAFT / PENDING — poll GET /templates/{templateId} until it’s APPROVED.

POST /v1/whatsapp/templates
X-Client-Id: qa_client_***
X-Client-Secret: qa_secret_***
Content-Type: application/json

{
  "name": "order_shipped",
  "language": "en",
  "category": "UTILITY",
  "body": "Hi {{1}}, your order is on the way! Track it here: {{2}}",
  "footer": "Reply STOP to opt out",
  "variables": [
    { "name": "name",     "example": "Asha" },
    { "name": "tracking", "example": "BLX-4471" }
  ],
  "buttons": [
    { "type": "URL", "text": "Track order", "url": "https://shop.example/t/{{1}}", "urlParam": "BLX-4471" }
  ]
}

Optional fields

Templates also support a headerType (TEXT / IMAGE / VIDEO / DOCUMENT) with headerText or headerMediaUrl, quick-reply and phone-number buttons, and authentication-specific fields (OTP button, codeExpirationMinutes, Android app signals). Omit anything you don’t need.

GET/v1/whatsapp/templates

List your templates

Returns every template on your account with its current status.

curl https://api.quickauth.in/v1/whatsapp/templates \
  -H "X-Client-Id: qa_client_***" \
  -H "X-Client-Secret: qa_secret_***"
GET/v1/whatsapp/templates/{templateId}

Get one template's status

Poll this after creating a template to watch it reach APPROVED. Returns 404 if the id isn’t on your account.

Template status reference

statusMeaningCan you send it?
DRAFTSaved, not yet submittedNo
PENDINGIn whitelist / Meta reviewNo
APPROVEDLive and sendableYes ✅
REJECTEDMeta declined — edit & resubmitNo

Sending messages

POST/v1/whatsapp/messages

Send one template message

Send an approved template to a single recipient. Great for transactional, event-driven messages (order shipped, OTP, reminder).

POST /v1/whatsapp/messages

{
  "templateId": "order_shipped",   // an APPROVED template
  "to": "919876543210",            // international format, digits only
  "variables": {                   // optional — keyed by your variable names
    "name": "Asha",
    "tracking": "BLX-4471"
  }
}
POST/v1/whatsapp/campaigns

Send a bulk campaign

Send an approved template to many recipients in one async campaign — each with its own variable values. Up to 100 recipients per call.

POST /v1/whatsapp/campaigns

{
  "templateId": "diwali_offer",
  "campaignName": "Diwali 2026 — VIP segment",
  "recipients": [
    { "phoneNumber": "919876543210", "variables": { "name": "Asha",  "code": "VIP20" } },
    { "phoneNumber": "919812345678", "variables": { "name": "Rahul", "code": "VIP20" } }
  ]
}

Batch large audiences

More than 100 recipients? Split your list into pages of ≤100 and call /campaigns once per page. Each call returns its own campaignId.

POST/v1/whatsapp/messages/session

Send a free-form session message

Reply with plain text — no template — inside the 24-hour window that opens when a customer messages you. Costs one WhatsApp credit. Returns 409 if there’s no open window for that contact.

POST /v1/whatsapp/messages/session

{
  "to": "919876543210",
  "text": "Thanks for reaching out! Your refund is processed ✅"
}

Account health

GET/v1/whatsapp/health

Read your WABA health

Quality rating, messaging tier, daily limit and connection status for each of your connected numbers — the same data behind the dashboard’s Number-health view. Poll it before a big send to confirm you’re CONNECTED and within your daily cap.

curl https://api.quickauth.in/v1/whatsapp/health \
  -H "X-Client-Id: qa_client_***" \
  -H "X-Client-Secret: qa_secret_***"

Errors

Errors use standard HTTP status codes with a JSON body of shape { error: { code, message } }.

StatusWhen
400Validation failed (missing to/templateId, >100 recipients)
401Missing or invalid X-Client-Id / X-Client-Secret
402Out of WhatsApp credits (prepaid) or over your postpaid limit
404Template not found on your account
409Session message with no open 24h window for the contact

Delivery status & replies

Wire up webhooks to receive delivery receipts (sent → delivered → read), button taps, and inbound customer replies in real time instead of polling. Configure your webhook URL in Dashboard → Settings → Webhooks.