# Getting Started

This guide walks you through setting up your eCommunicate integration and sending your first WhatsApp message. You'll go from zero to a delivered message in four steps.

Before you begin
You need:

- An **eCommunicate account** — contact [support@ecommunicate.co.za](mailto:support@ecommunicate.co.za) to get started
- A **registered WhatsApp number** (Cloud or Lite)
- Your **Developer API key** (a UUID string)


## Server URLs

Choose the correct base URL for your channel and environment:

| Environment | Base URL | Channel |
|  --- | --- | --- |
| **Production** | `https://api.payless4messaging.com` | WhatsApp Cloud |
| **Production** | `https://api.payless4messages.com` | WhatsApp Lite |


## How the system fits together

eCommunicate has two messaging surfaces that share the same WhatsApp number — and which surface a message goes through determines whether agents see it in the live-chat UI.

```mermaid
flowchart LR
    Your(["Your system"])
    Customer(["Customer"])

    subgraph eComm["eCommunicate platform"]
        direction LR
        API["API Service"]
        Chat["Chat Service"]
        Bot{{"Create Chat Participant<br/>or Bot reply"}}
        API <--> Chat
        Chat --> Bot
    end

    Customer <-->|"messages"| API
    Your -->|"Notification/Chat"| API
    Your -->|"Agent replies"| Chat
    API -. "incoming / status / session / event webhooks" .-> Your
    Chat -. "chatbot webhook" .-> Your
```

| Message path | Endpoint | Reaches customer? | Visible in live chat? |
|  --- | --- | --- | --- |
| **Notification / chat send** | `POST /whatsapp-api-service/v2/channels/whatsapp` | ✅ Yes | ❌ No |
| **Agent reply** | `POST /pl4chat-service/api/v2/messages` (with `channel: WHATSAPP`) | ✅ Yes | ✅ Yes |
| **Inbound customer message** | (customer → API Service → Chat Service) | n/a | ✅ Yes — creates a participant or routes to the chatbot |


Notifications don't appear in live chat
Anything you send through the **notifications endpoint** (`/whatsapp-api-service/v2/channels/whatsapp`) is delivered directly to the customer through the API Service — it does **not** flow through the chat service, so it will not show up on agent screens or in `/pl4chat-service/api/v2/messages` responses.

