Webhook Documentation

Real-time event notifications for your WhatsApp accounts

Overview

WMAM webhooks allow you to receive real-time HTTP POST notifications when events occur in your WhatsApp accounts. When an event is triggered, we'll send an HTTP POST request to your configured webhook URL with a JSON payload containing event details.

Use Cases: Log messages to your CRM, trigger automations, sync data with external systems, monitor group activity, etc.

Setup

1. Create a Webhook Endpoint

Your webhook endpoint should:

  • Accept HTTP POST requests
  • Return a 2xx status code within 5 seconds
  • Use HTTPS (recommended for production)
  • Verify the webhook signature (optional but recommended)

2. Register Your Webhook

Use the API or dashboard to register your webhook:

POST /api/webhooks Content-Type: application/json Authorization: Bearer YOUR_ACCESS_TOKEN { "name": "My CRM Integration", "url": "https://your-domain.com/webhook", "events": ["message_received", "message_sent"], "secret": "your_webhook_secret_key" }

Supported Events

Event Description Trigger
message_received A new message was received When any message arrives in a monitored group or private chat
message_sent A message was sent successfully When your account sends a message
connection_update Connection status changed When account connects/disconnects
group_participants_update Group member changes When members join/leave a group

Payload Structure

Common Fields (All Events)

{ "event": "message_received", // Event type "timestamp": "2026-02-09T14:30:00Z", // ISO 8601 timestamp "accountId": "main", // Your WhatsApp account ID "userId": "6987c2e528fe091d2e95a8c8", // Your user ID "webhookId": "webhook_abc123" // Webhook identifier }

message_received Event

{ "event": "message_received", "timestamp": "2026-02-09T14:30:00Z", "accountId": "main", "userId": "6987c2e528fe091d2e95a8c8", "webhookId": "webhook_abc123", "data": { "messageId": "3EB0C0123456789ABCDEF", "from": "212612345678@s.whatsapp.net", "fromName": "John Doe", "chatId": "212612345678@s.whatsapp.net", "chatName": "John Doe", "isGroup": false, "messageType": "text", "text": "Hello, how are you?", "timestamp": 1707487800, "hasMedia": false } }

message_received Event (Group Message)

{ "event": "message_received", "timestamp": "2026-02-09T14:30:00Z", "accountId": "main", "userId": "6987c2e528fe091d2e95a8c8", "webhookId": "webhook_abc123", "data": { "messageId": "3EB0C0987654321FEDCBA", "from": "212698765432@s.whatsapp.net", "fromName": "Jane Smith", "chatId": "120363313524633508@g.us", "chatName": "Project Team", "isGroup": true, "messageType": "text", "text": "Meeting at 3pm", "timestamp": 1707487800, "hasMedia": false, "groupMetadata": { "subject": "Project Team", "participantCount": 25 } } }

message_received Event (With Media)

{ "event": "message_received", "timestamp": "2026-02-09T14:30:00Z", "accountId": "main", "data": { "messageId": "3EB0C0ABCDEF123456789", "from": "212612345678@s.whatsapp.net", "fromName": "Alice", "chatId": "212612345678@s.whatsapp.net", "isGroup": false, "messageType": "image", "caption": "Check this out!", "timestamp": 1707487800, "hasMedia": true, "media": { "type": "image", "mimetype": "image/jpeg", "size": 245760, "filename": "photo.jpg" } } }

message_sent Event

{ "event": "message_sent", "timestamp": "2026-02-09T14:31:00Z", "accountId": "main", "userId": "6987c2e528fe091d2e95a8c8", "webhookId": "webhook_abc123", "data": { "messageId": "3EB0C0SENT123456789", "to": "212612345678@s.whatsapp.net", "toName": "John Doe", "messageType": "text", "text": "Thank you for your message!", "status": "sent", "timestamp": 1707487860 } }

connection_update Event

{ "event": "connection_update", "timestamp": "2026-02-09T15:00:00Z", "accountId": "main", "userId": "6987c2e528fe091d2e95a8c8", "webhookId": "webhook_abc123", "data": { "connection": "open", "status": "connected", "phoneNumber": "212612345678", "legacyConnection": false } }

group_participants_update Event

{ "event": "group_participants_update", "timestamp": "2026-02-09T16:00:00Z", "accountId": "main", "userId": "6987c2e528fe091d2e95a8c8", "webhookId": "webhook_abc123", "data": { "groupId": "120363313524633508@g.us", "groupName": "Project Team", "action": "add", "participants": [ "212698765432@s.whatsapp.net" ], "author": "212612345678@s.whatsapp.net" } }

Field Reference

Message Fields

Field Type Description
messageId string Unique message identifier from WhatsApp
from string Sender's WhatsApp JID (e.g., "212612345678@s.whatsapp.net")
fromName string Sender's display name
chatId string Chat JID - private: "NUMBER@s.whatsapp.net", group: "ID@g.us"
chatName string Chat display name (contact name or group name)
isGroup boolean true if message is from a group, false for private chat
messageType string "text", "image", "video", "audio", "document", "sticker", etc.
text string Message text content (if type is text or has caption)
caption string Media caption (if media message has text)
timestamp number Unix timestamp (seconds since epoch)
hasMedia boolean true if message contains media (image, video, etc.)

Media Fields

Field Type Description
media.type string "image", "video", "audio", "document", "sticker"
media.mimetype string MIME type (e.g., "image/jpeg", "video/mp4")
media.size number File size in bytes
media.filename string Original filename (if available)

Connection Status Values

Status Description
connecting Attempting to connect to WhatsApp
open Successfully connected and ready
close Disconnected from WhatsApp

Group Participant Actions

Action Description
add Participants were added to the group
remove Participants were removed from the group
promote Participants were promoted to admin
demote Participants were demoted from admin

Security & Verification

Webhook Signature

Each webhook request includes an X-Webhook-Signature header containing an HMAC-SHA256 signature. Use this to verify the request came from WMAM.

Verification Example (Node.js)

const crypto = require('crypto'); function verifyWebhookSignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(JSON.stringify(payload)) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) ); } // Express.js example app.post('/webhook', express.json(), (req, res) => { const signature = req.headers['x-webhook-signature']; const secret = 'your_webhook_secret_key'; if (!verifyWebhookSignature(req.body, signature, secret)) { return res.status(401).json({ error: 'Invalid signature' }); } // Process webhook console.log('Event:', req.body.event); res.status(200).json({ received: true }); });

