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

# Send messages

> Reply on a ticket and add private notes through the Support API.

These endpoints send messages **as your business**: what an agent would write from the inbox. To pass a message *from* a customer to the AI agent, use the [AI service integration](/support/ai-service.md) instead.

Every request goes to `https://back.leap.onclarity.com` with `Authorization: Bearer $CLARITY_API_KEY` (see [Authentication](/authentication.md)). Sends are asynchronous: a `200` means Clarity accepted the message and queued it for delivery on the ticket's channel.

| Endpoint | Use it to |
| - | - |
| `POST /api/message/send` | Reply on an existing ticket, or add a private note or system notification to it |
| `POST /api/attachment/upload` | Upload a file to attach to a message |

## Reply on a ticket

`POST /api/message/send` writes into an existing ticket on whatever channel the ticket is on.

```bash Request theme={null}
curl -X POST https://back.leap.onclarity.com/api/message/send \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ticket_id": 12345,
    "mode": "message",
    "text": "Your replacement shipped today. Tracking number: 1Z999AA10123456784.",
    "files": []
  }'
```

```json Response theme={null}
{
  "created_at": "2026-10-22T09:12:03.512000Z",
  "internal_id": "0199f3a2-6c1e-7d4b-9a10-2f5c8e1b7a44",
  "files": []
}
```

**ticket\_id** `integer` *required*

The ticket to write to.

**mode** `string` *required*

`message` (the customer sees it), `private_note` (only agents see it), or `system_notification` (a system line in the ticket timeline).

**text** `string` *required*

The message text.

**files** `integer[]` (default: \[])

Attachment ids from `POST /api/attachment/upload`. At most 5.

**mentioned\_agent\_ids** `integer[]`

For a private note: the agents to mention.

**email\_cc** `string[]`

Email tickets only. The CC recipients. Omit it to reply to everyone on the thread; send `[]` to reply to the author only.

**widgets** `object[]`

Buttons and other interactive elements to show under the message on channels that support them. See the [API reference](/api-reference/introduction.md) for the widget types.

**created\_at** `string`

When Clarity accepted the message.

**internal\_id** `string`

The message's id.

**files** `object[]`

The attached files, each with `id`, `original_url`, `thumbnail_url`, `mime_type`, and `original_filename`.

### Rules for `mode: "message"`

* The ticket must have an assigned agent. Otherwise the request answers `400 ticket_no_agent`. Assign one first with [`POST /api/ticket/assign/v2`](/support/customers-and-tickets#assign-a-ticket).
* On a **closed** ticket the message is saved as a private note instead. Reopen the ticket first if the customer must receive it.
* On WhatsApp, interactive widgets need an open 24-hour window: a customer message in the last 24 hours. When the window is closed and you call with an organization API key, the message is sent as plain text without the widgets. Outside the window, WhatsApp delivers only approved templates, which you send from the Clarity inbox.
* On X, Instagram, and LinkedIn, the request answers `409 account_reauth_required` when the connected account must be re-authenticated in Clarity.

### Errors

| Code | Status | Meaning |
| - | - | - |
| `ticket_not_found` | 404 | No ticket with that id in your organization. |
| `ticket_no_agent` | 400 | The ticket has no assigned agent. |
| `channel_not_found` | 404 | The ticket's channel was deleted. |
| `too_many_files_error` | 400 | More than 5 files. |
| `account_reauth_required` | 409 | The social account behind the ticket needs to be reconnected. |

## Attachments

Upload a file first, then pass its `id` in `files`.

```bash Request theme={null}
curl -X POST https://back.leap.onclarity.com/api/attachment/upload \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -F "file=@invoice-4471.pdf"
```

```json Response theme={null}
{
  "id": 88213,
  "original_filename": "invoice-4471.pdf",
  "stored_filename": "5f0c2b7e9a1d4c3e8b6a.pdf",
  "mime_type": "application/pdf",
  "file_size": 48213,
  "file_path": "attachments/5f0c2b7e9a1d4c3e8b6a.pdf",
  "download_url": "https://example-storage.invalid/attachments/5f0c2b7e9a1d4c3e8b6a.pdf"
}
```

The request body can be up to 50 MB. A message carries at most 5 attachments.

## See also

> **[Customers and tickets](/support/customers-and-tickets.md)**
>
> Assign tickets, change their status, and look up ids.

> **[Webhooks](/support/webhooks.md)**
>
> Get notified when the customer replies.


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