Skip to main content
A conversation is a thread between one customer and the business on one channel. The routes below work on every channel. Some actions depend on the channel, and each conversation says what it allows.

List conversations

The list starts with the oldest update. Read from the last time you stopped with updated_since, or follow next_cursor. Needs the messages:read scope.

The conversation object

Read messages

GET /api/v1/partner/tenants/{external_ref}/conversations/{session_id}/messages/ lists the messages, oldest first. Use limit (1 to 100, default 50) and after. A message has role (user, assistant or human), type (text, image, template, reaction and the other types that the channel carries), text, and a channel block with the provider message id, the sender or receiver, and the status of a message that went out. An edit changes the text of the message it edits. A revoked message has deleted_at. A message from before the number was connected has history set to true. A message that the business typed on its own phone has source set to business_app. A message with a file has channel.media.ref. Fetch the file with GET /api/v1/partner/tenants/{external_ref}/media/{media_ref}/. The answer is the file.

Send a message

The answer is 201 with message and conversation. Needs the messages:write scope. Add reply_to to quote a message. A send is the reply of the business owner. If the agent pauses when a person replies, the reply takes the conversation over, and the agent can come back after the time that you set on the agent. A closed conversation opens again. Rules that depend on the channel:
  • On WhatsApp, Messenger and Instagram you can send free text for 24 hours after the last customer message. After that the call answers 422 outside_customer_service_window, and the error holds the window. On WhatsApp, send a template. See Templates.
  • On Messenger, a person can also reply for seven days with "tag": "HUMAN_AGENT".
  • Messenger, Instagram and website chat take text only. Another type answers 422 text_only.
  • A customer who opted out answers 409 opted_out.
  • A refusal by the provider answers 502 channel_rejected.

Message a customer first

channel is whatsapp (default), messenger or instagram. On WhatsApp the call opens a conversation, or uses the open one for that number. Send whatsapp_number to pick the number to send from. On Messenger and Instagram the conversation must already exist, and a call without one answers 409 no_such_thread. The body is the same as the send body above.

Take over and give back

POST .../conversations/{session_id}/handoff/ with { "on": true, "reason": "billing question" } puts a person in charge. The agent stays silent. { "on": false } gives the conversation back to the agent. The answer is the conversation. Needs messages:write. POST .../conversations/{session_id}/resume/ gives the conversation back to the agent and answers { "id", "status", "resumed" }. resumed is false when nobody had taken it. Needs assistants:write. POST .../conversations/{session_id}/turns/ makes the agent answer now. Send text as an instruction. The answer is 202 { "queued": true }. While a person has the conversation, the call answers 409 human_control. Send "force": true to give the conversation back first. A closed conversation answers 409.

Read receipts and typing

POST .../conversations/{session_id}/read/ marks the last customer message as read. Call it when a person opens the thread. It is never automatic. POST .../typing/ shows a typing indicator and marks the message as read. Both take an optional message_id. A conversation with no customer message answers 409. The answer is { "ok", "message_id" }. Both need messages:write.

Events

ImpelLabs sends message.* events and conversation.created, conversation.completed and handoff.requested to your webhook endpoint, so you do not need to poll.