Skip to content

WhatsApp Webhook Format Reference ​

v1.6.0+

Complete technical reference for WhatsApp webhook payloads forwarded by WhatsMarkSaaS to external endpoints like N8N, Zapier, and Make.com.

Overview ​

This document provides the complete specification for WhatsApp webhook payloads in N8N format. All webhooks follow a consistent structure regardless of event type.

Audience

This reference is for developers building custom integrations. If you're using N8N, Zapier, or Make.com, see the WhatsApp Webhook Forwarding Guide instead.

Base Payload Structure ​

All WhatsApp webhooks follow this standard structure:

typescript
interface WhatsAppWebhookPayload {
  event: EventObject;
  tenant: TenantObject;
  data: DataObject;
  whatsapp: WhatsAppObject;
  metadata: MetadataObject;
}

Complete Schema ​

json
{
  "event": {
    "id": "string",              // Format: evt_{timestamp}_{random}
    "type": "string",            // Event type (see Event Types section)
    "timestamp": "string",       // ISO 8601 datetime
    "version": "string"          // Format version (currently "1.0")
  },
  "tenant": {
    "id": number,               // Tenant ID
    "name": "string"            // Tenant/company name
  },
  "data": {
    "resource": {
      "type": "string",         // Resource type: message, status, account, etc.
      "id": "string|null",      // Resource identifier (message ID, etc.)
      "attributes": object      // Resource-specific attributes
    },
    "relationships": object     // Related entities (contact, metadata, etc.)
  },
  "whatsapp": {
    "original_payload": object  // Complete original WhatsApp webhook
  },
  "metadata": {
    "source": "whatsapp_webhook_forward",
    "environment": "string",    // production, staging, etc.
    "request_id": "string"      // UUID for request tracing
  }
}

Event Object ​

Contains event metadata and identification.

typescript
interface EventObject {
  id: string; // Unique event identifier
  type: string; // Event type (see Event Types)
  timestamp: string; // ISO 8601 timestamp
  version: string; // Payload format version
}

Event ID Format ​

evt_{unix_timestamp}_{random_string}

Example: evt_1767263928_7KGQvXqbFF

Event Types ​

All possible event types:

typescript
type WhatsAppEventType =
  // Message Events
  | 'whatsapp.message.received'
  | 'whatsapp.message.sent'
  | 'whatsapp.message.delivered'
  | 'whatsapp.message.read'
  | 'whatsapp.message.failed'

  // Status Events
  | 'whatsapp.status.updated'

  // Account Events
  | 'whatsapp.account.alert'
  | 'whatsapp.account.review_updated'
  | 'whatsapp.account.updated'

  // Business Events
  | 'whatsapp.business.capability_updated'
  | 'whatsapp.business.status_updated'

  // Template Events
  | 'whatsapp.template.status_updated'
  | 'whatsapp.template.quality_updated'

  // Phone Events
  | 'whatsapp.phone.quality_updated'
  | 'whatsapp.phone.name_updated'

  // Other Events
  | 'whatsapp.call.received'
  | 'whatsapp.flow.event';

Tenant Object ​

Multi-tenancy context information.

typescript
interface TenantObject {
  id: number; // Tenant identifier
  name: string; // Tenant/company name
}

Example:

json
{
  "id": 3,
  "name": "Acme Corporation"
}

Data Object ​

Contains the actual event data and relationships.

typescript
interface DataObject {
  resource: ResourceObject;
  relationships: RelationshipsObject;
}

Resource Object ​

typescript
interface ResourceObject {
  type: string; // Resource type
  id: string | null; // Resource identifier
  attributes: object; // Resource-specific data
}

Relationships Object ​

Related entities vary by resource type. Common relationships:

typescript
interface RelationshipsObject {
  contact?: ContactRelationship;
  metadata?: MetadataRelationship;
  [key: string]: any;
}

WhatsApp Object ​

Contains the complete original WhatsApp webhook payload.

typescript
interface WhatsAppObject {
  original_payload: {
    object: string;
    entry: Array<{
      id: string;
      changes: Array<{
        value: object;
        field: string;
      }>;
    }>;
  };
}

