POST /conversations/{id}/messages is the API equivalent of an agent typing into the dashboard’s reply box. It posts a message from your team to the visitor — not from the bot.
What it does
1
Inserts an assistant-role message
The message lands on the thread with
role: "assistant", attributed to your
API key in metadata.source = "api". It renders in the visitor’s chat
window immediately.2
Performs human takeover
If the conversation was in
agent_requested, status flips to open. The
bot stops handling the slot — every subsequent visitor turn waits for an
agent. A system marker message is inserted: “A team member has joined the
conversation.”3
Broadcasts in realtime
Connected clients (open browser tabs on the visitor’s side, other dashboard
sessions) receive a realtime
new_message event so they don’t have to poll.4
Fires webhooks
message.created fires with the new message. If the status changed,
conversation.updated also fires with the diff.5
Schedules an away-email
If the visitor isn’t actively watching the tab and
contact_email is set,
an email notification is scheduled. The job rechecks presence before sending
— replying many times in quick succession won’t fan out duplicate emails.Allowed conversation states
The conversation must be inopen or agent_requested. Any other status returns 400.
Unlike the dashboard UI, the API does not require the conversation to be
assigned to a specific user. API keys operate at the org level. The
conversation will remain unassigned after the reply unless a human picks it
up.
Request
Body
string
required
The reply text. May be empty if you’re sending only attachments. Trimmed of
leading/trailing whitespace.
array
Image attachments to include. Each entry is
{ "url": "https://..." }. See Attachments below for the full contract.Attachments
You can include image attachments by passing a publicly-accessible URL. Awardee fetches the image, stores it in your organization’s asset library (content-addressed and de-duplicated), and references the stored copy on the resultingmessage_part row. The URL on the persisted message is ours, not yours — so the visitor’s chat tab keeps rendering the attachment even if your source link rots.
Asset bytes are de-duplicated within your organization: posting the same screenshot to ten different conversations stores it once, and you’re billed for storage once. The file_url returned for the same image in different conversations will be identical.
Limits
- v1 is image-only. Accepted MIME types:
image/png,image/jpeg,image/webp,image/gif. - 15 MiB max per attachment.
- Public
http/httpsURL required. Theurlmust use thehttporhttpsscheme; any other scheme (data:,ftp:,file:, …) is rejected. Awardee fetches the bytes server-side from your URL — no auth headers are forwarded. Private / loopback / link-local hosts are blocked (SSRF protection). - 15s fetch timeout. Slow or unresponsive sources return
422.
Error responses
File attachments (PDFs, video, etc.) will be supported in a future release. v1
only accepts images.
Response
Idempotency
Pass anIdempotency-Key header to make retries safe:

