CLEANHOSTBULKSEND
Documentation

CLEANHOSTBULKSEND API

Connect your WhatsApp number once, then use these endpoints from your own website or backend to manage clients, send them notifications, and get notified the moment they reply.

What you can build with this

Client control panelPull your connected numbers, conversation history, and group lists into your own dashboard.
Admin notificationsRegister a webhook so your site is notified the instant a client messages you back — no polling required.
Client notificationsSend order updates, reminders, and confirmations to clients from your own app.

Authentication

Every request to the API is authenticated with your account's API key, sent as a bearer token:

Authorization: Bearer YOUR_API_KEY

Find your key under API key in your dashboard once logged in. Treat it like a password — anyone holding it can send messages from your connected numbers. If it ever leaks, regenerate it immediately from that same page; the old key stops working the moment you do.

All requests and responses are JSON. Send Content-Type: application/json on any POST request with a body.

Connecting a number

Before the API can send or receive anything, a WhatsApp number needs to be connected once from your dashboard (NumbersConnect a number → scan the QR code from the WhatsApp app on that phone). This is a one-time step per number; the API itself doesn't create connections, only uses ones that are already active.

Each connected number is called an instance and has a numeric instance_id you'll pass to most endpoints below.

Webhooks — getting notified as admin

To be notified whenever a client replies (instead of continuously checking for new messages), set a webhook URL for each number under Webhook settings in your dashboard. We'll POST to that URL in real time whenever a message arrives:

{
  "instance_id": 1,
  "from": "254712345678",
  "type": "text",
  "content": "Hi, is this still available?",
  "wa_message_id": "ABCD1234",
  "timestamp": "2026-07-11T10:15:00Z"
}

Your endpoint should respond quickly with a 2xx status. Delivery is best-effort — if your endpoint is briefly down, it won't affect your WhatsApp connection, but retries aren't currently queued, so keep it reliable and fast.

Use this to trigger your own admin alerts — email, Slack, an internal dashboard badge, whatever your site already uses — the moment a client responds.

List your numbers

GET/api/v1/instances.php

Returns every WhatsApp number on your account, so you can build a client-facing or internal picker for "which number should this notification send from."

curl /api/v1/instances.php \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "success": true,
  "data": [
    { "id": 1, "label": "Sales line", "phone_number": "254712345678", "status": "connected", "created_at": "2026-06-01 09:00:00" }
  ]
}

Conversation history

GET/api/v1/messages.php?instance_id=1&limit=50

Returns recent messages (both directions) for one of your numbers — useful for showing a client's conversation thread inside your own admin panel.

ParamRequiredNotes
instance_idYesMust belong to your account.
limitNo1–200, default 50.

List groups

GET/api/v1/groups.php?instance_id=1

Returns the WhatsApp groups a number belongs to. Add &sync=1 to force a fresh pull straight from WhatsApp first (a little slower, but up to date) instead of the last cached copy.

Send a message

POST/api/v1/send-message.php

Send a single notification to one client — order confirmations, appointment reminders, support replies, anything triggered by an event on your own site.

curl -X POST /api/v1/send-message.php \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instance_id": 1,
    "to": "254712345678",
    "text": "Hi Jane, your order #4021 has shipped!"
  }'
FieldTypeRequiredNotes
instance_idnumberYesWhich connected number sends this.
tostringYesClient's phone number.
textstringYesMessage body.
{ "success": true, "wa_message_id": "ABCD1234" }

Send to many clients

POST/api/v1/send-bulk.php

Send the same notification to a list of clients at once — a promo, a service update, a reminder batch. Messages are queued and delivered gradually rather than sent all at once in the same request; check conversation history or your dashboard's Messages page to see each one's delivery status as it goes out.

curl -X POST /api/v1/send-bulk.php \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instance_id": 1,
    "numbers": ["254712345678", "0798765432"],
    "text": "Reminder: your appointment is tomorrow at 10am."
  }'
{ "success": true, "queued": 2 }
This endpoint is for genuine client updates your recipients expect — order/appointment notifications, service alerts, replies to inbound conversations. It isn't a bulk-marketing or cold-outreach tool, and sending unsolicited messages to numbers that haven't opted in risks your number being restricted by WhatsApp regardless of how it's sent. Keep lists limited to clients who've engaged with your business.

Delivery & status

Every message you send is recorded against the instance it went out on. Poll /api/v1/messages.php for an instance to see each message's current status, or view the same thing under Messages in your dashboard.

Errors

Errors return a non-2xx status code with a JSON body:

{ "success": false, "message": "Instance not found on your account." }
CodeMeaning
401Missing, malformed, or invalid API key.
403Account suspended or subscription expired.
404The instance doesn't exist or isn't yours.
409The instance exists but isn't connected right now.
422Missing or invalid fields in your request.
429Would exceed your plan's monthly message limit.
502The WhatsApp connection failed to send — usually transient, safe to retry shortly.

Rate limits & quota

Each plan includes a monthly message allowance. send-bulk.php checks remaining quota up front and rejects the whole batch with 429 if it would push you over, so you can show the client a clear "limit reached" message instead of a partial send. Check your current usage and limit from your dashboard's billing page.

Phone number format

Numbers are normalized automatically — both local (07XXXXXXXX) and international (2547XXXXXXXX) formats are accepted for Kenyan numbers. Any entries that can't be normalized are silently dropped from a bulk request, and the response's queued count reflects only the valid ones — compare it against the length of the list you sent if you need to know which were skipped.