Metadata Object ​

Request tracking and environment information.

typescript
interface MetadataObject {
  source: 'whatsapp_webhook_forward';
  environment: string; // production, staging, development
  request_id: string; // UUID for tracing
}

Event Type Details ​

Message Events ​

whatsapp.message.received ​

Incoming message from customer.

Payload Example:

json
{
  "event": {
    "id": "evt_1767263928_abc123",
    "type": "whatsapp.message.received",
    "timestamp": "2026-01-01T10:38:48+00:00",
    "version": "1.0"
  },
  "tenant": {
    "id": 3,
    "name": "Acme Corp"
  },
  "data": {
    "resource": {
      "type": "message",
      "id": "wamid.HBgMOTE5OTI1MTE5Mjg0FQIAEhgWM0VCMDE1NDRCMTFBMDQ1RTlFM0NFMwA=",
      "attributes": {
        "message_id": "wamid.HBgMOTE5OTI1MTE5Mjg0FQIAEhgWM0VCMDE1NDRCMTFBMDQ1RTlFM0NFMwA=",
        "from": "919876543210",
        "timestamp": "1767263926",
        "type": "text",
        "text": "Hello, I need help!",
        "context": null
      }
    },
    "relationships": {
      "contact": {
        "wa_id": "919876543210",
        "name": "John Doe"
      },
      "metadata": {
        "phone_number_id": "339141689277134",
        "display_phone_number": "919428735270"
      }
    }
  },
  "whatsapp": {
    "original_payload": {
      /* Full WhatsApp payload */
    }
  },
  "metadata": {
    "source": "whatsapp_webhook_forward",
    "environment": "production",
    "request_id": "595bbcf8-93bf-418b-8209-3343c76ad852"
  }
}

Message Types:

  • text - Plain text message
  • image - Image with optional caption
  • video - Video with optional caption
  • audio - Audio/voice message
  • document - Document/file
  • location - Location coordinates
  • contacts - Contact card
  • sticker - Sticker
  • interactive - Button/list responses
  • button - Quick reply button
  • order - Order message

**Text Message Attributes:

typescript
{
  message_id: string;
  from: string;           // Phone number with country code
  timestamp: string;      // Unix timestamp
  type: "text";
  text: string;          // Message text
  context: {             // Reply context (if replying)
    from: string;
    id: string;
  } | null;
}

Image Message Attributes:

typescript
{
  message_id: string;
  from: string;
  timestamp: string;
  type: "image";
  image: {
    id: string;         // Media ID
    mime_type: string;
    sha256: string;
    caption?: string;
  };
  context: object | null;
}

Document Message Attributes:

typescript
{
  message_id: string;
  from: string;
  timestamp: string;
  type: "document";
  document: {
    id: string;
    filename: string;
    mime_type: string;
    sha256: string;
    caption?: string;
  };
  context: object | null;
}

Location Message Attributes:

typescript
{
  message_id: string;
  from: string;
  timestamp: string;
  type: "location";
  location: {
    latitude: number;
    longitude: number;
    name?: string;
    address?: string;
  };
  context: object | null;
}

whatsapp.message.sent ​

Message sent by your business (echo event).

Payload Structure: Same as message.received but triggered when your business sends a message.

Note: The from field will be your business phone number.

whatsapp.message.delivered ​

Message delivered to customer's device.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.message.delivered",
    "timestamp": "2026-01-01T10:39:00+00:00"
  },
  "data": {
    "resource": {
      "type": "status",
      "id": "wamid.xxx",
      "attributes": {
        "status": "delivered",
        "timestamp": "1767264000",
        "recipient_id": "919876543210",
        "conversation": {
          "id": "conv_id",
          "origin": {
            "type": "user_initiated"
          }
        }
      }
    }
  }
}

Status Values:

  • sent - Message sent from your server
  • delivered - Delivered to customer's device
  • read - Customer read the message
  • failed - Delivery failed

whatsapp.message.read ​

