# Conversations

The Conversations API enables long-lived WhatsApp conversations that remain open until explicitly closed — they are **not** subject to the standard 24-hour session window.

Not the same as WhatsApp sessions
Standard WhatsApp messages have a 24-hour customer service window. The Conversations API creates persistent conversations that stay open for days, weeks, or months. Think automotive sales, ongoing support cases, or multi-day negotiations.

Authentication Required
All API requests require your Developer Key in the `Authorization` header. No `Bearer` prefix — pass the key directly.
See [Authentication](/guides/authentication) for setup and security best practices.

## Conversation lifecycle

Every conversation follows four stages:

```
CREATE ──> SEND MESSAGES ──> CHECK TIME ──> CLOSE
                  ↑              │
                  └──────────────┘
```

### 1. Create a conversation

```
POST /payless4messaging-service/WhatsApp/WhatsAppConversations/createWhatsAppConversation
```

```json
{
  "sender": "+27123456789",
  "recipient": "+27987654321",
  "customerUserId": "ZA.1021033720668862"
}
```

The `recipient` is the customer's phone number. You may instead (or additionally) pass `customerUserId` (the customer **BSUID**, e.g. `ZA.1021033720668862`) — supply at least one. When both are present the phone takes precedence and the BSUID is stored as a durable fallback; pass `customerUserId` on its own to open a conversation with a customer who has no phone number.

**Response:**

```json
{
  "sender": "27123456789",
  "recipient": "+27987654321",
  "customerUserId": "ZA.1021033720668862",
  "conversationId": "486268ed-f233-4c3b-8321-dc69c7ba984b",
  "conversationState": "ACTIVE",
  "clientRef": "MyClient",
  "createdTime": "2026-07-16T10:30:00.000+00:00",
  "conversationStatusCode": "200",
  "conversationStatusMessage": "Conversation started."
}
```

| Field | Description |
|  --- | --- |
| `conversationId` | The conversation UUID — needed for every subsequent operation |
| `conversationState` | `ACTIVE` on a new conversation |
| `conversationStatusCode` | `"200"` when a new conversation was created; `"452"` when an active conversation already exists for this sender and recipient (the existing `conversationId` is returned) |
| `customerUserId` | The customer BSUID, if one was supplied (`null` otherwise) |


Save the conversationId
You'll need the `conversationId` for all subsequent operations — sending messages, checking time, and closing the conversation. A `conversationStatusCode` of `"452"` means a conversation was already open — reuse the returned `conversationId` rather than treating it as an error.

### 2. Send messages

```
POST /whatsapp-api-service/v2/json
```

The `messageType` must be `"CONVERSATION"`. Five message types are supported:

Addressing a recipient — phone or BSUID
Every customer has a durable, business-scoped user id (**BSUID**, alpha usernames — e.g. `ZA.1021033720668862`) that stays stable for your business even if the customer changes their phone number. Address a recipient by phone (`to`), by BSUID (`customerUserId`), or both — supply at least one. When both are present, `to` takes precedence and the BSUID rides along as a durable fallback. **The phone number remains the primary identifier today** — store the BSUID now and rely on it as phone numbers become optional.

Each entry in `recipients` (or `recipientNumbers`) accepts:

| Field | Type | Description |
|  --- | --- | --- |
| `to` | string | Recipient phone number in international format (e.g. `+27987654321`). Required unless `customerUserId` is supplied |
| `customerUserId` | string | Recipient **BSUID** (e.g. `ZA.1021033720668862`), durable across phone-number changes. Supply alongside `to` (phone wins, BSUID kept as a fallback) or on its own to address a recipient with no phone. A malformed value is ignored, so a BSUID-only send then requires a valid `to`. Required unless `to` is supplied |
| `ctId` | string | Client-defined tracking id, echoed back in delivery receipts and webhooks |


Text Only
```json
{
  "sender": "+27123456789",
  "template_name": "your_template",
  "template_id": "template-uuid",
  "messageType": "CONVERSATION",
  "messages": [
    {
      "recipients": [{ "to": "+27987654321", "customerUserId": "ZA.1021033720668862" }],
      "components": [
        { "type": "body", "parameters": ["John"] }
      ]
    }
  ]
}
```

Text + Media
```json
{
  "sender": "+27123456789",
  "template_name": "your_template",
  "template_id": "template-uuid",
  "messageType": "CONVERSATION",
  "messages": [
    {
      "recipients": [{ "to": "+27987654321" }],
      "components": [
        { "type": "body", "parameters": ["John"] }
      ],
      "media": {
        "url": "https://example.com/brochure.pdf",
        "caption": "Product Brochure"
      }
    }
  ]
}
```