Verification Example (Python)

import hmac import hashlib import json from flask import Flask, request, jsonify app = Flask(__name__) def verify_webhook_signature(payload, signature, secret): expected_signature = hmac.new( secret.encode('utf-8'), json.dumps(payload).encode('utf-8'), hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature, expected_signature) @app.route('/webhook', methods=['POST']) def webhook(): signature = request.headers.get('X-Webhook-Signature') secret = 'your_webhook_secret_key' if not verify_webhook_signature(request.json, signature, secret): return jsonify({'error': 'Invalid signature'}), 401 # Process webhook print('Event:', request.json['event']) return jsonify({'received': True})
Security Best Practices: Always verify signatures, use HTTPS in production, keep your secret key secure, implement rate limiting on your endpoint.

Retry Logic & Error Handling

Delivery Attempts

If your webhook endpoint doesn't respond with a 2xx status code, WMAM will retry:

  • 1st retry: after 1 minute
  • 2nd retry: after 5 minutes
  • 3rd retry: after 30 minutes
  • After 3 failed attempts, the webhook will be disabled

Timeout

Your endpoint must respond within 5 seconds. Longer responses will be treated as failures.

Status Codes

  • 200-299: Success - webhook acknowledged
  • 400-499: Client error - no retry (except 429)
  • 429: Rate limited - will retry
  • 500-599: Server error - will retry

Testing Your Webhook

1. Use a Test Endpoint

For development, use services like:

2. Test Via API

Send a test event to your webhook:

POST /api/webhooks/:webhookId/test Authorization: Bearer YOUR_ACCESS_TOKEN Response: { "success": true, "message": "Test webhook sent", "statusCode": 200 }

3. Check Logs

View webhook delivery logs in the dashboard under Webhooks → History.

Rate Limits

Plan Webhooks Delivery Rate
Free 2 webhooks 10 requests/min
Pro 10 webhooks 100 requests/min
Premium Unlimited 1000 requests/min

Need help with webhooks?