Customer read your message (blue checkmarks).

Payload Structure: Similar to message.delivered with status: "read".

whatsapp.message.failed ​

Message delivery failed.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.message.failed"
  },
  "data": {
    "resource": {
      "type": "status",
      "attributes": {
        "status": "failed",
        "timestamp": "1767264000",
        "recipient_id": "919876543210",
        "errors": [
          {
            "code": 131047,
            "title": "Re-engagement message",
            "message": "Re-engagement message is outside the customer service window."
          }
        ]
      }
    }
  }
}

Template Events ​

whatsapp.template.status_updated ​

Message template approval status changed.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.template.status_updated"
  },
  "data": {
    "resource": {
      "type": "template",
      "id": null,
      "attributes": {
        "event": "APPROVED",
        "message_template_id": "1234567890",
        "message_template_name": "welcome_message",
        "message_template_language": "en",
        "reason": null
      }
    }
  }
}

Status Values:

  • APPROVED - Template approved and active
  • REJECTED - Template rejected
  • PENDING - Under review
  • PAUSED - Template paused
  • DISABLED - Template disabled

Rejection Reasons: When status is REJECTED, reason field contains explanation.

whatsapp.template.quality_updated ​

Template quality score changed.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.template.quality_updated"
  },
  "data": {
    "resource": {
      "type": "template_quality",
      "attributes": {
        "message_template_id": "1234567890",
        "message_template_name": "welcome_message",
        "message_template_language": "en",
        "quality_score": "GREEN",
        "previous_quality_score": "YELLOW"
      }
    }
  }
}

Quality Scores:

  • GREEN - High quality
  • YELLOW - Medium quality
  • RED - Low quality (at risk)
  • UNKNOWN - Not enough data

Account Events ​

whatsapp.account.alert ​

Account alert or warning.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.account.alert"
  },
  "data": {
    "resource": {
      "type": "account_alert",
      "attributes": {
        "alert_type": "ACCOUNT_UPDATE",
        "description": "Your phone number quality is low",
        "severity": "WARNING"
      }
    }
  }
}

Alert Types:

  • ACCOUNT_UPDATE - Account information updated
  • ACCOUNT_REVIEW - Account under review
  • BUSINESS_CAPABILITY_UPDATE - Capability changed
  • TEMPLATE_QUALITY_UPDATE - Template quality alert

Severity Levels:

  • INFO - Informational
  • WARNING - Warning
  • CRITICAL - Critical issue

whatsapp.account.review_updated ​

Account review status changed.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.account.review_updated"
  },
  "data": {
    "resource": {
      "type": "account_review",
      "attributes": {
        "review_status": "APPROVED",
        "previous_status": "PENDING"
      }
    }
  }
}

whatsapp.business.capability_updated ​

Business account capabilities changed.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.business.capability_updated"
  },
  "data": {
    "resource": {
      "type": "business_capability",
      "attributes": {
        "capability": "MESSAGE_TEMPLATES",
        "status": "AVAILABLE",
        "previous_status": "RESTRICTED"
      }
    }
  }
}

Capabilities:

  • MESSAGE_TEMPLATES - Template messaging
  • BUSINESS_INITIATED_CONVERSATIONS - Initiate conversations
  • UNLIMITED_CONVERSATIONS - No conversation limits

Phone Events ​

whatsapp.phone.quality_updated ​

Phone number quality rating changed.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.phone.quality_updated"
  },
  "data": {
    "resource": {
      "type": "phone_quality",
      "attributes": {
        "phone_number": "919428735270",
        "quality_score": "GREEN",
        "previous_quality_score": "YELLOW"
      }
    }
  }
}

Quality Scores:

  • GREEN - High quality (good)
  • YELLOW - Medium quality (warning)
  • RED - Low quality (at risk)
  • UNKNOWN - Not determined

whatsapp.phone.name_updated ​

Display name updated.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.phone.name_updated"
  },
  "data": {
    "resource": {
      "type": "phone_name",
      "attributes": {
        "phone_number": "919428735270",
        "display_name": "Acme Corp Support",
        "previous_name": "Acme Support"
      }
    }
  }
}

