Send Conversation Message
/v1/conversations/{conversation_id}/messagesSends a message to a conversation. The message is enqueued for asynchronous delivery.
Supports plain text messages and forms. Requires chat:write scope.
Closing the conversation in the same call
Set transition_status_to to close the conversation right after this message is delivered —
for a goodbye note, or a "this chat has ended" notice. Use this rather than sending the
message and then calling PUT /v1/conversations/{id}/status yourself: as two separate
requests they can overtake each other.
| Value | Meaning |
|---|---|
RESOLVED | Closed, but the contact reopens it by sending another message. |
FINALIZED | Permanently closed. You will need a new conversation next time. |
OPEN | Not accepted. Sending any message into a resolved conversation reopens it already. |
| Rule | Behavior |
|---|---|
| Ordering | The message always lands first — the conversation is only closed once the message is persisted, so the customer never sees a closed chat missing your last message. |
| Response | Still 202, immediately. The close happens moments later in the background; the response acknowledges the message, not the close. |
| End state | The one you asked for, whatever the conversation was doing beforehand. If it was already closed, the message reopens it and it closes again — agents may see a brief reopen in the history. If it was already in the requested state, nothing changes. |
FINALIZED from OPEN | Resolved first, then finalized — matching PUT /v1/conversations/{id}/status. |
| Enablement | Requires the capability to be switched on for your workspace. Until it is, the field is silently ignored: the message is sent normally and returns 202, but the conversation stays open. |
Already FINALIZED | A finalized conversation rejects new messages, so this cannot add a farewell to a chat that is already permanently closed. Create a new conversation instead. |
| Invalid value | 400, and no message is sent. (While the capability is off nothing is validated, so the same request returns 202 instead.) |
Best-effort, and a failure is silent. The message is never affected — it is sent, stored
and delivered regardless. But if the close itself fails (transient backend problem, or
someone changed the status in the meantime) the conversation keeps its previous status and
nothing tells you: the 202 was only ever about the message, and there is no webhook for a
close that did not happen. If the final status matters, read it back with
GET /v1/conversations/{id} and fall back to PUT /v1/conversations/{id}/status.
Authorization
BearerAuth In: header
Path Parameters
The unique identifier (UUID) of the conversation that will receive the message.
uuidRequest Body
application/json
The message content, type, and sender information.
TypeScript Definitions
Use the request body type in TypeScript.
Request body for sending a conversation message. Supports plain text messages, forms, and attachments.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/conversations/8b86b34d-3d4e-4f20-9d55-9d4c93d0b8a2/messages" \ -H "Content-Type: application/json" \ -d '{ "content": "Hello, how can I help you today?", "message_type": "MESSAGE", "send_as": { "agent_id": "9e9097a8-5c9a-4e1e-8218-3b833d8b0039" }, "transition_status_to": "RESOLVED" }'{ "request_id": "ca9b5a07-1d77-46f3-9fa6-6c827db6ac3d"}Create Conversation POST
Creates a new conversation on behalf of a customer contact via an external integration. The first message is always sent as the customer (contact) — agent-initiated messages are not supported. Message type is always plain text. Either `contact_id` or `contact_name` must be provided: - If `contact_id` is provided, the contact must already exist and belong to the authenticated workspace. - If `contact_id` is omitted, a new contact is created using `contact_name`. Requires `chat:write` scope.
Get Attachment URL GET
Retrieves the signed URL for an attachment. The signed URL can be used to access the attachment file. Requires `chat:read` scope.