Quick Reply
Quick Reply buttons use `conversationState` to control the conversation flow:

```json
{
  "sender": "+27123456789",
  "template_name": "your_template",
  "template_id": "template-uuid",
  "messageType": "CONVERSATION",
  "messages": [
    {
      "recipients": [{ "to": "+27987654321" }],
      "components": [
        { "type": "body", "parameters": ["John"] },
        {
          "type": "button",
          "parameters": ["Interested", "Not Now"],
          "conversationParameters": [
            { "payload": "Interested", "conversationState": "start" },
            { "payload": "Not Now", "conversationState": "end" }
          ]
        }
      ]
    }
  ]
}
```

| State | Effect |
|  --- | --- |
| `conversationState: "start"` | Keeps the conversation open for follow-up messages |
| `conversationState: "end"` | Closes the conversation when the recipient taps this button |


Card
Rich card with media and body text:

```json
{
  "sender": "+27123456789",
  "template_name": "your_template",
  "template_id": "template-uuid",
  "messageType": "CONVERSATION",
  "messages": [
    {
      "recipients": [{ "to": "+27987654321" }],
      "components": [
        { "type": "body", "parameters": ["2024 Model X", "From $35,000"] }
      ],
      "media": {
        "url": "https://example.com/car.jpg",
        "caption": "2024 Model X"
      }
    }
  ]
}
```

Call to Action
Template with actionable button URLs:

```json
{
  "sender": "+27123456789",
  "template_name": "your_template",
  "template_id": "template-uuid",
  "messageType": "CONVERSATION",
  "messages": [
    {
      "recipients": [{ "to": "+27987654321" }],
      "components": [
        { "type": "body", "parameters": ["John"] },
        {
          "type": "button",
          "parameters": ["https://example.com/schedule"]
        }
      ]
    }
  ]
}
```

### 3. Check remaining time

```
GET /payless4messaging-service/WhatsApp/WhatsAppConversations/getRemainingTime?conversationId=conv-uuid
```

Returns the remaining time in **seconds** (e.g., `83053` = approximately 23 hours).

Time management
Monitor remaining time and send follow-up messages or close the conversation before it expires. Expired conversations cannot accept new messages.

### 4. Close the conversation

```
GET /payless4messaging-service/WhatsApp/WhatsAppConversations/closeWhatsAppConversation?conversationId=conv-uuid
```

**Response:**

```json
{
  "closeStatus": true,
  "closeMessage": "CONVERSATION CLOSED SUCCESSFULLY",
  "tqrmtId": "tracking-uuid"
}
```

## Managing conversations

### List your conversations

```
GET /payless4messaging-service/WhatsApp/WhatsAppConversations/getAllWhatsAppConversationsForCurrentUser?page=0&size=20
```

### List conversations by client

```
GET /payless4messaging-service/WhatsApp/WhatsAppConversations/getAllWhatsAppConversationsByClientRef?clientRef=MyClient
```

### Conversation analytics

```
GET /payless4messaging-service/WhatsApp/WhatsAppAnalytics/getConversationAnalyticsForCurrentLoginUser
```

**Query parameters:**

| Parameter | Type | Description |
|  --- | --- | --- |
| `startDate` | string | **Required.** Start of the reporting period in `YYYY-MM-DD HH:mm:ss` format (UTC) |
| `endDate` | string | **Required.** End of the reporting period in `YYYY-MM-DD HH:mm:ss` format (UTC) |
| `messageType` | enum | `NOTIFICATION`, `SESSION24HOUR`, `CONVERSATION`, `CHAT` |


**Response:**

```json
{
  "conversationSubmitted": 150,
  "conversationSent": 148,
  "conversationDelivered": 145,
  "conversationRead": 120,
  "conversationFailed": 2
}
```

## Conversation states

| State | Description |
|  --- | --- |
| `OPEN` | Conversation is active and accepting messages |
| `CLOSED` | Conversation has been closed (by API call, button click, or expiration) |


## Retrieving conversation messages

To retrieve the messages exchanged within a live chat conversation (e.g. for a chatbot or agent dashboard), see the [Chatbot conversation flow](/guides/live-chat#chatbot-conversation-flow) guide. It walks through receiving an incoming webhook, looking up the chat participant, and fetching the full message history.

## Use cases

| Scenario | Why conversations? |
|  --- | --- |
| **Automotive sales** | Multi-day negotiation with test drive scheduling |
| **Insurance claims** | Back-and-forth document exchange over weeks |
| **Real estate** | Property viewing coordination spanning days |
| **Customer onboarding** | Step-by-step guided onboarding over multiple sessions |
| **Travel bookings** | Itinerary planning with multiple touchpoints |