Other Events ​

whatsapp.call.received ​

Incoming WhatsApp call.

Payload Example:

json
{
  "event": {
    "type": "whatsapp.call.received"
  },
  "data": {
    "resource": {
      "type": "call",
      "id": "call_id_xxx",
      "attributes": {
        "from": "919876543210",
        "timestamp": "1767264000"
      }
    },
    "relationships": {
      "contact": {
        "wa_id": "919876543210",
        "name": "John Doe"
      }
    }
  }
}

HTTP Headers ​

All webhook requests include these headers:

Content-Type: application/json
Accept: application/json
User-Agent: whatsmark-Webhook/1.0
X-Webhook-Signature: <hmac-sha256-signature>
X-Webhook-Event: <event-type>
X-Webhook-Timestamp: <iso-8601-timestamp>
X-Webhook-Format: n8n

Header Details ​

HeaderDescriptionExample
X-Webhook-SignatureHMAC-SHA256 signaturea1b2c3...
X-Webhook-EventEvent typewhatsapp.message.received
X-Webhook-TimestampEvent timestamp2026-01-01T10:38:48+00:00
X-Webhook-FormatPayload formatn8n

Signature Verification ​

Algorithm ​

signature = HMAC-SHA256(payload_json, secret_key)

Node.js Implementation ​

javascript
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)
  );
}

// Usage
const payload = req.body;
const signature = req.headers['x-webhook-signature'];
const secret = process.env.WEBHOOK_SECRET;

if (!verifyWebhookSignature(payload, signature, secret)) {
  return res.status(403).json({ error: 'Invalid signature' });
}

PHP Implementation ​

php
<?php
function verifyWebhookSignature($payload, $signature, $secret) {
    $expectedSignature = hash_hmac(
        'sha256',
        json_encode($payload),
        $secret
    );

    return hash_equals($signature, $expectedSignature);
}

// Usage
$payload = json_decode(file_get_contents('php://input'), true);
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$secret = getenv('WEBHOOK_SECRET');

if (!verifyWebhookSignature($payload, $signature, $secret)) {
    http_response_code(403);
    echo json_encode(['error' => 'Invalid signature']);
    exit;
}

Testing ​

Sample Payloads ​

Text Message:

json
{
  "event": {
    "id": "evt_test_12345",
    "type": "whatsapp.message.received",
    "timestamp": "2026-01-01T10:00:00Z",
    "version": "1.0"
  },
  "tenant": {
    "id": 1,
    "name": "Test Company"
  },
  "data": {
    "resource": {
      "type": "message",
      "id": "wamid.test123",
      "attributes": {
        "message_id": "wamid.test123",
        "from": "1234567890",
        "timestamp": "1735728000",
        "type": "text",
        "text": "Test message",
        "context": null
      }
    },
    "relationships": {
      "contact": {
        "wa_id": "1234567890",
        "name": "Test User"
      },
      "metadata": {
        "phone_number_id": "1111111111",
        "display_phone_number": "1234567890"
      }
    }
  },
  "whatsapp": {
    "original_payload": {}
  },
  "metadata": {
    "source": "whatsapp_webhook_forward",
    "environment": "test",
    "request_id": "test-request-id"
  }
}

cURL Test Command ​

bash
curl -X POST https://your-endpoint.com/webhook \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Event: whatsapp.message.received" \
  -H "X-Webhook-Timestamp: 2026-01-01T10:00:00Z" \
  -H "X-Webhook-Format: n8n" \
  -d '{
    "event": {
      "id": "evt_test_12345",
      "type": "whatsapp.message.received",
      "timestamp": "2026-01-01T10:00:00Z",
      "version": "1.0"
    },
    "tenant": {"id": 1, "name": "Test"},
    "data": {
      "resource": {
        "type": "message",
        "attributes": {
          "text": "Test message"
        }
      }
    }
  }'

Β© 2024 - Corbital Technologies. All rights reserved.