W8W8Buzz

W8BUZZ DEVELOPER PLATFORM · VERSION 2.0.6

From credentials to a delivered message, in one guide.

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.

Download OpenAPI 3.1
Base URLhttps://buzz.w8mediaworks.com/api/{INSTANCE_ID}
Before production: obtain recipient consent, respect opt-outs, protect credentials, and test with dedicated numbers before sending customer traffic.

FIRST REQUEST CHECKLIST

Complete these six steps in order

  1. Create an instance.Sign in, open Instances, select New instance, give it a recognizable name, and save it.
  2. Connect WhatsApp.Open Show QR and scan it from WhatsApp → Linked devices. Wait until the instance says authenticated.
  3. Copy the correct credentials.Open Credentials. Copy the API instance ID and API token. Do not use the five-digit Support ID in an API URL.
  4. Store credentials server-side.Put the base URL, instance ID, and token in environment variables. Never embed the token in public JavaScript, a mobile app, or a repository.
  5. Send to a valid test number.Use the full international number as digits only, including country code: 919829057897, not a local number.
  6. Save IDs and enable webhooks.Store the returned W8Buzz messageId and WhatsApp whatsappId. Use signed webhooks for delivery/read updates and incoming messages.
Ready means authenticated. Creating an instance is not enough. Message sends return 409 until its status is authenticated.

CREDENTIALS

Four identifiers with different purposes

API instance IDWB01K2…

Used in every API URL. It is a long public identifier and is not secret.

API tokenw8_f578…

Sent as a bearer token. Treat it like a password. It can be viewed or regenerated from the Credentials dialog.

Support ID#11011

A short human reference for support conversations. Never put it in an API URL.

Webhook secret64 hex characters

Verifies that webhook requests were sent by W8Buzz. It is not the API token.

Recommended environment variables

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_SECRET

AUTHENTICATION

Send one bearer token on every request

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/json

Content-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.

Keep it server-side. Calls from a browser expose the token to visitors. Send requests from PHP, Python, Node.js, your backend framework, or a protected server function.

FORMATS & CONVENTIONS

Rules that prevent most first-request failures

ValueRequired formatExample
Direct recipientFull international number, country code included. Digits-only is safest. No domestic trunk prefix.919829057897
Group recipientWhatsApp group JID returned by GET /groups.1203630…@g.us
Dates from W8BuzzAPI lists may contain UTC database timestamps; webhook envelopes use ISO 8601 UTC.2026-09-16T01:02:03Z
Media URLPublic http:// or https:// URL reachable by the W8Buzz server, up to 32 MB.https://cdn.example.com/a.jpg
referenceIdYour optional correlation value, such as an order or ticket ID.order-1042

Reference IDs are not idempotency keys

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.

Immediate delivery mode

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

Send the same text from four common environments

cURL

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 8 with cURL

<?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'];

Python 3 with requests

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"])

Node.js 18+ / TypeScript

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

What a successful send means

HTTP/1.1 200 OK
Content-Type: application/json

{
  "sent": true,
  "messageId": "MSG01K5EXAMPLE",
  "whatsappId": "3EB0A1B2C3D4EXAMPLE",
  "recipient": "919829057897@s.whatsapp.net",
  "status": "sent"
}
messageId

W8Buzz’s durable ID. Store it and use it to correlate event viewer records and webhook events.

whatsappId

WhatsApp’s message identifier. Delivery/read acknowledgements refer to it.

recipient

The normalized WhatsApp JID actually used for delivery.

status: sent

The 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

POST /messages/chat

FieldTypeRequiredDescription
tostringYesDirect international number or a group JID.
bodystringYesNon-empty UTF-8 message text.
referenceIdstringNoYour 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

Images, video, audio, and documents

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.

POST/messages/imageto, url; optional caption
POST/messages/videoto, url; optional caption
POST/messages/audioto, url; optional mimetype, ptt
POST/messages/documentto, url; optional filename, mimetype, caption

Image

{
  "to": "919829057897",
  "url": "https://cdn.example.com/invoices/preview.jpg",
  "caption": "Invoice preview",
  "referenceId": "invoice-2026-0042"
}

Document

{
  "to": "919829057897",
  "url": "https://cdn.example.com/invoices/42.pdf",
  "filename": "invoice-42.pdf",
  "mimetype": "application/pdf",
  "caption": "Your invoice is attached"
}

Voice-note style audio

{
  "to": "919829057897",
  "url": "https://cdn.example.com/audio/update.mp3",
  "mimetype": "audio/mpeg",
  "ptt": true
}
When media fails: test the URL from the W8Buzz server, confirm that redirects end at HTTP 200, check the 32 MB limit, and provide the correct MIME type for documents and audio.

STRUCTURED MESSAGES

Location, contact, and reaction payloads

POST /messages/location

{
  "to": "919829057897",
  "latitude": 28.6139,
  "longitude": 77.2090,
  "name": "Meeting point",
  "address": "Connaught Place, New Delhi"
}

POST /messages/contact

{
  "to": "919829057897",
  "name": "W8Buzz Support",
  "vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:W8Buzz Support\nTEL;TYPE=CELL:+919829057897\nEND:VCARD"
}

POST /messages/reaction

{
  "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

List retained events and aggregate statuses

GET /messages

GET /messages?limit=25&status=all&sort=desc
ParameterAllowed valuesDefault
limit1–10025
statusall, processing, sent, delivered, read, received, failed, invalid, expiredall
sortasc or descdesc
{
  "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"
  }]
}

