WB01K2…Used in every API URL. It is a long public identifier and is not secret.
W8BUZZ DEVELOPER PLATFORM · VERSION 2.0.6
This page documents the complete public API currently implemented by W8Buzz. Each WhatsApp connection is an isolated instance with its own API instance ID, bearer token, session, message history, webhook settings, and webhook secret.
https://buzz.w8mediaworks.com/api/{INSTANCE_ID}FIRST REQUEST CHECKLIST
authenticated.919829057897, not a local number.messageId and WhatsApp whatsappId. Use signed webhooks for delivery/read updates and incoming messages.409 until its status is authenticated.CREDENTIALS
WB01K2…Used in every API URL. It is a long public identifier and is not secret.
w8_f578…Sent as a bearer token. Treat it like a password. It can be viewed or regenerated from the Credentials dialog.
#11011A short human reference for support conversations. Never put it in an API URL.
64 hex charactersVerifies that webhook requests were sent by W8Buzz. It is not the API token.
W8BUZZ_BASE_URL=https://buzz.w8mediaworks.comW8BUZZ_INSTANCE_ID=WB_REPLACE_WITH_API_INSTANCE_ID
W8BUZZ_TOKEN=w8_REPLACE_WITH_API_TOKEN
W8BUZZ_WEBHOOK_SECRET=REPLACE_WITH_WEBHOOK_SECRETAUTHENTICATION
The token is scoped to exactly one instance. A valid token from instance A cannot read messages or send through instance B.
Authorization: Bearer YOUR_INSTANCE_TOKEN
Accept: application/json
Content-Type: application/jsonContent-Type is required for requests with a JSON body. Accept is recommended. W8Buzz also accepts X-Instance-Token for compatibility, but the bearer header is preferred. Do not put tokens in URLs because URLs are commonly stored in logs and browser history.
FORMATS & CONVENTIONS
| Value | Required format | Example |
|---|---|---|
| Direct recipient | Full international number, country code included. Digits-only is safest. No domestic trunk prefix. | 919829057897 |
| Group recipient | WhatsApp group JID returned by GET /groups. | 1203630…@g.us |
| Dates from W8Buzz | API lists may contain UTC database timestamps; webhook envelopes use ISO 8601 UTC. | 2026-09-16T01:02:03Z |
| Media URL | Public http:// or https:// URL reachable by the W8Buzz server, up to 32 MB. | https://cdn.example.com/a.jpg |
referenceId | Your optional correlation value, such as an order or ticket ID. | order-1042 |
W8Buzz stores and returns referenceId, but it does not reject duplicate values. Retrying a send after an uncertain network result can therefore create a second WhatsApp message. For critical workflows, store an application-level idempotency key before calling W8Buzz, save the returned messageId, and check your own record before retrying.
Send endpoints are synchronous: W8Buzz returns only after the connected WhatsApp socket accepts the message, or returns an error. Requests for the same instance are serialized briefly to protect the socket, but they do not enter a delayed application queue.
COPY-READY QUICKSTARTS
curl --request POST \
"https://buzz.w8mediaworks.com/api/$W8BUZZ_INSTANCE_ID/messages/chat" \
--header "Authorization: Bearer $W8BUZZ_TOKEN" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '{
"to": "919829057897",
"body": "Hello from W8Buzz",
"referenceId": "quickstart-001"
}'<?php
$base = rtrim(getenv('W8BUZZ_BASE_URL'), '/');
$instance = getenv('W8BUZZ_INSTANCE_ID');
$token = getenv('W8BUZZ_TOKEN');
$payload = ['to' => '919829057897', 'body' => 'Hello from PHP', 'referenceId' => 'order-1042'];
$ch = curl_init("{$base}/api/{$instance}/messages/chat");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}", 'Accept: application/json', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
]);
$body = curl_exec($ch);
if ($body === false) throw new RuntimeException(curl_error($ch));
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$result = json_decode($body, true, flags: JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300) throw new RuntimeException($result['error'] ?? "W8Buzz HTTP {$status}");
echo $result['messageId'];import os, requests
url = f"{os.environ['W8BUZZ_BASE_URL'].rstrip('/')}/api/{os.environ['W8BUZZ_INSTANCE_ID']}/messages/chat"
response = requests.post(url, headers={"Authorization": f"Bearer {os.environ['W8BUZZ_TOKEN']}", "Accept": "application/json"}, json={"to": "919829057897", "body": "Hello from Python", "referenceId": "order-1042"}, timeout=30)
data = response.json()
if not response.ok:
raise RuntimeError(data.get("error", f"W8Buzz HTTP {response.status_code}"))
print(data["messageId"], data["whatsappId"])const base = process.env.W8BUZZ_BASE_URL!.replace(/\/$/, '');
const instance = process.env.W8BUZZ_INSTANCE_ID!;
const response = await fetch(`${base}/api/${instance}/messages/chat`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.W8BUZZ_TOKEN}`, Accept: 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({ to: '919829057897', body: 'Hello from Node.js', referenceId: 'order-1042' }),
signal: AbortSignal.timeout(30_000)
});
const data = await response.json();
if (!response.ok) throw new Error(data.error ?? `W8Buzz HTTP ${response.status}`);
console.log(data.messageId, data.whatsappId);SEND RESPONSE
HTTP/1.1 200 OK
Content-Type: application/json
{
"sent": true,
"messageId": "MSG01K5EXAMPLE",
"whatsappId": "3EB0A1B2C3D4EXAMPLE",
"recipient": "919829057897@s.whatsapp.net",
"status": "sent"
}messageIdW8Buzz’s durable ID. Store it and use it to correlate event viewer records and webhook events.
whatsappIdWhatsApp’s message identifier. Delivery/read acknowledgements refer to it.
recipientThe normalized WhatsApp JID actually used for delivery.
status: sentThe WhatsApp socket accepted the send. It does not yet guarantee delivery or reading.
Listen for message.ack webhooks to observe delivered and read. Some recipients or WhatsApp clients may not provide read receipts.
TEXT MESSAGES
| Field | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Direct international number or a group JID. |
body | string | Yes | Non-empty UTF-8 message text. |
referenceId | string | No | Your correlation identifier. It is not deduplicated. |
{
"to": "919829057897",
"body": "Your booking has been confirmed for tomorrow at 10:30 AM.",
"referenceId": "booking-7842"
}MEDIA MESSAGES
W8Buzz downloads the URL from its server and then uploads the content to WhatsApp. The URL must be publicly reachable without cookies or custom headers, must respond within 20 seconds, and must not exceed 32 MB. Use short-lived signed URLs when the content is private.
/messages/imageto, url; optional caption/messages/videoto, url; optional caption/messages/audioto, url; optional mimetype, ptt/messages/documentto, url; optional filename, mimetype, caption{
"to": "919829057897",
"url": "https://cdn.example.com/invoices/preview.jpg",
"caption": "Invoice preview",
"referenceId": "invoice-2026-0042"
}{
"to": "919829057897",
"url": "https://cdn.example.com/invoices/42.pdf",
"filename": "invoice-42.pdf",
"mimetype": "application/pdf",
"caption": "Your invoice is attached"
}{
"to": "919829057897",
"url": "https://cdn.example.com/audio/update.mp3",
"mimetype": "audio/mpeg",
"ptt": true
}STRUCTURED MESSAGES
{
"to": "919829057897",
"latitude": 28.6139,
"longitude": 77.2090,
"name": "Meeting point",
"address": "Connaught Place, New Delhi"
}{
"to": "919829057897",
"name": "W8Buzz Support",
"vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:W8Buzz Support\nTEL;TYPE=CELL:+919829057897\nEND:VCARD"
}{
"to": "919829057897",
"messageId": "3EB0A1B2C3D4_WHATSAPP_MESSAGE_ID",
"reaction": "👍"
}For reactions, messageId is the WhatsApp message ID—not the W8Buzz MSG… ID—and to must identify the same conversation. The current reaction endpoint targets a received message.
MESSAGE HISTORY
GET /messages?limit=25&status=all&sort=desc| Parameter | Allowed values | Default |
|---|---|---|
limit | 1–100 | 25 |
status | all, processing, sent, delivered, read, received, failed, invalid, expired | all |
sort | asc or desc | desc |
{
"messages": [{
"id": "MSG01K5EXAMPLE",
"whatsapp_id": "3EB0A1B2C3D4EXAMPLE",
"reference_id": "booking-7842",
"direction": "outbound",
"type": "chat",
"recipient": "919829057897",
"sender": null,
"body": "Your booking has been confirmed.",
"status": "delivered",
"created_at": "2026-09-16 05:30:00"
}]
}Returns retained raw-message counts grouped by status. Raw event items are deleted after seven days, so this endpoint is not a permanent billing ledger.
{
"statistics": [
{"status": "sent", "count": 42},
{"status": "delivered", "count": 38},
{"status": "received", "count": 17}
]
}INSTANCE LIFECYCLE
/instance/statusStored connection state, instance ID, and last-seen timestamp./instance/qrPairing state, raw QR value, and browser-ready PNG data URL./instance/meLive status, connected boolean, phone, profile name, and update time./instance/restartReplaces the current socket while preserving the saved WhatsApp session./instance/logoutLogs out and erases the stored session. A new QR scan is required./instance/settingsRead immediate-delivery and webhook settings./instance/settingsReplace the webhook URL and subscribed event list.# 1. Poll until qrDataUrl is non-null
GET /instance/qr
{
"status": "qr",
"qr": "2@...raw pairing value...",
"qrDataUrl": "data:image/png;base64,iVBORw0..."
}
# 2. Display qrDataUrl as an image and scan it in WhatsApp
# 3. Poll GET /instance/me until:
{
"status": "authenticated",
"connected": true,
"phone": "919829057897",
"profileName": "Example Account",
"updatedAt": "2026-09-16T05:30:00.000Z"
}POST /instance/logout unlinks the WhatsApp device and deletes its saved session. Use restart for ordinary recovery.WHATSAPP RESOURCES
/contactsContacts observed by the active connection in {"contacts": [...]}./chatsChats observed by the active connection in {"chats": [...]}./groupsGroups fetched from WhatsApp in {"groups": [...]}, including participant metadata.Contacts and chats use a live connection cache and may be incomplete immediately after connection because full history synchronization is disabled. Groups are fetched live when the connection is available. Treat unrecognized fields as forward-compatible metadata and rely primarily on IDs, names/subjects, and participants.
# First obtain a group ID from GET /groups, then use it as "to"
{
"to": "120363012345678901@g.us",
"body": "Hello, group"
}WEBHOOK SETUP
Configure the URL from the dashboard or replace settings through the API. The URL must be publicly reachable over HTTP or HTTPS. Production endpoints should use HTTPS.
curl --request POST \
"https://buzz.w8mediaworks.com/api/$W8BUZZ_INSTANCE_ID/instance/settings" \
--header "Authorization: Bearer $W8BUZZ_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"webhook_url": "https://app.example.com/webhooks/w8buzz",
"webhook_events": [
"message.created",
"message.received",
"message.ack",
"instance.status"
],
"webhook_download_media": true
}'This operation replaces the event selection. Send an empty URL and empty event array to disable delivery. Set webhook_download_media to true only when your endpoint needs the actual inbound file; image, video, audio, document, and sticker payloads up to 25 MB are then Base64 encoded in data.mediaBase64. Media metadata is supplied even when downloading is off. Accepted aliases are webhookUrl, webhookEvents, and webhookDownloadMedia.
WEBHOOK PAYLOADS
{
"id": "EVT01K5EXAMPLE",
"type": "message.ack",
"instanceId": "WB01K2EXAMPLE",
"createdAt": "2026-09-16T05:30:00Z",
"data": {
"messageId": "MSG01K5EXAMPLE",
"whatsappId": "3EB0A1B2C3D4EXAMPLE",
"status": "delivered"
}
}| Event | When it occurs | Important data fields |
|---|---|---|
message.created | An outbound API message record is created before sending. | messageId, direction, fromMe, type, to, plus the supplied body, caption, mediaUrl, document/audio/location/contact/reaction fields, and referenceId when applicable |
message.received | A new user-visible inbound WhatsApp message arrives. Internal protocol messages are filtered out. | whatsappId, from, to, author, chatId, groupId, messageType, actual body/caption, forwarding, mention, quote and optional media fields |
message.ack | WhatsApp reports sent, delivered, or read progress. | messageId when available, whatsappId, status |
instance.status | The QR, connection, authentication, retry, or logout state changes. | status, connected, phone, profileName, updatedAt, sometimes disconnectCode |
{
"whatsappId": "3EB0A1B2C3D4EXAMPLE",
"from": "919876543210",
"to": "919829057897",
"author": "919876543210",
"chatId": "120363012345678901@g.us",
"groupId": "120363012345678901@g.us",
"isGroup": true,
"pushName": "Example User",
"messageType": "image",
"body": "Invoice attached",
"caption": "Invoice attached",
"fromMe": false,
"isForwarded": false,
"isMentioned": true,
"mentionedIds": ["919829057897@s.whatsapp.net"],
"quotedMessage": {
"whatsappId": "3EB0QUOTED",
"participant": "919800000000@s.whatsapp.net",
"type": "extendedText",
"body": "Please send the invoice"
},
"media": { "included": true, "mimetype": "image/jpeg", "size": 48192 },
"mediaBase64": "/9j/4AAQSkZJRgABAQ...",
"timestamp": 1789612200
}body contains the actual text for text messages and the usable caption for media messages. quotedMsg is retained as an alias of quotedMessage. If a selected media download fails, mediaError explains why while the message event is still delivered.
For a direct chat, from is the sender’s digits-only international phone number whenever WhatsApp supplies a mapping. fromPhone repeats that normalized number and fromJid preserves the technical WhatsApp address. For a group, groupId and chatId contain the @g.us group ID while from and author identify the participant. The dashboard’s Group directory maps each readable group name to that exact ID.
@lid address before a phone mapping exists. Then from and fromJid retain the LID, fromPhone is null, and unresolvedIdentity is true. Do not guess a phone number.Webhook consumers must tolerate additional fields. Use the top-level event id for deduplication because delivery retries reuse the same event record and payload.
WEBHOOK SECURITY
Every request includes X-W8Buzz-Event and X-W8Buzz-Signature. The signature is lowercase hexadecimal HMAC-SHA256 over the exact raw HTTP body, prefixed with sha256=.
X-W8Buzz-Event: message.received
X-W8Buzz-Signature: sha256=HEX_ENCODED_HMAC
expected_hex = HMAC_SHA256(raw_request_body, WEBHOOK_SECRET)$raw = file_get_contents('php://input');
$provided = $_SERVER['HTTP_X_W8BUZZ_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $raw, getenv('W8BUZZ_WEBHOOK_SECRET'));
if (!hash_equals($expected, $provided)) {
http_response_code(401);
exit('Invalid signature');
}
$event = json_decode($raw, true, flags: JSON_THROW_ON_ERROR);import hashlib, hmac, os
from flask import request, abort
raw = request.get_data(cache=True)
expected = hmac.new(os.environ["W8BUZZ_WEBHOOK_SECRET"].encode(), raw, hashlib.sha256).hexdigest()
provided = request.headers.get("X-W8Buzz-Signature", "").removeprefix("sha256=")
if not hmac.compare_digest(expected, provided):
abort(401)
event = request.get_json()import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.post('/webhooks/w8buzz', express.raw({ type: 'application/json' }), (req, res) => {
const expected = 'sha256=' + crypto.createHmac('sha256', process.env.W8BUZZ_WEBHOOK_SECRET).update(req.body).digest('hex');
const provided = req.get('X-W8Buzz-Signature') ?? '';
const valid = expected.length === provided.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(provided));
if (!valid) return res.status(401).send('Invalid signature');
const event = JSON.parse(req.body.toString('utf8'));
res.sendStatus(204);
});WEBHOOK DELIVERY
Any HTTP status from 200 through 299 marks delivery successful. Other responses, connection failures, and the 10-second timeout are retried with exponential backoff—approximately 30 seconds, 60 seconds, 2 minutes, and progressively up to one hour—with a default maximum of eight attempts.
401.id into a unique database column. If it already exists, return success.200 or 204 before doing slow business logic.ERROR RESPONSES
HTTP/1.1 422 Unprocessable Content
Content-Type: application/json
{ "error": "Recipient is not registered on WhatsApp" }| Status | Meaning | Recommended action |
|---|---|---|
401 | Instance ID/token pair is invalid. | Copy both credentials from the same instance. Check whitespace and the Bearer prefix. |
403 | User or instance is suspended. | Ask the platform administrator to reactivate it. |
404 | Endpoint path is not implemented. | Compare the path and HTTP method with this guide. |
409 | WhatsApp instance is not authenticated. | Check /instance/me; scan QR or recover the connection. |
422 | Number, media URL, webhook URL, or payload is invalid. | Correct the request; do not retry unchanged. |
429 | Monthly plan limit reached or traffic throttled. | Stop sending, inspect plan usage, and apply bounded backoff where appropriate. |
500–599 | Gateway, dependency, or temporary server failure. | Log the body and request correlation data; retry only with application-level duplicate protection. |
Automatically retry connection timeouts, 429, and selected 5xx responses with exponential backoff and jitter. Do not retry 401, 403, 404, or 422 without changing something. Because send calls are not idempotent, reconcile uncertain outcomes through your own idempotency record and the message/event history before sending again.
TROUBLESHOOTING
Use the long API instance ID—not Support ID #11011. Copy the token from the same instance. Ensure the header is exactly Authorization: Bearer TOKEN without quotes, line breaks, or extra spaces.
Call GET /instance/me. If connected is false, open the dashboard, scan a current QR, or restart the instance. Only authenticated can send.
Confirm the country code and remove any domestic trunk prefix. For example, use an Indian number as 91 plus its ten-digit mobile number. Test that the number has an active WhatsApp account.
Open the URL without signing in, test it from the server’s network, verify its final response is HTTP 200 within 20 seconds, and keep it below 32 MB. URLs requiring cookies or authorization headers are unsupported.
sent means WhatsApp accepted the message. Enable message.ack, verify webhook signatures, and allow for recipient connectivity and disabled read receipts.
Your endpoint did not return a 2xx response within ten seconds. Verify first, persist the event, return 204, and process it later. Deduplicate using the top-level event id.
These are live in-memory caches and full history sync is disabled. Keep the instance connected and let new activity populate them. Participating groups are fetched separately through GET /groups.
PRODUCTION CHECKLIST
messageId, whatsappId, referenceId, recipient, and request time.instance.status and alert when an instance remains disconnected or retrying.CODEX & AI CODING AGENTS
Share the public OpenAPI URL. Do not paste live credentials into a prompt; let the generated integration read them from environment variables.
Read the W8Buzz guide and OpenAPI specification.
Build a server-side integration that checks instance health,
sends with duplicate protection, stores returned IDs, verifies
raw-body webhook signatures, deduplicates events, handles errors,
and tests the complete workflow. Read credentials only from
environment variables.