Webhooks
Overview
Section titled “Overview”CloudWA receives webhooks from Meta’s WhatsApp Business API and processes them automatically. You can also configure your own webhook endpoints to receive notifications about message events.
Meta Webhook Configuration
Section titled “Meta Webhook Configuration”CloudWA exposes webhook endpoints that you configure in your Meta App settings:
Verification Endpoint
Section titled “Verification Endpoint”GET /api/webhookMeta sends a verification request when setting up webhooks:
| Parameter | Description |
|---|---|
hub.mode | Always “subscribe” |
hub.verify_token | Your configured verify token |
hub.challenge | Challenge string to return |
Event Endpoint
Section titled “Event Endpoint”POST /api/webhookAll WhatsApp events are sent to this endpoint.
Webhook Events
Section titled “Webhook Events”Incoming Message
Section titled “Incoming Message”Triggered when a new message is received.
{ "object": "whatsapp_business_account", "entry": [ { "id": "WHATSAPP_BUSINESS_ACCOUNT_ID", "changes": [ { "value": { "messaging_product": "whatsapp", "metadata": { "display_phone_number": "1234567890", "phone_number_id": "PHONE_NUMBER_ID" }, "contacts": [ { "profile": { "name": "John Doe" }, "wa_id": "1234567890" } ], "messages": [ { "from": "1234567890", "id": "wamid.xxx", "timestamp": "1234567890", "type": "text", "text": { "body": "Hello!" } } ] }, "field": "messages" } ] } ]}Message Status Update
Section titled “Message Status Update”Triggered when a message status changes.
{ "object": "whatsapp_business_account", "entry": [ { "changes": [ { "value": { "statuses": [ { "id": "wamid.xxx", "status": "delivered", "timestamp": "1234567890", "recipient_id": "1234567890" } ] }, "field": "messages" } ] } ]}Status Values
Section titled “Status Values”| Status | Description |
|---|---|
sent | Message sent to WhatsApp servers |
delivered | Message delivered to recipient |
read | Message read by recipient |
failed | Message failed to deliver |
WebSocket Events
Section titled “WebSocket Events”For real-time updates in your frontend, connect to the WebSocket endpoint. Note that authentication must be performed after connection setup by sending an auth message within 5 seconds:
const ws = new WebSocket('wss://dashboard.cloudwa.net/ws');
ws.onopen = () => { // Must authenticate within 5 seconds of connection ws.send(JSON.stringify({ type: 'auth', payload: { token: 'YOUR_JWT_TOKEN' } }));};
ws.onmessage = (event) => { const data = JSON.parse(event.data); console.log('Event:', data.type, data.payload);};Event Types
Section titled “Event Types”| Event | Description |
|---|---|
message:new | New message received |
message:status | Message status updated |
contact:new | New contact created |
contact:updated | Contact information updated |
Message Event Payload
Section titled “Message Event Payload”{ "type": "message:new", "payload": { "id": "uuid", "contact_id": "uuid", "direction": "incoming", "type": "text", "content": { "text": "Hello!" }, "timestamp": "2024-01-01T12:00:00Z" }}Security
Section titled “Security”Webhook Verification
Section titled “Webhook Verification”Always verify webhook requests are from Meta:
- Check the
X-Hub-Signature-256header - Compute HMAC-SHA256 of the request body using your app secret
- Compare with the signature in the header
CloudWA handles this verification automatically.
Rate Limiting
Section titled “Rate Limiting”Meta may send webhooks at high volumes during campaigns. CloudWA:
- Processes webhooks asynchronously
- Queues events in Redis for processing
- Handles duplicate events gracefully
Webhook Management API
Section titled “Webhook Management API”Manage webhook subscriptions to receive CloudWA events at your own external endpoints.
List Webhooks
Section titled “List Webhooks”Get all configured webhooks for your organization.
GET /api/webhooksQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
search | string | Filter by name or URL (case-insensitive) |
page | integer | Page number for pagination (default: 1) |
limit | integer | Items per page (default: 50) |
Response
Section titled “Response”{ "status": "success", "data": { "webhooks": [ { "id": "uuid", "name": "My Endpoint", "url": "https://api.my-app.com/webhooks/whatsapp", "events": ["message:incoming", "contact:created"], "headers": { "Authorization": "Bearer token123" }, "is_active": true, "has_secret": true, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ], "available_events": [ { "value": "message:incoming", "label": "Message Incoming", "description": "When a new message is received from a contact" }, { "value": "message:sent", "label": "Message Sent", "description": "When an agent sends a message" }, { "value": "contact:created", "label": "Contact Created", "description": "When a new contact is created" }, { "value": "transfer:created", "label": "Transfer Created", "description": "When a transfer to human agent is requested" }, { "value": "transfer:assigned", "label": "Transfer Assigned", "description": "When a transfer is assigned to an agent" }, { "value": "transfer:resumed", "label": "Transfer Resumed", "description": "When chatbot is resumed (transfer closed)" } ], "total": 1, "page": 1, "limit": 50 }}Create Webhook
Section titled “Create Webhook”Register a new webhook subscription.
POST /api/webhooksRequest Body
Section titled “Request Body”{ "name": "My Endpoint", "url": "https://api.my-app.com/webhooks/whatsapp", "events": ["message:incoming", "contact:created"], "headers": { "Authorization": "Bearer token123" }, "secret": "my-hmac-secret-key", "is_active": true}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Friendly name for the webhook |
url | string | Yes | The URL that will receive the webhook POST payloads |
events | array | Yes | List of events to subscribe to (e.g. message:incoming, contact:created) |
headers | object | No | Custom HTTP headers sent with the webhook request |
secret | string | No | HMAC-SHA256 verification secret (auto-generated if omitted) |
is_active | boolean | No | Active status of the webhook subscription |
Response
Section titled “Response”{ "status": "success", "data": { "id": "uuid", "name": "My Endpoint", "url": "https://api.my-app.com/webhooks/whatsapp", "events": ["message:incoming", "contact:created"], "headers": { "Authorization": "Bearer token123" }, "is_active": true, "has_secret": true, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" }}Get Webhook
Section titled “Get Webhook”Get details of a webhook subscription.
GET /api/webhooks/{id}Path Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
id | string | The unique UUID of the webhook |
Response
Section titled “Response”{ "status": "success", "data": { "id": "uuid", "name": "My Endpoint", "url": "https://api.my-app.com/webhooks/whatsapp", "events": ["message:incoming", "contact:created"], "headers": { "Authorization": "Bearer token123" }, "is_active": true, "has_secret": true, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" }}Update Webhook
Section titled “Update Webhook”Update an existing webhook subscription.
PUT /api/webhooks/{id}Path Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
id | string | The unique UUID of the webhook |
Request Body
Section titled “Request Body”{ "name": "Updated Endpoint Name", "is_active": false}Response
Section titled “Response”{ "status": "success", "data": { "id": "uuid", "name": "Updated Endpoint Name", "url": "https://api.my-app.com/webhooks/whatsapp", "events": ["message:incoming", "contact:created"], "headers": { "Authorization": "Bearer token123" }, "is_active": false, "has_secret": true, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" }}Test Webhook
Section titled “Test Webhook”Send a synchronous test event to verify your webhook endpoint is responding correctly.
POST /api/webhooks/{id}/testPath Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
id | string | The unique UUID of the webhook |
Response
Section titled “Response”{ "status": "success", "data": { "message": "Test webhook sent successfully" }}Delete Webhook
Section titled “Delete Webhook”Remove a webhook subscription.
DELETE /api/webhooks/{id}Path Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
id | string | The unique UUID of the webhook |
Response
Section titled “Response”{ "status": "success", "data": { "message": "Webhook deleted successfully" }}