Read a conversation’s full history or patch its status and unread counter. Opening the thread marks it read.
GET /api/conversations/{id} — returns the conversation, every message (ordered sent_at ASC), enriched participant details (company, position, headline, profile picture), and sender-account health. Side effect: resets unread_count to 0 before returning.PATCH /api/conversations/{id} — patches status (archive/un-archive) and/or unread_count.conversations row) or when the agent sends the first outbound reply via sendConversationMessage.
GET returns senderDisconnected: true when the sender account backing this thread is missing or its status isn’t one of connected, active, or warming. The inbox UI renders an amber banner and disables the reply composer in that state — agents should refuse to call sendConversationMessage and prompt the user to reconnect first.
GET resets unread_count to 0. Don’t use this endpoint just to peek at a thread from a polling loop — use listConversationMessages instead, which does not mutate state.Ownership errors mask existence. 404 is returned both when the id is unknown and when it’s owned by another user — the API never reveals whether a foreign conversation exists.PATCH accepts two fields.status: "active" | "archived" — archive/un-archive the thread. Other string values are silently dropped.unread_count: number — raw counter override. Most agents can ignore this; the server already resets to 0 on GET."No valid fields to update".Preconditions before replying.GET /api/conversations/{id} — confirm senderDisconnected: false.sendConversationMessage.Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Conversation UUID. Must be owned by the authenticated user — other callers get 404.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Conversation, all messages, participant metadata, and sender health.
Canonical conversation row. unread_count is always 0 here — the server resets it as part of this call.
Every message in the thread, ordered sent_at ASC (oldest first). Rendered top-to-bottom in the UI.
Best-effort metadata about the prospect on the other end of the thread. Populated by joining the conversation's participant identifier against campaign_prospects and (for LinkedIn) linkedin_conversations. Any field can be missing.
true when the sender account is missing or its status isn't connected/active/warming. The UI renders an amber warning banner and the reply composer should refuse to send until the user reconnects.
Minimal snapshot of the sender account tied to this conversation. null when the account no longer exists.