API Reference

Programmatic access to send messages, manage contacts, and pull reports.

← Back to dashboard

Authentication

Pass your key on every request with the X-API-Key header (or Authorization: Bearer <key>). Get your key from Settings.

X-API-Key: YOUR_API_KEY

Base URL: https://whatsapp.pdthosting.com/api/v1

POST /send

Send a single message immediately (subject to throttle / quiet hours).

Body

{
  "phone":        "8801XXXXXXXXX",   // digits only, no +
  "message":      "Hello {name}, your code is 1234",
  "device_label": "primary"          // optional, defaults to "primary". Use GET /devices to list yours.
}

cURL

curl -X POST https://whatsapp.pdthosting.com/api/v1/send \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone":"8801XXXXXXXXX","message":"Hi there"}'

PHP

$ch = curl_init('https://whatsapp.pdthosting.com/api/v1/send');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'phone' => '8801XXXXXXXXX',
        'message' => 'Hi there',
    ]),
]);
$res = json_decode(curl_exec($ch), true);
GET /campaigns

Paginated list of your campaigns.

POST /campaigns
{
  "name": "April promo",
  "message": "Hi {name}, {Save|Get} 20% today",
  "tag": "leads",              // optional: only contacts with this tag
  "scheduled_for": "2026-04-25T10:00:00+06:00"  // optional
}

Supports spintax {a|b|c} and variables {name}, {custom}, {phone}.

GET /campaigns/{id}

Campaign status and counters (sent/failed/total).

GET /contacts?tag=leads

Paginated contact list, optionally filtered by tag.

POST /contacts
{
  "phone":  "8801XXXXXXXXX",
  "name":   "Alice",
  "tag":    "leads",
  "custom": "VIP"
}

Upserts on (user, phone). Phone is normalized to digits.

DELETE /contacts/{id}

Devices

GET /devices

List your connected devices with live state.

curl https://whatsapp.pdthosting.com/api/v1/devices -H "X-API-Key: YOUR_API_KEY"

Response

{
  "devices": [{
    "device_label": "primary",
    "phone_number": "8801XXXXXXXXX",
    "state": "ready",          // ready | qr | starting | disconnected | not_started
    "ready": true,
    "warmup_enabled": true,
    "warmup_day": 5,           // 1-7 during ramp, null after day 7 or when disabled
    "effective_daily_cap": 150
  }],
  "count": 1,
  "max_allowed": 3
}
POST /devices

Add a new device (subject to your plan's max_wa_accounts). Body: {"device_label":"sales"}. Then call /devices/sales/start + poll /devices/sales/qr until ready.

POST /devices/{device_label}/start POST /restart POST /logout

Lifecycle controls. Disclaimer must be accepted at /whatsapp first.

GET /devices/{device_label}/qr

Returns {"qr": "data:image/png;base64,..."} when in qr state. Poll every 2-3s until qr is null AND GET /devices shows state=ready.

DELETE /devices/{device_label}

Remove a device entirely (frees a plan slot). Cannot remove "primary" — use logout instead.

Campaign control

All four take a campaign id and return updated status. Stop also returns credits_refunded.

POST https://whatsapp.pdthosting.com/api/v1/campaigns/{id}/pause       # sending → paused
POST https://whatsapp.pdthosting.com/api/v1/campaigns/{id}/resume      # paused → sending
POST https://whatsapp.pdthosting.com/api/v1/campaigns/{id}/stop        # any → stopped, refunds queued credits
POST https://whatsapp.pdthosting.com/api/v1/campaigns/{id}/redispatch  # re-send queued jobs (e.g. after worker downtime)

Contact updates

PATCH /contacts/{id}

Update name, custom, or tag. Phone is immutable (delete + re-create instead).

POST /contacts/bulk

Insert/update up to 1000 contacts in one call.

{
  "contacts": [
    {"phone": "8801711111111", "name": "Alice", "tag": "vip"},
    {"phone": "8801722222222", "name": "Bob",   "tag": "vip"}
  ]
}

Returns {created, updated, total_processed}.

Webhooks

Receive real-time delivery events. Set your URL once, then we POST every send/fail/skip to it.

GET /webhooks PUT /webhooks

PUT body: {"webhook_url": "https://your.app/wa-events", "rotate_secret": false}. Set webhook_url=null to disable.

Event payload (POSTed to your URL)

{
  "event":       "delivery.sent",       // or .failed / .skipped
  "job_id":      12345,
  "campaign_id": 678,
  "phone":       "8801XXXXXXXXX",
  "status":      "sent",
  "error":       null,
  "sent_at":     "2026-04-25T12:34:56+00:00"
}

Signature verification

Each request includes X-Webhook-Signature: sha256=<hex>. Verify with HMAC-SHA256 over the raw request body using your webhook_secret.

$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $YOUR_WEBHOOK_SECRET);
if (!hash_equals($expected, $request->header('X-Webhook-Signature'))) abort(401);

Rotate API key

POST /keys/rotate

Returns a new api_key and immediately invalidates the old one. Use this if you think your key has leaked.

curl -X POST https://whatsapp.pdthosting.com/api/v1/keys/rotate -H "X-API-Key: YOUR_API_KEY"
GET /reports/summary

Your plan, credits, and message counters (today/week/month/total) plus a 30-day daily sent series.

curl https://whatsapp.pdthosting.com/api/v1/reports/summary -H "X-API-Key: YOUR_API_KEY"

Errors

CodeMeaning
401Missing / invalid API key
402Insufficient credits
403Account not active (pending/suspended)
404Resource not found or not yours
422Validation / plan-limit error (details in error)
503WhatsApp session not connected

Terms of Service

1. Acceptable use. Bulk WhatsApp messaging carries ban risk for the underlying phone number. You are responsible for the recipients you message and for complying with WhatsApp's terms and your local anti-spam laws.

2. Account locking. We may lock your account at any time for spam complaints, fraudulent payment claims (re-using TXIDs, falsified senders), abusive content, or violation of our content filters. Locked accounts cannot log in until reviewed.

3. Free trial. Each user may use a free-trial plan exactly once. Re-registration with a new email but the same WhatsApp number or IP will be denied the trial.

4. Payments. Manual payments (bKash/Nagad/bank) are verified by an admin before plan activation or credits are added. False or duplicate transaction IDs will be rejected. Approved payments are non-refundable.

5. Subscription expiry. Plans expire after their listed duration. We will email + WhatsApp you near expiry and generate a renewal invoice. Sending capability pauses while expired.

6. Data. We store your contacts, message bodies, and IP addresses for audit and fraud prevention. We do not sell your data.

7. Liability. The service is provided as-is. We are not liable for WhatsApp account bans, message non-delivery, or business losses arising from automation use.

By registering you confirm you have read and accept these terms.

Built with care by SomoySoft.