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.
| Header | Value |
|---|---|
X-Client-Id | qa_client_*** |
X-Client-Secret | qa_secret_*** |
Content-Type | application/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:
- Create a template once (
POST /templates) and wait for it to reachAPPROVED. - Send it to one recipient (
POST /messages) or many (POST /campaigns), filling its variables per recipient. - 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
| Category | Use for | Approval path |
|---|---|---|
UTILITY | Order updates, appointment reminders, receipts | Reviewed via QuickAuth’s whitelisting queue, then Meta |
MARKETING | Promotions, offers, re-engagement | Submitted to Meta directly |
AUTHENTICATION | OTP / login codes | Submitted 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
/campaignscall 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
/v1/whatsapp/templatesCreate 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.
/v1/whatsapp/templatesList 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_***"/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
| status | Meaning | Can you send it? |
|---|---|---|
DRAFT | Saved, not yet submitted | No |
PENDING | In whitelist / Meta review | No |
APPROVED | Live and sendable | Yes ✅ |
REJECTED | Meta declined — edit & resubmit | No |
Sending messages
/v1/whatsapp/messagesSend 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"
}
}/v1/whatsapp/campaignsSend 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.
/v1/whatsapp/messages/sessionSend 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
/v1/whatsapp/healthRead 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 } }.
| Status | When |
|---|---|
400 | Validation failed (missing to/templateId, >100 recipients) |
401 | Missing or invalid X-Client-Id / X-Client-Secret |
402 | Out of WhatsApp credits (prepaid) or over your postpaid limit |
404 | Template not found on your account |
409 | Session 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.