> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lacy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Send Freeform Message

> Send a free-text WhatsApp message within an active 24-hour session

This endpoint sends a freeform (free-text) WhatsApp message to a recipient. Unlike template messages, freeform messages can contain any text but **require an active 24-hour messaging window** — meaning the recipient must have sent a message to your WhatsApp sender within the last 24 hours.

> [!WARNING]
>
> Freeform messages can only be sent during an active 24-hour messaging window. If the session has expired, you must send a [template message](https://docs.lacy.ai/api-reference/whatsapp/send-template.md) first to re-initiate the conversation. Use the [Session Status](https://docs.lacy.ai/api-reference/whatsapp/session-status.md) endpoint to check if a session is active.

> [!NOTE]
>
> This endpoint is rate-limited to **5 requests per second** per user.

### Request Body

**sender\_id** `integer` *required*

The ID of the WhatsApp sender to send from (obtained from the [Get Senders](https://docs.lacy.ai/api-reference/whatsapp/get-senders.md) endpoint)

**recipient\_phone** `string` *required*

The recipient's phone number in international format (e.g., `+1234567890`)

**message** `string` *required*

The message content to send (max 4096 characters)

### Response Fields

**success** `boolean`

Whether the message was sent successfully

**conversation\_id** `integer`

The ID of the conversation associated with this message

**message\_id** `integer`

The ID of the conversation message record

**whatsapp\_message\_id** `integer`

The ID of the WhatsApp message record

**message\_sid** `string`

The Twilio message SID for tracking delivery

**session\_status** `object`

Updated session status after sending the message

**Session status properties**

**is\_open** `boolean`

Whether the 24-hour messaging window is currently open

**can\_send\_freeform** `boolean`

Whether freeform messages can be sent right now

**requires\_template** `boolean`

Whether a template message is required

**message** `string`

Human-readable description of the session state

**minutes\_remaining** `integer`

Minutes remaining in the 24-hour window

**expires\_at** `string`

ISO 8601 timestamp when the session expires

### Error Responses

**402 Insufficient Balance**

**Error Response**

**success** `boolean`

`false`

**error** `string`

`Insufficient balance. Please top up your account.`

**error\_code** `string`

`INSUFFICIENT_BALANCE`

**403 Session Expired**

**Error Response**

**success** `boolean`

`false`

**error** `string`

Message indicating the 24-hour messaging window has expired

**error\_code** `string`

`SESSION_EXPIRED`

**session\_status** `object`

Current session status with `is_open`, `can_send_freeform`, `requires_template`, and `message` fields

**404 Not Found**

**Error Response**

**success** `boolean`

`false`

**error** `string`

`Sender not found or does not belong to you`

**error\_code** `string`

`SENDER_NOT_FOUND`

**503 Sender Offline**

**Error Response**

**success** `boolean`

`false`

**error** `string`

Message indicating the sender is currently offline

**error\_code** `string`

`SENDER_OFFLINE`

```bash cURL theme={null}
curl -X POST "https://app.lacy.ai/api/user/whatsapp/send-freeform" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sender_id": 12,
    "recipient_phone": "+1234567890",
    "message": "Thank you for your inquiry! Our team will review your request and get back to you within 2 hours."
  }'
```

```javascript JavaScript theme={null}
const response = await fetch(
  'https://app.lacy.ai/api/user/whatsapp/send-freeform',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      sender_id: 12,
      recipient_phone: '+1234567890',
      message: 'Thank you for your inquiry! Our team will review your request and get back to you within 2 hours.'
    })
  }
);

const data = await response.json();
console.log(data);
```

```python Python theme={null}
import requests

response = requests.post(
    'https://app.lacy.ai/api/user/whatsapp/send-freeform',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'sender_id': 12,
        'recipient_phone': '+1234567890',
        'message': 'Thank you for your inquiry! Our team will review your request and get back to you within 2 hours.'
    }
)

print(response.json())
```

```json 200 Success theme={null}
{
  "success": true,
  "conversation_id": 1234,
  "message_id": 567,
  "whatsapp_message_id": 890,
  "message_sid": "SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "session_status": {
    "is_open": true,
    "can_send_freeform": true,
    "requires_template": false,
    "message": "Session open (23 hr 45 min remaining). Unlimited free-form messages allowed.",
    "minutes_remaining": 1425,
    "expires_at": "2026-02-25T10:30:00+00:00"
  }
}
```

```json 402 Insufficient Balance theme={null}
{
  "success": false,
  "error": "Insufficient balance. Please top up your account.",
  "error_code": "INSUFFICIENT_BALANCE"
}
```

```json 403 Session Expired theme={null}
{
  "success": false,
  "error": "The 24-hour messaging window is closed. Customer must reply first, or use a template message.",
  "error_code": "SESSION_EXPIRED",
  "session_status": {
    "is_open": false,
    "can_send_freeform": false,
    "requires_template": true,
    "message": "Session expired. Send a template or wait for customer to reply.",
    "expired_at": "2026-02-23T10:30:00+00:00"
  }
}
```

```json 404 Sender Not Found theme={null}
{
  "success": false,
  "error": "Sender not found or does not belong to you",
  "error_code": "SENDER_NOT_FOUND"
}
```

```json 422 Invalid Phone theme={null}
{
  "success": false,
  "error": "Invalid phone number format. Use E.164 format (e.g., +14155551234).",
  "error_code": "INVALID_PHONE"
}
```

```json 503 Sender Offline theme={null}
{
  "success": false,
  "error": "Sender is not online. Current status: Offline",
  "error_code": "SENDER_OFFLINE"
}
```

### 24-Hour Messaging Window

WhatsApp enforces a **24-hour messaging window** policy:

1. When a customer sends a message to your WhatsApp Business number, a 24-hour window opens.
2. During this window, you can send freeform messages without restrictions.
3. After the window expires, you must use a [template message](https://docs.lacy.ai/api-reference/whatsapp/send-template.md) to re-initiate the conversation.
4. Each new customer message resets the 24-hour timer.

Use the [Session Status](https://docs.lacy.ai/api-reference/whatsapp/session-status.md) endpoint to check whether a session is active before attempting to send a freeform message.

### Notes

* Maximum message length is **4,096 characters** (WhatsApp limit).
* The sender must be `online`. Offline senders return a `503` error.
* Message costs are automatically deducted from your account balance.
* Rate limit: 5 requests per second per user.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.