10. Inbox / Conversation
10.1 Conversation Lifecycle
A conversation is created automatically the first time a webhook message arrives from a given wa_id with no
existing open conversation (see §8.2) — there is no manual
"create conversation" endpoint. Status, priority, pin, and archive state are independent flags tracked on
WhatsAppConversationDto/WhatsAppConversationDetailsDto (see
§6.3).
10.2 Notes
Internal-only annotations on a conversation, never sent to the customer. Author-only edit enforcement is applied service-side. See §6.4 WhatsAppNoteController.
10.3 Tags
Tenant-wide labels, optionally marked IsSystem (protected from edit/delete). Applied per-conversation via
AssignTag/RemoveTag, both logged to the conversation timeline. See
§6.6 WhatsAppTagController.
10.4 Saved Replies
Reusable canned responses, personal or tenant-shared, with an optional /shortcut for composer
autocompletion. Bilingual via Title/FTitle (an intentional exception to the platform's usual
Name/FName convention). See
§6.5 WhatsAppSavedReplyController.
10.5 Timeline
A single append-only audit trail per conversation — every assignment, transfer, close/reopen/archive/pin,
tag add/remove, and note add is logged as a WhatsAppConversationEventType entry. See
§6.7 WhatsAppTimelineController and
§16 Appendix for the full enum.
10.6 Media
Inbound media (images, documents, audio, video) is referenced by Meta's MediaId; the backend always proxies
the actual bytes through GetMediaInfoAsync/DownloadMediaAsync — the Meta CDN URL is never exposed to a
frontend client. Outbound media is sent as a public URL inside a template component parameter, not as an
uploaded binary (this integration has no outbound media-upload capability — see
§3.2).
10.7 Reply Flow
Two distinct reply mechanisms, gated by Meta's own 24-hour customer-service window rule:
- Free-text reply (
SendReply) — only within 24 hours of the customer's last inbound message (CanSendFreeTexton the conversation DTO signals this to the frontend). - Template reply (
SendTemplateReply) — always available, using an approved template, regardless of window state.
See §5.7 Reply From Inbox for the full sequence.
10.8 Tenant Credentials in the Inbox Context
The Inbox system always uses the platform's own WhatsApp Business number (WhatsAppCloudApiOptions),
not a per-tenant number — every inbound customer conversation and agent reply flows through the same Meta
Cloud API credentials configured at the platform level. Tenant-scoped credentials
(WhatsAppOperationalSettings) are used exclusively by the Communication module for outbound business
document sends, a separate flow that does not create Inbox conversations. This is a structural distinction
worth remembering: a customer replying to an invoice sent via the Communication module will not appear in
the Inbox unless the platform's own number is also the number that customer is messaging.
