Skip to content
View as Markdown
How-to guideInbox

Inbox & Chat

The shared team inbox for two-way WhatsApp conversations — assignment, tags, notes, and message sending

Agents and team leadsUpdated

The Inbox is where your team has day-to-day conversations with customers over WhatsApp. It’s a shared, real-time view: incoming messages arrive live over WebSocket, agents reply with text, media, buttons, or approved templates, and each conversation carries its own assignment, tags, and private notes.

Shared team inbox

Every WhatsApp conversation for the organization in one list, ordered by most recent activity.

Assignment

Route a conversation to a specific agent so ownership is clear.

Tags

Colour-coded labels for filtering and triage (e.g. vip, billing, lead).

Private notes

Internal-only annotations on a conversation — never sent to the customer.

The left-hand list is the set of contacts the signed-in user is allowed to see, ordered by last_message_at (most recent first, contacts with no messages last). Each row surfaces:

Field Meaning
Profile name / phone The contact’s WhatsApp profile name, falling back to the phone number. Both can be masked org-wide.
Last message preview A short preview of the most recent message ([Image], [Document: …], or truncated text).
Unread count Number of incoming messages that haven’t been marked read.
Assigned agent The agent the conversation is routed to, if any.
Tags The contact’s tags.
Service window Whether the 24-hour free-form messaging window is open (see below).

The list supports server-side search and tag filtering:

  • Search matches the contact’s phone number or profile name (case-insensitive on the profile name).
  • Tag filter accepts a comma-separated list of tag names and returns contacts that have any of them (?tags=vip,billing).

These map to the search and tags query parameters on GET /api/contacts — see the Contacts API.

A conversation’s unread count is the number of incoming messages whose status is not yet read. Opening the conversation and calling mark-as-read clears it (see Marking messages as read). When the chatbot auto-handles an exchange, it marks the incoming messages read for you so bot-handled chats don’t leave a stale unread badge.

WhatsApp enforces a 24-hour customer service window. It opens each time the customer sends you a message and lasts 24 hours from that last inbound message. Soosh tracks this per contact as service_window_open (true when the last inbound message was less than 24 hours ago).

What the window controls:

Window state What you can send
Open (customer messaged within 24h) Free-form messages — text, media, interactive buttons, reactions.
Closed (no inbound in 24h) Only pre-approved message templates. Free-form messages will be rejected by Meta.

What a user sees in the inbox depends on their role’s permissions:

  • With chat:read — the user can open conversations. Combined with contacts:read, they see every conversation in the organization.
  • Without contacts:read — visibility is narrowed to conversations the user owns: contacts assigned to them (assigned_user_id), plus contacts with an active agent transfer to them. This scoping is applied uniformly to listing, reading, messaging, reactions, and notes — an agent cannot read or reply to a conversation they don’t own.

Assignment is controlled separately:

  • chat.assign:write and contacts:write let a user assign or reassign conversations to agents.

All outbound sends target a contact and resolve a WhatsApp account (the one specified on the request, else the contact’s account, else the org’s default outgoing account).

Send a plain text message. Supports replying to an earlier message for threaded context.

POST /api/contacts/{id}/messages
{
"type": "text",
"content": { "body": "Hi Sarah, how can we help?" },
"reply_to_message_id": "…optional…"
}

When your workspace has AI reply suggestions, the message box has a Suggest a reply button (the sparkles). The AI reads the end of the conversation, your bot’s AI instructions and knowledge, and what it knows about the customer, then writes up to 3 drafts. The first shows in the empty message box, in the brand blue (with a blue-to-neon edge) so it can’t be mistaken for your own text, with a row under the box to go through them:

  • Tab (or Use) puts the draft in the message box, where you can edit it.
  • ↑ and ↓ (or the arrows in the row) show the other drafts.
  • Esc, ✕ or starting to type dismisses them.

Nothing is sent until you send it, so check it first: AI can be wrong.

  • Each set of drafts counts as AI use, like a bot reply, and is charged when the workspace pays for AI.
  • If you can see only the current conversation, the drafts come from it alone.
  • Whether you sent a draft, and how much you changed it, is recorded to measure how useful the drafts are. A message that keeps less than half of the draft counts as your own.
  • If you open another chat before sending a draft you haven’t edited, it is taken out of the message box: it was written for the other customer.
  • A super admin turns the feature on for a workspace; it also needs AI replies and knowledge.

When your workspace has AI rewrite, the message box has a Rewrite button (the pencil with a spark). Write your reply, then pick how to rewrite it:

  • Fix spelling and grammar changes nothing else.
  • Make it friendlier, Make it more formal or Make it shorter change the tone or length.

The rewrite is asked to keep your language, meaning, names, numbers, links and formatting, but AI can get it wrong. It replaces what you wrote. A row under the box says it was rewritten: Undo (or Ctrl+Z / ⌘Z straight away) puts your text back. Undo goes once you change the rewrite, send it or open another chat. If you type while it is being rewritten, your text is kept and the rewrite dropped.

Nothing is sent until you send it, so read it first. Each rewrite counts as AI use and is charged when the workspace pays for AI. A super admin turns the feature on for a workspace; it also needs AI replies and knowledge.

