Skip to main contentSkip to Content
Inbox

Inbox

The Inbox holds two-way conversations with contacts. The Sent messages page is different: it is the delivery log of campaign and broadcast sends.

How messages arrive

ChannelSourceUnknown sender
TelegramBot webhook, registered automatically when the bot token is saved (Settings → Telegram shows its health and can re-register it)A contact is created with the Telegram chat as identity and attributes.createdFrom = "inbound:telegram"
WhatsAppMeta webhook (/api/providers/whatsapp/webhooks)A contact is created with the phone number and a WhatsApp identity
SMSProvider webhook (/api/providers/sms/webhooks), except STOP/START/HELP keywordsA contact is created with the phone number

Every inbound message is added to the contact’s open conversation on that channel, or starts a new one. Duplicate webhook deliveries are ignored. Auto-reply and assignment rules run on each message, and the assignee (or the whole team for a new unassigned conversation) is notified.

Telegram specifics

  • /start records Telegram consent as opted in, /stop records it as opted out.
  • Each contact profile has a Copy Telegram link button. The link opens the bot with a signed start token. When the person presses Start, the chat is attached to that contact, and a placeholder contact created earlier for the same chat is merged into it.
  • Telegram only lets a bot message people who have started it, so share the link before starting a Telegram conversation.

Working a conversation

  • Reply sends through the conversation’s channel (Telegram, WhatsApp, SMS or email) and shows whether delivery succeeded. Failed deliveries can be retried. Email replies are transactional: they reach the contact even if they opted out of email. Telegram and SMS replies are not sent to a contact who opted out of that channel.
  • Internal note is visible to teammates only.
  • Assignee and status (Open, Waiting on contact, Resolved, Closed). Replying assigns an unassigned conversation to you and marks it as waiting on the contact.
  • Link to contact moves the conversation and its channel identity to an existing contact.
  • New conversation starts a thread with any contact and sends the first message.

List Threads

GET /api/workspaces/{workspaceId}/inbox

Paginated list of inbox threads.

Auth: Session required

Query Parameters:

ParamTypeDefaultDescription
pagenumber1Page number
limitnumber50Items per page
statusstring—OPEN, PENDING, RESOLVED, CLOSED, or active for open and pending
channelstring—TELEGRAM, WHATSAPP, SMS, EMAIL, …
assignedstring—me, unassigned or a user id
contactIdstring—Only conversations with this contact
qstring—Search contact name, email, phone, subject and message text

The response also includes counts with open, mine and unassigned.

Response:

{ "data": [ { "id": "thr_abc123", "channel": "EMAIL", "subject": "Question about pricing", "status": "OPEN", "priority": "NORMAL", "assignedTo": "usr_123", "tags": ["sales", "pricing"], "contact": { "id": "ct_1", "email": "jane@example.com", "firstName": "Jane" }, "lastReply": { "body": "Hi, I have a question...", "createdAt": "2026-01-15T10:00:00.000Z" }, "createdAt": "2026-01-15T09:00:00.000Z" } ], "pagination": { "page": 1, "limit": 50, "total": 100, "totalPages": 2 } }

Create Thread

POST /api/workspaces/{workspaceId}/inbox

Auth: Session required

Request Body:

{ "contactId": "ct_abc123", "channel": "EMAIL", "subject": "Onboarding follow-up" }

Get Thread

GET /api/workspaces/{workspaceId}/inbox/{threadId}

Returns full thread details with all replies in chronological order.

Add Reply

POST /api/workspaces/{workspaceId}/inbox/{threadId}

Request Body:

{ "sender": "AGENT", "body": "Thanks for reaching out! Here's the information you requested...", "metadata": {} }
SenderDescription
AGENTReply from a team member
CONTACTReply from the contact (triggers auto-reply processing)
SYSTEMSystem-generated message

Update Thread

PATCH /api/workspaces/{workspaceId}/inbox/{threadId}

Update thread metadata.

Request Body:

{ "status": "RESOLVED", "assignedTo": "usr_456", "priority": "HIGH", "tags": ["escalated", "billing"] }

Auto-Reply Rules

Automatically respond to contact messages based on conditions.

GET /api/workspaces/{workspaceId}/inbox/auto-replies

Lists all auto-reply rules ordered by priority.

