WhatsApp Business Messaging Gateway
Standard REST API interface allowing third-party applications (ERPs, CRMs, Billing systems, Service Management, or automated workflows) to discover approved Meta templates and trigger automated WhatsApp notifications to customers.
1. Overview & Architecture
This gateway decouples your software from Meta Cloud API complexities. Using your assigned API Key, you can programmatically fetch available approved templates, send notification messages, attach documents/media, and check real-time message delivery status.
2. Security & Zero-Access Isolation
This integration enforces total isolation. Third-party vendors are provided only an API Key and isolated REST endpoints. They have zero access to:
- The administrator management console or passwords
- Meta Business Manager tokens or app secrets
- Internal database connections or customer history tables
The platform owner can monitor request counts or revoke API keys instantly with one click if required.
3. Authentication Headers
Provide the assigned API Key in every HTTP request. Supported header formats:
# Preferred Header Format: X-API-Key: wa_live_YOUR_ASSIGNED_KEY_HERE Content-Type: application/json # Standard Bearer Header also supported: Authorization: Bearer wa_live_YOUR_ASSIGNED_KEY_HERE Content-Type: application/json
4. Meta Templates Discovery API
Third-party software can programmatically query this endpoint to inspect all approved Meta templates available for use, their variable placeholders ({{1}}, {{2}}), categories, and copy ready-to-use dispatch payloads.
{
"status": "success",
"count": 2,
"templates": [
{
"template_name": "order_status_update",
"language": "en_US",
"category": "UTILITY",
"status": "APPROVED",
"header_format": "DOCUMENT",
"body_text": "Hello {{1}}, your order #{{2}} is ready! Total: {{3}}. Thank you.",
"variable_count": 3,
"variables": [
{ "position": 1, "placeholder": "{{1}}", "type": "text" },
{ "position": 2, "placeholder": "{{2}}", "type": "text" },
{ "position": 3, "placeholder": "{{3}}", "type": "text" }
],
"example_payload": {
"to": "919876543210",
"type": "template",
"template_name": "order_status_update",
"language": "en_US",
"header_media": {
"type": "document",
"url": "https://example.com/invoice.pdf",
"filename": "invoice.pdf"
},
"parameters": [
{ "type": "text", "text": "Customer Name" },
{ "type": "text", "text": "ORD-1042" },
{ "type": "text", "text": "$250.00" }
]
}
}
]
}
5. Send Message API
Send Meta Template Message (Recommended)
Templates are approved by Meta and deliver reliably even if the customer hasn't messaged you recently. The parameters replace positional variables {{1}}, {{2}}, etc.
{
"to": "919876543210",
"type": "template",
"template_name": "YOUR_TEMPLATE_NAME",
"language": "en_US",
"parameters": [
{ "type": "text", "text": "Customer Name" },
{ "type": "text", "text": "Ref #12345" },
{ "type": "text", "text": "$150.00" }
]
}
Send Template with PDF, Document, or Image Attachment
If the template has a document or media header, include the public file URL in header_media:
{
"to": "919876543210",
"type": "template",
"template_name": "invoice_notification",
"language": "en_US",
"header_media": {
"type": "document",
"url": "https://example.com/invoices/INV-12345.pdf",
"filename": "Invoice_12345.pdf"
},
"parameters": [
{ "type": "text", "text": "John Doe" }
]
}
Direct Free-Form Text Alert
For numbers with an active customer service session (inbound message received in the last 24 hours):
{
"to": "919876543210",
"type": "text",
"message": "Hello, your service request has been processed successfully. Reference: #12345."
}
{
"status": "success",
"message_id": "wamid.HBgLMzkxOTg3NjU0MzIxMBUC...",
"recipient": "919876543210",
"delivery_status": "sent",
"type": "template",
"template": "YOUR_TEMPLATE_NAME",
"timestamp": "2026-10-09T15:00:00+00:00"
}
6. Integration Code Snippets
curl -X POST "" \
-H "Content-Type: application/json" \
-H "X-API-Key: wa_live_YOUR_KEY_HERE" \
-d '{
"to": "919876543210",
"type": "template",
"template_name": "order_status_update",
"language": "en_US",
"parameters": [
{ "type": "text", "text": "Customer Name" },
{ "type": "text", "text": "ORD-12345" },
{ "type": "text", "text": "$150.00" }
]
}'
import requests
url = ""
headers = {
"Content-Type": "application/json",
"X-API-Key": "wa_live_YOUR_KEY_HERE"
}
payload = {
"to": "919876543210",
"type": "template",
"template_name": "order_status_update",
"language": "en_US",
"parameters": [
{"type": "text", "text": "Customer Name"},
{"type": "text", "text": "ORD-12345"},
{"type": "text", "text": "$150.00"}
]
}
response = requests.post(url, json=payload, headers=headers, timeout=10)
print(response.json())
const sendMessage = async () => {
const url = '';
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'wa_live_YOUR_KEY_HERE'
},
body: JSON.stringify({
to: '919876543210',
type: 'template',
template_name: 'order_status_update',
language: 'en_US',
parameters: [
{ type: 'text', text: 'Customer Name' },
{ type: 'text', text: 'ORD-12345' },
{ type: 'text', text: '$150.00' }
]
})
});
const result = await response.json();
console.log('Dispatch Result:', result);
};
sendMessage();
<?php
$url = '';
$apiKey = 'wa_live_YOUR_KEY_HERE';
$payload = [
'to' => '919876543210',
'type' => 'template',
'template_name' => 'order_status_update',
'language' => 'en_US',
'parameters' => [
['type' => 'text', 'text' => 'Customer Name'],
['type' => 'text', 'text' => 'ORD-12345'],
['type' => 'text', 'text' => '$150.00']
]
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: ' . $apiKey
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result);
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
private static readonly HttpClient client = new HttpClient();
static async Task Main()
{
var url = "";
var payload = new
{
to = "919876543210",
type = "template",
template_name = "order_status_update",
language = "en_US",
parameters = new[]
{
new { type = "text", text = "Customer Name" },
new { type = "text", text = "ORD-12345" },
new { type = "text", text = "$150.00" }
}
};
var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Add("X-API-Key", "wa_live_YOUR_KEY_HERE");
request.Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);
}
}
7. Message Delivery Status Query
Check whether a message was queued, sent, delivered, or read by passing the message_id received from the dispatch response:
{
"status": "success",
"message_id": "wamid.HBgL...",
"recipient": "919876543210",
"delivery_status": "delivered", // queued | sent | delivered | read | failed
"created_at": "2026-10-09 15:00:00",
"updated_at": "2026-10-09 15:00:03"
}
8. HTTP Response Codes & Error Reference
| Code | Condition | Resolution |
|---|---|---|
| 200 OK | Message dispatched and queued in Meta Cloud. | Store message_id in your database. |
| 400 Bad Request | Missing recipient phone number (to) or parameters. |
Check phone format (international digits without +). |
| 401 Unauthorized | Missing or invalid X-API-Key. |
Verify API key header spelling and token. |
| 403 Forbidden | API key is revoked or template is restricted. | Contact platform administrator to reactivate key. |
| 502 / 500 | Meta Graph API error or network timeout. | Inspect JSON error message for Meta Cloud reason. |
9. Inbound Customer Replies (Two-Way Sync)
When a customer replies to any notification triggered by your software, the reply automatically appears in real time in the platform's Leads Inbox. Support staff can chat with the customer directly without the external software needing to implement any webhook listener or messaging socket.