Back to Docs

WhatsApp Integration

Track WhatsApp messaging events to analyze conversations, response times, and engagement.

How It Works

Send events to our collector whenever something happens in your WhatsApp system:

  • Message received from user
  • Message sent to user
  • Message delivered/read
  • Contact created
  • Chat assigned to agent

Endpoint: POST https://analytics.chatnationbot.com/v1/capture

Authentication

You must include your Write Key in the request header to authenticate your events. This ensures the data is assigned to the correct project.

X-Write-Key: your_write_key_here

You can find your Write Key in the API Keys section.

Base Payload Structure

{
  "batch": [
    {
      "type": "track",
      "event": "event_name",
      "userId": "+254712345678",
      "timestamp": "2026-01-20T06:30:00.000Z",
      "context": {
        "channel": "whatsapp",
        "library": {
          "name": "crm-whatsapp",
          "version": "1.0.0"
        }
      },
      "properties": {
        // Event-specific data
      }
    }
  ]
}

Key: The userId should be the WhatsApp phone number (e.g., "+254712345678"). The context.channel must be "whatsapp".

Event Types

message.received

User sends a message to your WhatsApp number.

{
  "type": "track",
  "event": "message.received",
  "userId": "+254712345678",
  "timestamp": "2026-01-20T06:30:00.000Z",
  "context": { "channel": "whatsapp" },
  "properties": {
    "messageId": "wamid.xxx",
    "chatId": "chat_123",
    "direction": "inbound",
    "contentType": "text",
    "hasMedia": false
  }
}

message.sent

You send a message to a user.

{
  "type": "track",
  "event": "message.sent",
  "userId": "+254712345678",
  "timestamp": "2026-01-20T06:31:00.000Z",
  "context": { "channel": "whatsapp" },
  "properties": {
    "messageId": "wamid.yyy",
    "chatId": "chat_123",
    "direction": "outbound",
    "contentType": "template",
    "templateId": "welcome_v2",
    "agentId": "agent_456"
  }
}

message.read

User reads your message.

{
  "type": "track",
  "event": "message.read",
  "userId": "+254712345678",
  "timestamp": "2026-01-20T06:32:00.000Z",
  "context": { "channel": "whatsapp" },
  "properties": {
    "messageId": "wamid.yyy",
    "readAt": "2026-01-20T06:32:00.000Z"
  }
}

contact.created

New contact added to CRM.

{
  "type": "track",
  "event": "contact.created",
  "userId": "+254712345678",
  "timestamp": "2026-01-20T06:30:00.000Z",
  "context": { "channel": "whatsapp" },
  "properties": {
    "chatId": "chat_123",
    "name": "John Doe",
    "source": "organic",
    "countryCode": "KE"
  }
}

chat.resolved

Conversation is marked as resolved.

{
  "type": "track",
  "event": "chat.resolved",
  "userId": "+254712345678",
  "timestamp": "2026-01-20T08:30:00.000Z",
  "context": { "channel": "whatsapp" },
  "properties": {
    "chatId": "chat_123",
    "agentId": "agent_456",
    "resolutionType": "resolved",
    "messageCount": 12,
    "durationMinutes": 120
  }
}

agent.handoff

User is transferred from bot to human agent (Self-serve → Assisted).

{
  "type": "track",
  "event": "agent.handoff",
  "userId": "+254712345678",
  "timestamp": "2026-01-20T07:00:00.000Z",
  "context": { "channel": "whatsapp" },
  "properties": {
    "chatId": "chat_123",
    "fromMode": "bot",
    "toMode": "agent",
    "agentId": "agent_456",
    "handoffReason": "user_request",
    "journeyStep": "payment_issue"
  }
}

Tip: Use serviceMode to segment analytics between "bot" (Self-serve) and "agent" (Assisted).

message.delivered

Message was delivered to user's device.

{
  "type": "track",
  "event": "message.delivered",
  "userId": "+254712345678",
  "timestamp": "2026-01-20T06:31:30.000Z",
  "context": { "channel": "whatsapp" },
  "properties": {
    "messageId": "wamid.yyy",
    "deliveredAt": "2026-01-20T06:31:30.000Z"
  }
}

Metrics You Can Track

MetricHow It's Calculated
Response TimeTime between message.received and next message.sent
Daily New ContactsCount of contact.created per day
Read Ratemessage.read / message.sent
Delivery Ratemessage.delivered / message.sent
Reply Ratemessage.received / message.sent
Message FunnelSent → Delivered → Read → Replied
Traffic by Countrymessage.received grouped by countryCode
Peak Hoursmessage.received grouped by hour
Agent PerformanceEvents grouped by agentId
Self-serve vs AssistedEvents grouped by serviceMode (bot/agent)

Example: Full Conversation

// 1. User sends first message (new contact)
POST /v1/capture
{ "batch": [
  { "event": "contact.created", "userId": "+254712345678", ... },
  { "event": "message.received", "userId": "+254712345678", ... }
]}

// 2. Agent is assigned
POST /v1/capture
{ "batch": [{ "event": "chat.assigned", "userId": "+254712345678", ... }]}

// 3. Agent replies
POST /v1/capture
{ "batch": [{ "event": "message.sent", "userId": "+254712345678", ... }]}

// 4. User reads and replies
POST /v1/capture
{ "batch": [
  { "event": "message.read", "userId": "+254712345678", ... },
  { "event": "message.received", "userId": "+254712345678", ... }
]}

// 5. Chat resolved
POST /v1/capture
{ "batch": [{ "event": "chat.resolved", "userId": "+254712345678", ... }]}