POST /api/workspaces/{workspaceId}/inbox/auto-replies

Creates a new auto-reply rule.

PATCH /api/workspaces/{workspaceId}/inbox/auto-replies/{ruleId}

Updates an existing auto-reply rule.

DELETE /api/workspaces/{workspaceId}/inbox/auto-replies/{ruleId}

Deletes an auto-reply rule.


Assignment Rules

Automatically assign threads to team members based on conditions.

GET /api/workspaces/{workspaceId}/inbox/assignment-rules

Lists all assignment rules ordered by priority.

POST /api/workspaces/{workspaceId}/inbox/assignment-rules

Creates a new assignment rule.

PATCH /api/workspaces/{workspaceId}/inbox/assignment-rules/{ruleId}

Updates an existing assignment rule.

DELETE /api/workspaces/{workspaceId}/inbox/assignment-rules/{ruleId}

Deletes an assignment rule.


Canned Responses

Pre-written response templates for quick replies.

GET /api/workspaces/{workspaceId}/inbox/canned-responses

Lists all canned responses ordered by title.

POST /api/workspaces/{workspaceId}/inbox/canned-responses

Creates a new canned response.

PATCH /api/workspaces/{workspaceId}/inbox/canned-responses/{responseId}

Updates an existing canned response.

DELETE /api/workspaces/{workspaceId}/inbox/canned-responses/{responseId}

Deletes a canned response.

Delivery endpoints

POST /api/workspaces/{workspaceId}/inbox/{threadId}

Agent replies ("sender": "AGENT") are delivered through the thread channel; the returned reply has metadata.delivery with status (sent, failed, skipped), error and providerMessageId. Pass "metadata": { "internal": true } for an internal note.

POST /api/workspaces/{workspaceId}/inbox/{threadId}/replies/{replyId}/deliver

Retries delivery of an agent or auto-reply message that was not delivered.

PATCH /api/workspaces/{workspaceId}/inbox/{threadId}

Besides status, assignedTo, priority and tags, accepts contactId to move the conversation (and its Telegram, WhatsApp or phone identity) to another contact.

Returns { url, linked }, the personal https://t.me/<bot>?start=… link for the contact.

Commands and quick replies

Telegram, WhatsApp and SMS share one command list, in Settings under each channel. A command has a keyword, a description, a reply, and a reply per language.

ChannelHow a contact triggers itMenu
Telegram/promoPublished to Telegram’s command menu, one menu per language
WhatsAppPROMO or /promoNo menu
SMSPROMO (plus the usual STOP, START, HELP, and LANGUAGE keywords)No menu

Built-in commands are start, stop, help and language; start and stop also record channel consent. help renders {{commands}}, the enabled commands with their descriptions in the contact’s language.

Languages

Each command keeps a default reply plus a reply per language. A contact receives the reply for their locale, falling back to the language without the region, then another regional variant, then the workspace default, then the default reply. Descriptions are localized the same way, and Telegram menus are published per language.

/language lets a contact set their own language: /language pt, /language pt-BR, or LANGUAGE pt on WhatsApp and SMS. It stores the locale and country on the contact and confirms in the new language, so every later email, Telegram message, push and SMS uses it. Sending it with no code replies with the list of languages you reply in.

Replies support contact tokens, {{args}}, {{commands}}, {{languages}} and promo codes such as {{contact.id | code:PROMO10}}.

Every command emits telegram.command, whatsapp.command or sms.command with command and args in metadata, so a campaign with an Event trigger can react to it.

API

GET /api/workspaces/{workspaceId}/channel-commands?channel=TELEGRAM returns the commands, and PUT the same path with { channel, commands: [{ command, description, reply, translations, descriptions, enabled, showInMenu }] } saves them and republishes the Telegram menu.

Real-time automations

Email opens and clicks (message.open, message.click), and inbound telegram.message_received, telegram.command, whatsapp.message_received and sms.message_received events run automations immediately:

  • Campaigns with an Event trigger for that event enroll the contact.
  • Enrollments waiting on a Decision node for that contact are re-evaluated at once, so “opened the email → send a Telegram message” happens seconds after the open instead of at the next scheduled check.

The code template filter produces a stable, contact-specific code: {{contact.id | code:OPEN15}} renders the same OPEN15-XXXXXX value in every email and Telegram message for that contact.

Last updated on