When your workspace has AI translation, messages with text have a Translate button among the tools that show when you point at a message. The translation appears under the message’s own text, in the language you use the app in (English if the app’s language isn’t one of Soosh’s). Click again to hide it.

  • Only the message’s text (or caption) is translated. Card, account and ID numbers, and codes, PINs and passwords, are removed before it is sent to the AI, and one-time-code messages aren’t translated.
  • A message already translated into your language in the last 30 days comes back straight away and costs nothing; otherwise each translation counts as AI use.
  • If you can see only the current conversation, you can translate only its messages.
  • A super admin turns the feature on for a workspace; it also needs AI replies and knowledge.

When your workspace has AI transfer summaries, each time a chat is transferred to agents (by a member, a keyword, a flow or because the bot is off) AI sums up the conversation in a sentence or three: what the customer wants, what they were told, and what is still open. It is written a few seconds after the transfer and shows up on its own:

  • In the chat, on the strip above the messages (AI summary · …) while the transfer is open. When the AI assistant handed the chat over itself, the strip shows its own hand-over note instead (Handed over by AI · …), and no summary is written.
  • On the hand-over line in the conversation, under “Handed to agents”, so past transfers keep theirs.
  • In the transfers list, under the contact’s name, in your transfers, the queue and all active transfers.

The AI reads only this conversation, up to the transfer, with codes and card, account and ID numbers removed. It can get things wrong, so check the messages before you act on it. Each summary counts as AI use. A super admin turns the feature on for a workspace; it also needs transfers and AI replies and knowledge.

Images, video, audio, and documents are sent as multipart/form-data with the file, a type (image / video / audio / document), an optional caption, and an optional whatsapp_account override.

POST /api/messages/media (multipart/form-data)
file=<binary> type=image caption="Your receipt" contact_id=<uuid>

The chat send endpoint also sends interactive messages via the interactive field:

Interactive type What it sends
button Up to a few tappable quick-reply buttons under a body text.
list A list-style picker of options.
cta_url A single call-to-action button that opens a URL.
voice_call A WhatsApp Business Calling button that lets the customer call you. Requires the account to have Business Calling enabled.
flow Launches a WhatsApp Flow form. The flow_id must belong to your organization.

When the service window is closed — or for any structured, pre-approved outreach — send an approved template via POST /api/messages/template. You supply the template name or ID plus its body/header/button parameters. The send is rejected if the template isn’t APPROVED, if required parameters are missing, or if the contact has opted out of marketing and the template is a MARKETING template. See the Messages API for the full parameter list.

React to any message with an emoji. Each user can have one reaction per message; sending an empty emoji removes your reaction.

POST /api/contacts/{id}/messages/{message_id}/reaction
{ "emoji": "👍" }

Opening a conversation should mark its incoming messages read to clear the unread badge:

POST/api/contacts/{id}/mark-read

This flips the contact’s incoming messages to read. If the sending account has auto read receipts enabled, Soosh also sends read receipts (the blue ticks) back to the customer over the WhatsApp API.

Notes are internal annotations on a conversation. They are stored against the contact, visible to your team in the chat view, and never sent to the customer.

  • Any user with chat:read can view notes; chat:write is required to create them.
  • A note records its author and timestamps, and displays the author’s name.
  • Only the note’s author can edit or delete their own note.
  • Note changes broadcast in real time over WebSocket, so teammates viewing the same conversation see them appear live.

Endpoints (see the route table): GET / POST /api/contacts/{id}/notes, and PUT / DELETE /api/contacts/{id}/notes/{note_id}.

Each conversation is backed by a contact record you can manage from the inbox.

Assign a conversation to an agent to make ownership explicit and — for agents without contacts:read — grant them access to it. Assignment requires contacts:write.

PUT /api/contacts/{id}/assign
{ "user_id": "…agent uuid…" } // null to unassign

The assignee must be a user in the same organization. Unassign by sending null.

Tags are organization-scoped, colour-coded labels. Manage the tag catalog under tags:read / tags:write / tags:delete; valid colours are blue, red, green, yellow, purple, gray. Apply tags to a contact (requires contacts:write):

PUT /api/contacts/{id}/tags
{ "tags": ["vip", "billing"] }

Renaming or deleting a tag in the catalog propagates the change to every contact that carries it. Filter the inbox by tag as described in Search and tag filtering.

A contact carries a phone number, profile name, WhatsApp account, tags, and a free-form metadata object. Creating and editing contacts requires contacts:write; both are audit-logged. Re-creating a previously deleted contact restores the soft-deleted record rather than erroring.

Contacts flagged marketing_opt_out cannot be sent MARKETING-category templates — such sends are rejected. This keeps bulk and promotional messaging compliant with the customer’s stated preference.

When phone masking is enabled for the organization, phone numbers (and profile names that are themselves phone numbers) are masked in list and detail responses. This is an org-level privacy control applied server-side, so agents never see the raw number.

The inbox is driven by the WebSocket hub: new inbound and outbound messages, status changes (sent / delivered / read / failed), reaction updates, and note changes are all broadcast to connected clients for the organization, so the list and open conversation update without a refresh.