GET /messages/statistics

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

Know whether the connection is ready

GET/instance/statusStored connection state, instance ID, and last-seen timestamp.
GET/instance/qrPairing state, raw QR value, and browser-ready PNG data URL.
GET/instance/meLive status, connected boolean, phone, profile name, and update time.
POST/instance/restartReplaces the current socket while preserving the saved WhatsApp session.
POST/instance/logoutLogs out and erases the stored session. A new QR scan is required.
GET/instance/settingsRead immediate-delivery and webhook settings.
POST/instance/settingsReplace the webhook URL and subscribed event list.

Status values

initialize Newly createdqr Waiting for QR scanconnecting Opening a socketauthenticated Ready to sendretrying Recovering connectiondisconnected Logged out/offlinestandby Socket not activesuspended Disabled by administrator

Pairing flow through the API

# 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"
}
Logout is destructive. POST /instance/logout unlinks the WhatsApp device and deletes its saved session. Use restart for ordinary recovery.

WHATSAPP RESOURCES

Contacts, chats, and participating groups

GET/contactsContacts observed by the active connection in {"contacts": [...]}.
GET/chatsChats observed by the active connection in {"chats": [...]}.
GET/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.

Send to a group

# First obtain a group ID from GET /groups, then use it as "to"
{
  "to": "120363012345678901@g.us",
  "body": "Hello, group"
}

WEBHOOK SETUP

Subscribe to the events your backend needs

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

A stable envelope around event-specific data

{
  "id": "EVT01K5EXAMPLE",
  "type": "message.ack",
  "instanceId": "WB01K2EXAMPLE",
  "createdAt": "2026-09-16T05:30:00Z",
  "data": {
    "messageId": "MSG01K5EXAMPLE",
    "whatsappId": "3EB0A1B2C3D4EXAMPLE",
    "status": "delivered"
  }
}
EventWhen it occursImportant data fields
message.createdAn 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.receivedA 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.ackWhatsApp reports sent, delivered, or read progress.messageId when available, whatsappId, status
instance.statusThe QR, connection, authentication, retry, or logout state changes.status, connected, phone, profileName, updatedAt, sometimes disconnectCode

Complete inbound content example

{
  "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.

Direct senders, groups, and WhatsApp LIDs

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.

Unresolved identities: WhatsApp can occasionally provide only a privacy-preserving @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

Verify the untouched request bytes before parsing JSON

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)

PHP

$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);

Python / Flask

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()

Node.js / Express

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

Acknowledge quickly, then process asynchronously

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.

  1. Verify signature.Reject invalid requests with 401.
  2. Deduplicate.Insert the event id into a unique database column. If it already exists, return success.
  3. Persist work.Save the event or enqueue it in your own worker system.
  4. Return promptly.Respond with 200 or 204 before doing slow business logic.
Delivery order: network retries and different event types can arrive later than expected. Make handlers idempotent and use message status progression rather than assuming strict arrival order.

ERROR RESPONSES

Always inspect both HTTP status and JSON

HTTP/1.1 422 Unprocessable Content
Content-Type: application/json

{ "error": "Recipient is not registered on WhatsApp" }
StatusMeaningRecommended action
401Instance ID/token pair is invalid.Copy both credentials from the same instance. Check whitespace and the Bearer prefix.
403User or instance is suspended.Ask the platform administrator to reactivate it.
404Endpoint path is not implemented.Compare the path and HTTP method with this guide.
409WhatsApp instance is not authenticated.Check /instance/me; scan QR or recover the connection.
422Number, media URL, webhook URL, or payload is invalid.Correct the request; do not retry unchanged.
429Monthly plan limit reached or traffic throttled.Stop sending, inspect plan usage, and apply bounded backoff where appropriate.
500–599Gateway, dependency, or temporary server failure.Log the body and request correlation data; retry only with application-level duplicate protection.

Safe retry pattern

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

Diagnose common failures in under a minute

“Invalid instance or token”

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.

“Instance is not authenticated”

Call GET /instance/me. If connected is false, open the dashboard, scan a current QR, or restart the instance. Only authenticated can send.

“Recipient is not registered on WhatsApp”

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.

Media download failed

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.

The send returned 200 but I have no delivery receipt

sent means WhatsApp accepted the message. Enable message.ack, verify webhook signatures, and allow for recipient connectivity and disabled read receipts.

Webhook is delivered repeatedly

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.

Contacts or chats are empty

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

Before sending customer traffic

  • Keep instance tokens and webhook secrets in a secret manager or protected environment variables.
  • Use HTTPS for your application and webhook endpoint.
  • Implement consent, opt-out, frequency limits, and suppression lists.
  • Store messageId, whatsappId, referenceId, recipient, and request time.
  • Verify webhook signatures against raw bytes and deduplicate event IDs.
  • Use connection/read timeouts; apply bounded retry with jitter only where safe.
  • Monitor instance.status and alert when an instance remains disconnected or retrying.
  • Do not use raw W8Buzz events as a permanent archive. Normal events follow the configured cleanup policy; API-created messages and related delivery events have a mandatory minimum retention of 14 days.
  • Validate media URLs and avoid exposing permanently public customer files.
  • Use dedicated WhatsApp test numbers before enabling production workflows.

CODEX & AI CODING AGENTS

Give your coding agent the contract and acceptance criteria

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.