Conversations & Messages

Conversations are automatically created when a message is sent or received. Each conversation is scoped to a phone number + contact pair.


List Conversations

GET /v1/phones/{phoneId}/conversations?page=1&limit=50

Returns conversations ordered by most recent message.

{
  "data": [
    {
      "id": "conv-uuid",
      "contactPhone": "5491155551234",
      "contactName": "John Doe",
      "lastMessageAt": "2026-03-10T14:30:00.000Z",
      "createdAt": "2026-03-01T10:00:00.000Z"
    }
  ],
  "meta": { "pagination": { "page": 1, "limit": 50, "total": 12, "hasMore": false } }
}

Get Messages

GET /v1/phones/{phoneId}/conversations/{conversationId}/messages?page=1&limit=50

Returns messages ordered by timestamp (newest first).

{
  "data": [
    {
      "id": "msg-uuid",
      "wamid": "wamid.HBgLNTQ5MTE1NTU...",
      "direction": "inbound",
      "type": "text",
      "content": { "body": "Hi there!" },
      "status": "delivered",
      "timestamp": "2026-03-10T14:30:00.000Z"
    }
  ]
}

Message Statuses

Messages go through these statuses:

Status Direction Description
pending Outbound Message queued for sending
sent Outbound Delivered to WhatsApp servers
delivered Outbound Delivered to the recipient's device
read Outbound Read by the recipient
failed Outbound Delivery failed (see error field)

Inbound messages don't have a status — they're received and stored immediately.


Message Types

The content field varies by message type:

Type Content Fields
text { body: string }
image { url: string, caption?: string, mimeType?: string }
video { url: string, caption?: string, mimeType?: string }
audio { url: string, mimeType?: string }
document { url: string, caption?: string, filename?: string }
sticker { url: string }
location { latitude: number, longitude: number, name?: string }
contacts { contacts: array }
interactive { type: string, ... } (button reply, list reply)
button { text: string, payload: string }
reaction { emoji: string }