# WAQU WhatsApp Gateway & Automation API Specification > Official API specification designed for Large Language Models (LLMs), AI coding assistants (Cursor, Claude, ChatGPT, GitHub Copilot), and automated agents. - Base URL (Production): https://api.waqu.biz.id/v1 - Interactive Swagger Reference: https://api.waqu.biz.id/api-docs/ - OpenAPI 3.0 Specification: https://api.waqu.biz.id/api-docs.json - Human Developer Docs: https://waqu.biz.id/docs --- ## 1. Authentication All API requests must include the API key in the request headers: ```http x-api-key: your_api_key_here Content-Type: application/json ``` Standard Rate Limit: 60 requests per minute per API key. --- ## 2. Endpoints ### 2.1 Send Single Message (Text, OTP, or Media) - Method: `POST` - Path: `/send` (Alias: `/messages/send`) - Description: Send transactional WhatsApp message, OTP verification, or media file with caption. #### Request Body (JSON) - `to` (string, required): Destination phone number in international E.164 format without '+' or spaces (e.g. "628123456789"). - `message` (string, required): The text message or media caption. Field `body` is also accepted as alias. - `attachment_url` (string URL, optional): Public direct URL to image (JPEG/PNG), document (PDF/DOCX), audio (MP3/OGG), or video (MP4). - `attachment_type` (string enum, optional): One of: `"image"`, `"document"`, `"audio"`, `"video"`. - `sender_pool` (string, optional, default: "auto"): Specific pool ID or "auto" for automatic load-balanced device selection. #### Response: `202 Accepted` ```json { "success": true, "messageId": "msg_cm830ad820000a1", "status": "queued" } ``` --- ### 2.2 Send Bulk Broadcast Messages - Method: `POST` - Path: `/send-bulk` (Alias: `/messages/send-bulk`) - Description: Queue messages to multiple recipients (up to 100 per call) with automatic anti-ban delay. #### Request Body (JSON) - `recipients` (array of strings, required): Array of phone numbers in E.164 format. Max 100 items. - `message` (string, required): Message text to broadcast. - `sender_pool` (string, optional, default: "auto") #### Response: `202 Accepted` ```json { "success": true, "data": { "success": [ { "to": "628123456789", "messageId": "msg_001" }, { "to": "628987654321", "messageId": "msg_002" } ], "failed": [], "meta": { "total": 2, "successful": 2, "failed": 0, "remainingQuota": 14980 } } } ``` --- ### 2.3 Check Message Delivery Status - Method: `GET` - Path: `/messages/{id}` - Description: Retrieve delivery status, error logs, and timestamps for a specific message ID. - Headers: `x-api-key: your_api_key_here` #### Response: `200 OK` ```json { "success": true, "data": { "id": "msg_cm830ad820000a1", "to": "628123456789", "status": "sent", // "queued" | "sent" | "delivered" | "read" | "failed" "createdAt": "2026-11-03T01:30:00.000Z", "error": null } } ``` --- ### 2.4 Check WhatsApp Device / Pool Status - Method: `GET` - Path: `/my-pools` - Description: List connected WhatsApp devices and their connection status. #### Response: `200 OK` ```json { "success": true, "data": [ { "id": "pool_clx1820a90001", "name": "Customer Support 1", "number": "628999888777", "status": "connected", // "connected" | "disconnected" "isReady": true } ] } ``` --- ## 3. Webhooks & Event Verification ### 3.1 Inbound Message Event (Received from Customer) When a customer sends a WhatsApp message to your connected number, WAQU delivers an HTTP POST to your webhook URL: ```json { "event": "message.received", "messageId": "wamid.HBgLMjY4...", "from": "628123456789", "fromName": "Customer Name", "body": "Hello, I want to confirm my order", "hasMedia": false, "mediaType": null, "poolId": "pool_clx1820a90001", "timestamp": "2026-11-03T01:30:00.000Z" } ``` ### 3.2 HMAC Signature Verification If you configured a Webhook Secret, WAQU signs requests using HMAC-SHA256 in header `X-Webhook-Signature`: #### Node.js Verification Example ```javascript const crypto = require('crypto'); function verifyWaquWebhook(rawBody, signatureHeader, secret) { const hash = crypto.createHmac('sha256', secret).update(rawBody).digest('hex'); return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(hash)); } ``` #### PHP Verification Example ```php $secret = getenv('WAQU_WEBHOOK_SECRET'); $rawBody = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''; $expected = hash_hmac('sha256', $rawBody, $secret); if (!hash_equals($signature, $expected)) { http_response_code(401); exit('Invalid signature'); } ``` --- ## 4. Code Implementation Examples ### 4.1 cURL ```bash curl -X POST https://api.waqu.biz.id/v1/send \ -H "x-api-key: your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "to": "628123456789", "message": "Your verification OTP is: 849201" }' ``` ### 4.2 PHP (Laravel Http Client) ```php use Illuminate\Support\Facades\Http; $response = Http::withHeaders([ 'x-api-key' => config('services.waqu.key'), ])->post('https://api.waqu.biz.id/v1/send', [ 'to' => '628123456789', 'message' => 'Your OTP is: 849201', ]); if ($response->successful()) { $data = $response->json(); } ``` ### 4.3 Node.js (fetch) ```javascript const response = await fetch('https://api.waqu.biz.id/v1/send', { method: 'POST', headers: { 'x-api-key': process.env.WAQU_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ to: '628123456789', message: 'Halo! Pesanan #1029 Anda telah dikirim.', attachment_url: 'https://example.com/invoice-1029.pdf', attachment_type: 'document' }), }); const result = await response.json(); ``` ### 4.4 Python (requests) ```python import requests response = requests.post( "https://api.waqu.biz.id/v1/send", headers={"x-api-key": "your_api_key_here"}, json={ "to": "628123456789", "message": "Halo dari WAQU WhatsApp Gateway!" } ) print(response.json()) ```