Conversation management
List conversations
Agents see only their own and unassigned conversations. Supervisors and admins see all conversations.
query Parameters
statusThe complete set of conversation states. Mirrors ConversationStatus in crates/omni-common/src/models/conversation.rs.
pending and expired were removed by migrations/20260326000039_simplify_conversation_statuses.sql (pending → open, expired → resolved) and snoozed was added by migrations/20260519000012_conversation_snooze.sql. Passing a removed value as a status filter is rejected with 400 before the handler runs, because the query struct deserializes straight into this enum.
A snoozed conversation is hidden from the inbox until snoozed_until passes, at which point it reopens automatically.
assigned_agent_idpageper_pageList conversations › Responses
List of conversations with contact info
idcontact_idstatusThe complete set of conversation states. Mirrors ConversationStatus in crates/omni-common/src/models/conversation.rs.
pending and expired were removed by migrations/20260326000039_simplify_conversation_statuses.sql (pending → open, expired → resolved) and snoozed was added by migrations/20260519000012_conversation_snooze.sql. Passing a removed value as a status filter is rejected with 400 before the handler runs, because the query struct deserializes straight into this enum.
A snoozed conversation is hidden from the inbox until snoozed_until passes, at which point it reopens automatically.
last_message_atunread_countcreated_atupdated_atcontact_channelwhatsapp, instagram, or email
assigned_agent_idassigned_agent_nameFull name of the assigned agent (null when unassigned)
contact_namecontact_phoneAll co-assignees (human agents and/or AI agent) attached to this conversation via the conversation_assignees junction, ordered by assignment time. assigned_agent_id remains the denormalized primary.
Get a single conversation
path Parameters
idGet a single conversation › Responses
Conversation details
idcontact_idstatusThe complete set of conversation states. Mirrors ConversationStatus in crates/omni-common/src/models/conversation.rs.
pending and expired were removed by migrations/20260326000039_simplify_conversation_statuses.sql (pending → open, expired → resolved) and snoozed was added by migrations/20260519000012_conversation_snooze.sql. Passing a removed value as a status filter is rejected with 400 before the handler runs, because the query struct deserializes straight into this enum.
A snoozed conversation is hidden from the inbox until snoozed_until passes, at which point it reopens automatically.
last_message_atunread_countcreated_atupdated_atcontact_channelwhatsapp, instagram, or email
assigned_agent_idassigned_agent_nameFull name of the assigned agent (null when unassigned)
contact_namecontact_phoneAll co-assignees (human agents and/or AI agent) attached to this conversation via the conversation_assignees junction, ordered by assignment time. assigned_agent_id remains the denormalized primary.
Assign or unassign an agent
Add an assignee (human agent or AI agent) to a conversation
Adds a co-assignee to a conversation. A conversation may have multiple human assignees at once, tracked in the conversation_assignees junction table; the earliest human is kept as the denormalized primary (assigned_agent_id) for capacity routing and WebSocket targeting. Supervisors/admins may add any agent; regular agents may only add themselves. Exactly one of agent_id or ai_agent_id must be set.
Handing off to AI (ai_agent_id) is mutually exclusive with human assignees: it clears all human assignees, sets assigned_agent_id to null, marks the conversation ai_handled, and activates the AI conversation state. Adding a human agent while AI is active pauses AI (deactivates the AI state and unlinks the AI agent).
path Parameters
idAdd an assignee (human agent or AI agent) to a conversation › Request Body
agent_idHuman agent to add as co-assignee
ai_agent_idAI agent to hand the conversation off to
Add an assignee (human agent or AI agent) to a conversation › Responses
Assignee added
messageRemove an assignee (human agent or AI agent) from a conversation
Removes a co-assignee. Pass agent_id to remove a human assignee (the primary assigned_agent_id is then re-synced to the earliest remaining human, or null if none remain), or ai=true to hand AI off / deactivate the AI conversation state. Supervisors/admins may remove any agent; regular agents may only remove themselves. Exactly one selector is required.
path Parameters
idquery Parameters
agent_idHuman agent to remove. Mutually exclusive with ai.
aiSet true to remove/deactivate the AI assignee.
Remove an assignee (human agent or AI agent) from a conversation › Responses
Assignee removed
messageUpdate conversation status
path Parameters
idUpdate conversation status › Request Body
statusThe complete set of conversation states. Mirrors ConversationStatus in crates/omni-common/src/models/conversation.rs.
pending and expired were removed by migrations/20260326000039_simplify_conversation_statuses.sql (pending → open, expired → resolved) and snoozed was added by migrations/20260519000012_conversation_snooze.sql. Passing a removed value as a status filter is rejected with 400 before the handler runs, because the query struct deserializes straight into this enum.
A snoozed conversation is hidden from the inbox until snoozed_until passes, at which point it reopens automatically.
Update conversation status › Responses
Status updated
messageconversation_idstatusBulk conversation actions
Apply bulk actions to multiple conversations: resolve, reopen, assign, add/remove tags. Max 100 conversations per request.
Bulk conversation actions › Request Body
conversation_idsBulk conversation actions › Responses
Bulk action applied
messageaffected_count