Replying to customers
Pre-release v1, published 2026-09-14. This page commits to the shape of the API, not to a
date. We will build exactly what is documented here. The shape can still change until
2026-10-14; after that, changes follow Versioning and stability.
The banner comes off one page at a time as each route goes live. While it is here, build against the contract and assume the route is not callable yet.
Your operators answer end customers from your panel, not ours. A conversation arrives on your webhook, your agent types a reply, and you post it back through this API. The message reaches the customer on whichever channel the conversation belongs to, so the same call covers Instagram and Telegram.
Send a text reply
Every event carries a conversation_id. That is all you need to reply.
external_id is your idempotency key. Send the same one twice and you get the original message
back rather than a duplicate, so retrying after a timeout is safe.
A status of queued means the channel is rate limited and we will deliver the message when
capacity frees. Nothing is discarded.
Send a file or a voice note
Two steps: upload the file, then send a message referencing it.
It is two steps rather than one so that a large upload failing mid-transfer can be retried on its own, and so one file can be sent to several conversations without uploading it again.
1. Upload
2. Send it
A voice note is just an attachment with type: voice. Upload the audio file the same way; we
infer the type from the media type, or you can pass type=voice explicitly.
Show a typing indicator
Call this when your agent starts typing, so the customer sees the same cue they would in any chat app.
The indicator expires by itself after a few seconds. Send it again while the agent keeps typing rather than sending a stop.
Build an operator queue
Filter conversations by status to find the ones waiting for a human.
You do not have to poll this. The chat webhook event fires the moment a conversation enters
operator_attention, so use the event to update your queue and this endpoint to rebuild it after
a restart.
Close a conversation
Closing is a context boundary, not a deletion. The transcript stays and remains readable. What
changes is that the next conversation with that customer starts without the earlier history as
AI context. See context_reset.