WA
WHATSAPP GATEWAY DOCS
🏠 Website 🔑 Client Portal 📥 Download Postman
REST API Reference v2.4

Developer API & Integration Guide

Complete guide for integrating WhatsApp automation, PDF invoice dispatch, status verification, and incoming webhooks into Laravel, Node.js, PHP, or Python applications.

Production Base URL: https://sachalabdullah.shop
🔒 Authentication

Every API request must include your Client API Key in the HTTP Request Header:

HTTP Headers
X-API-Key: wa_live_YOUR_API_KEY_HERE # Or Authorization: Bearer wa_live_YOUR_API_KEY_HERE
GET /api/v1/status — Check Connection & QR Code

Check if the WhatsApp line is currently connected. If disconnected, it returns the raw QR string and a browser connection link so you can display the QR code directly to the user.

cURL Example
curl -X GET "https://sachalabdullah.shop/api/v1/status" \ -H "X-API-Key: wa_live_YOUR_API_KEY"

Response Example (When Connected):

200 OK Response
{ "success": true, "connected": true, "status": "CONNECTED", "tenant": { "id": "client_123", "name": "My Business", "phone": "923001234567", "connected": true }, "qr": null }

Response Example (When Disconnected / QR Available):

200 OK Response
{ "success": true, "connected": false, "status": "QR_REQUIRED", "tenant": { "id": "client_123", "name": "My Business", "phone": null, "connected": false }, "qr": "2@4fK8g7...==,J9c...==,1", "connect_url": "/connect?session=client_123" }
POST /api/v1/send — Send PDF, Media or Text

Dispatch text messages, attached PDF documents (Multipart), or In-Memory Base64 PDFs (DomPDF) to any WhatsApp number.

Field Type Requirement Description
phone string Required Recipient phone number (e.g. 923001234567 or 03001234567)
file file Optional PDF or Image binary file for Multipart upload
media_base64 string Optional Base64 encoded string of the PDF (for in-memory DomPDF dispatch)
filename string Optional Custom name for the document (e.g. Invoice_1024.pdf)
caption / message string Optional Accompanying message text or document caption
cURL Multipart Example
curl -X POST https://sachalabdullah.shop/api/v1/send \ -H "X-API-Key: wa_live_YOUR_API_KEY" \ -F "phone=923001234567" \ -F "caption=Here is your PDF invoice" \ -F "filename=Invoice_1024.pdf" \ -F "file=@/path/to/invoice.pdf"
POST /api/v1/send-bulk — Smart Anti-Ban Bulk Dispatch

Send bulk announcements with automated humanized randomized jitter and batch resting protection.

Bulk JSON Example
curl -X POST https://sachalabdullah.shop/api/v1/send-bulk \ -H "X-API-Key: wa_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "numbers": ["923001234567", "923211234567", "923451234567"], "message": "Special announcement for our registered customers!", "delay_ms": 4000 }'
🛠️ Complete Laravel Service Class

Create app/Services/WhatsAppGatewayService.php in your Laravel project:

app/Services/WhatsAppGatewayService.php
<?php namespace App\Services; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; class WhatsAppGatewayService { protected string $baseUrl; protected string $apiKey; public function __construct(?string $apiKey = null) { $this->baseUrl = rtrim(config('services.whatsapp.base_url', 'https://sachalabdullah.shop'), '/'); $this->apiKey = $apiKey ?? config('services.whatsapp.api_key', ''); } /** * Check status and get QR code if disconnected */ public function getStatus(): array { try { $response = Http::withHeaders([ 'X-API-Key' => $this->apiKey, 'Accept' => 'application/json' ])->timeout(10)->get("{$this->baseUrl}/api/v1/status"); if ($response->successful()) { $data = $response->json(); return [ 'connected' => (bool) ($data['connected'] ?? false), 'status' => $data['status'] ?? 'DISCONNECTED', 'qr' => $data['qr'] ?? null, 'phone' => $data['tenant']['phone'] ?? null ]; } return ['connected' => false, 'status' => 'ERROR', 'qr' => null, 'phone' => null]; } catch (\Exception $e) { Log::error('WhatsApp Status Error: ' . $e->getMessage()); return ['connected' => false, 'status' => 'UNREACHABLE', 'qr' => null, 'phone' => null]; } } /** * Send In-Memory PDF (DomPDF Output) */ public function sendPdfBinary(string $phone, string $rawPdfContent, string $fileName = 'invoice.pdf', ?string $caption = null): array { try { $response = Http::withHeaders([ 'X-API-Key' => $this->apiKey, 'Accept' => 'application/json' ])->timeout(60)->post("{$this->baseUrl}/api/v1/send", [ 'phone' => $phone, 'media_base64' => base64_encode($rawPdfContent), 'mimetype' => 'application/pdf', 'filename' => $fileName, 'caption' => $caption ]); return $response->json(); } catch (\Exception $e) { Log::error('WhatsApp Send PDF Error: ' . $e->getMessage()); return ['success' => false, 'message' => $e->getMessage()]; } } /** * Send Physical PDF from storage disk (Multipart) */ public function sendPdfFile(string $phone, string $filePath, ?string $caption = null, ?string $fileName = null): array { if (!file_exists($filePath)) { return ['success' => false, 'message' => 'File not found on disk']; } try { $fileName = $fileName ?? basename($filePath); $fileResource = fopen($filePath, 'r'); $data = ['phone' => $phone]; if ($caption) $data['caption'] = $caption; if ($fileName) $data['filename'] = $fileName; $response = Http::withHeaders([ 'X-API-Key' => $this->apiKey, 'Accept' => 'application/json' ])->attach('file', $fileResource, $fileName)->timeout(60)->post("{$this->baseUrl}/api/v1/send", $data); return $response->json(); } catch (\Exception $e) { Log::error('WhatsApp Send File Error: ' . $e->getMessage()); return ['success' => false, 'message' => $e->getMessage()]; } } }