If you need an outbound message to be visible to your live-chat agents, send it through the **agent reply endpoint** (`/pl4chat-service/api/v2/messages` with `channel: WHATSAPP`) instead. See the [Live Chat guide](/guides/live-chat) for the full request shape. (The legacy `Message/sendMessageWhatsapp`, `Message/sendMessageWithAttachment`, and `Message/getMessagesByChatParticipant` endpoints are deprecated — see [Migrations](/guides/migrations#live-chat-v2).)

## Step 1: Get your API key

Every request to the eCommunicate API requires a Developer Key in the `Authorization` header.

**Retrieve your API key using your account credentials (no existing key required):**

cURL
```bash
curl -X POST \
  "https://api.payless4messaging.com/payless4messaging-service/WhatsApp/authenticate/retrieveApiKey" \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "your-password", "clientRef": "CLIENT001"}'
```

Node.js
```javascript
const response = await fetch(
  'https://api.payless4messaging.com/payless4messaging-service/WhatsApp/authenticate/retrieveApiKey',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      email: 'user@example.com',
      password: 'your-password',
      clientRef: 'CLIENT001',
    }),
  }
);
const { apiKey } = await response.json();
console.log('Your API key:', apiKey);
```

Python
```python
import requests

response = requests.post(
    "https://api.payless4messaging.com/payless4messaging-service/WhatsApp/authenticate/retrieveApiKey",
    json={
        "email": "user@example.com",
        "password": "your-password",
        "clientRef": "CLIENT001",
    },
)
print("Your API key:", response.json()["apiKey"])
```

**Generate a new key:**

```bash
curl -X POST \
  "https://api.payless4messaging.com/payless4messaging-service/WhatsApp/SystemUsers/generateAPIKey" \
  -H "Authorization: YOUR_CURRENT_KEY"
```

Key regeneration
Generating a new key **immediately invalidates** the previous one. All integrations using the old key will stop working. Update all your services before or immediately after regeneration.

## Step 2: Choose your channel

WhatsApp Cloud
WhatsApp Cloud uses Meta's official Cloud API. Messages route through `https://api.payless4messaging.com`.

| Characteristic | Detail |
|  --- | --- |
| **Template messages** | Required for outbound — must be pre-approved by Meta |
| **Session messages** | Free-form text/media within the 24-hour customer service window |
| **SMS fallback** | Automatic fallback when recipient is not on WhatsApp |
| **Rate limiting** | Managed by Meta based on your quality rating |


WhatsApp Lite
WhatsApp Lite connects directly via QR code or pairing code. Messages route through `https://api.payless4messaging.com`.

| Characteristic | Detail |
|  --- | --- |
| **No template restrictions** | Send any message at any time |
| **Connection** | QR code or pairing code |
| **Group management** | Create, manage, and message WhatsApp groups |
| **Contact sync** | Retrieve synced contacts from the connected device |
| **Throttling** | Configurable message throttling and batch delays |


SMS
Direct SMS messaging via the unified endpoint or dedicated SMS channel.

| Characteristic | Detail |
|  --- | --- |
| **GSM 7-bit** | 160 chars/part (153 multipart) — best for English text |
| **Unicode** | 70 chars/part (67 multipart) — for non-Latin characters or emoji |
| **Fallback** | Also available as automatic fallback for WhatsApp messages |


## Step 3: Send your first message

Use the unified endpoint to send a WhatsApp notification message:

cURL
```bash
curl -X POST \
  "https://api.payless4messaging.com/whatsapp-api-service/v2/messages" \
  -H "Authorization: $ECOMM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "WHATSAPP",
    "payload": {
      "sender": "+27123456789",
      "templateName": "seasonal_promo_text",
      "templateId": "your-template-uuid",
      "messageType": "NOTIFICATION",
      "messages": [
        {
          "recipients": [{ "to": "+27987654321", "customerUserId": "ZA.1021033720668862" }],
          "components": [
            { "type": "body", "parameters": ["John"] }
          ]
        }
      ]
    }
  }'
```

Node.js
```javascript
const API_KEY = process.env.ECOMM_API_KEY;
const BASE_URL = 'https://api.payless4messaging.com';

const response = await fetch(`${BASE_URL}/whatsapp-api-service/v2/messages`, {
  method: 'POST',
  headers: {
    'Authorization': API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    channel: 'WHATSAPP',
    payload: {
      sender: '+27123456789',
      templateName: 'seasonal_promo_text',
      templateId: 'your-template-uuid',
      messageType: 'NOTIFICATION',
      messages: [
        {
          recipients: [{ to: '+27987654321' }],
          components: [{ type: 'body', parameters: ['John'] }],
        },
      ],
    },
  }),
});

const data = await response.json();
console.log(data);
// { status: "ACCEPTED", requestId: "c3a1f8e2-...", channel: "WHATSAPP" }
```

Python
```python
import os
import requests

API_KEY = os.environ["ECOMM_API_KEY"]
BASE_URL = "https://api.payless4messaging.com"

response = requests.post(
    f"{BASE_URL}/whatsapp-api-service/v2/messages",
    headers={
        "Authorization": API_KEY,
        "Content-Type": "application/json",
    },
    json={
        "channel": "WHATSAPP",
        "payload": {
            "sender": "+27123456789",
            "templateName": "seasonal_promo_text",
            "templateId": "your-template-uuid",
            "messageType": "NOTIFICATION",
            "messages": [
                {
                    "recipients": [{"to": "+27987654321"}],
                    "components": [{"type": "body", "parameters": ["John"]}],
                }
            ],
        },
    },
)

print(response.json())
```

Java
```java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpResponse.BodyHandlers;

String API_KEY = System.getenv("ECOMM_API_KEY");
String BASE_URL = "https://api.payless4messaging.com";
HttpClient client = HttpClient.newHttpClient();

String json = """
    {
      "channel": "WHATSAPP",
      "payload": {
        "sender": "+27123456789",
        "templateName": "seasonal_promo_text",
        "templateId": "your-template-uuid",
        "messageType": "NOTIFICATION",
        "messages": [
          {
            "recipients": [{ "to": "+27987654321" }],
            "components": [
              { "type": "body", "parameters": ["John"] }
            ]
          }
        ]
      }
    }
    """;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(BASE_URL + "/whatsapp-api-service/v2/messages"))
    .header("Authorization", API_KEY)
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .build();

HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.body());
```

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.

**Response (202 Accepted):**

```json
{
  "status": "ACCEPTED",
  "message": "Request accepted",
  "requestId": "c3a1f8e2-4b6d-11ee-be56-0242ac120002",
  "channel": "WHATSAPP",
  "timestamp": "2026-01-15T10:30:00Z",
  "response": "Request Accepted for Processing"
}
```

Asynchronous processing
A `202 Accepted` response means the message is queued for delivery. Use [Webhooks](/guides/webhooks) or the Message Reports API to track the actual delivery status.

## Step 4: Set up webhooks

Configure webhooks to receive delivery receipts and incoming messages in real time:

```bash
curl -X POST \
  "https://api.payless4messaging.com/payless4messaging-service/WhatsApp/WhatsAppClientWebHook" \
  -H "Authorization: $ECOMM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "incomingMessageURL": "https://yourserver.com/webhooks/incoming",
    "statusUpdateURL": "https://yourserver.com/webhooks/status"
  }'
```

See the [Webhooks guide](/guides/webhooks) for full setup instructions, payload schemas, and handler examples.

## Next steps

Now that you've sent your first message, explore these guides to build out your integration:

| Guide | What you'll learn |
|  --- | --- |
| [Authentication](/guides/authentication) | API key management and security best practices |
| [WhatsApp Messaging](/guides/whatsapp-messaging) | Templates, media, buttons, carousels, and SMS fallback |
| [SMS Messaging](/guides/sms-messaging) | Direct SMS, encoding, and character limits |
| [Webhooks](/guides/webhooks) | Real-time delivery receipts and incoming messages |
| [Conversations](/guides/conversations) | Persistent conversations beyond the 24-hour window |
| [Error Handling](/guides/error-handling) | Status codes, error format, and troubleshooting |
| [Rate Limits](/guides/rate-limits) | Throughput limits, pagination, and best practices |