Conversations API
Conversations are multi-tenant messaging threads that support direct messages, group chats, and project-scoped discussions. Unlike channels, conversations are scoped to specific participants and support cursor-based message pagination, member management with UPSERT semantics, and bulk read receipts.
Base path and authentication
All endpoints use the base path /api/v2/conversations. Requires a valid JWT in the Authorization: Bearer header. Rate limit: 60 requests per minute.
Conversation CRUD
Create, list, update, and delete conversations. The authenticated user is automatically added as a member when creating a conversation.
/api/v2/conversationsAuthenticatedList all conversations the authenticated user is a member of. Supports filtering by type, unread status, and archive state.
Query Parameters
typestringFilter by conversation type (e.g. direct, group, project).
unreadbooleanIf true, return only conversations with unread messages.
archivedbooleanIf true, include archived conversations.
limitinteger20Maximum number of conversations to return.
offsetinteger0Number of conversations to skip for pagination.
Request
400">curl -X 400">GET 400">class="text-emerald-400">"https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations?400">type=group&limit=10" \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"data": [
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Project Alpha Discussion",
400">class="text-emerald-400">"conversation_type": 400">class="text-emerald-400">"group",
400">class="text-emerald-400">"description": 400">class="text-emerald-400">"Planning thread for Project Alpha",
400">class="text-emerald-400">"project_id": 400">class="text-emerald-400">"proj_b2c3d4e5-f6a7-8901-bcde-f23456789012",
400">class="text-emerald-400">"is_archived": false,
400">class="text-emerald-400">"member_count": 4,
400">class="text-emerald-400">"created_by": 400">class="text-emerald-400">"usr_8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-02-15T10:00:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T14:22:00.000Z"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"conv_d4e5f6a7-8901-bcde-f234-567890abcdef",
400">class="text-emerald-400">"name": null,
400">class="text-emerald-400">"conversation_type": 400">class="text-emerald-400">"direct",
400">class="text-emerald-400">"description": null,
400">class="text-emerald-400">"project_id": null,
400">class="text-emerald-400">"is_archived": false,
400">class="text-emerald-400">"member_count": 2,
400">class="text-emerald-400">"created_by": 400">class="text-emerald-400">"usr_2a3b4c5d-6e7f-8901-abcd-ef2345678901",
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-01T09:30:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T12:15:00.000Z"
}
],
400">class="text-emerald-400">"pagination": {
400">class="text-emerald-400">"limit": 10,
400">class="text-emerald-400">"offset": 0,
400">class="text-emerald-400">"total": 2
}
}/api/v2/conversationsAuthenticatedCreate a new conversation. The authenticated user is automatically added as a member. At least one other member must be specified in member_ids.
Body Parameters
conversation_typestringrequiredType of conversation: direct, group, or project.
member_idsstring[]requiredArray of user IDs to add as initial members.
namestringDisplay name for the conversation. Typically used for group and project conversations.
descriptionstringShort description of the conversation purpose.
project_idstringAssociate the conversation with a project.
parent_message_idstringCreate as a threaded reply to an existing message.
member_typesobjectMap of member_id to member type (e.g. user, twin, agent).
settingsobjectConversation-level settings (notifications, pinning, etc.).
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"conversation_type": 400">class="text-emerald-400">"group",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Sprint Planning",
400">class="text-emerald-400">"description": 400">class="text-emerald-400">"Weekly sprint planning thread",
400">class="text-emerald-400">"member_ids": [
400">class="text-emerald-400">"usr_2a3b4c5d-6e7f-8901-abcd-ef2345678901",
400">class="text-emerald-400">"usr_3b4c5d6e-7f80-9012-bcde-f34567890123"
],
400">class="text-emerald-400">"project_id": 400">class="text-emerald-400">"proj_b2c3d4e5-f6a7-8901-bcde-f23456789012"
}'Response 201
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"data": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"conv_e5f6a7b8-9012-cdef-3456-7890abcdef12",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Sprint Planning",
400">class="text-emerald-400">"conversation_type": 400">class="text-emerald-400">"group",
400">class="text-emerald-400">"description": 400">class="text-emerald-400">"Weekly sprint planning thread",
400">class="text-emerald-400">"project_id": 400">class="text-emerald-400">"proj_b2c3d4e5-f6a7-8901-bcde-f23456789012",
400">class="text-emerald-400">"is_archived": false,
400">class="text-emerald-400">"member_count": 3,
400">class="text-emerald-400">"created_by": 400">class="text-emerald-400">"usr_8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T15:30:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T15:30:00.000Z"
}
}/api/v2/conversations/:idAuthenticatedGet detailed information about a specific conversation, including its full member list.
Path Parameters
idstringrequiredThe conversation ID.
Request
400">curl -X 400">GET https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"data": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Project Alpha Discussion",
400">class="text-emerald-400">"conversation_type": 400">class="text-emerald-400">"group",
400">class="text-emerald-400">"description": 400">class="text-emerald-400">"Planning thread for Project Alpha",
400">class="text-emerald-400">"project_id": 400">class="text-emerald-400">"proj_b2c3d4e5-f6a7-8901-bcde-f23456789012",
400">class="text-emerald-400">"is_archived": false,
400">class="text-emerald-400">"settings": {},
400">class="text-emerald-400">"created_by": 400">class="text-emerald-400">"usr_8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-02-15T10:00:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T14:22:00.000Z",
400">class="text-emerald-400">"members": [
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"usr_8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
400">class="text-emerald-400">"display_name": 400">class="text-emerald-400">"Matty Squarzoni",
400">class="text-emerald-400">"role": 400">class="text-emerald-400">"admin",
400">class="text-emerald-400">"member_type": 400">class="text-emerald-400">"user",
400">class="text-emerald-400">"joined_at": 400">class="text-emerald-400">"2026-02-15T10:00:00.000Z"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"usr_2a3b4c5d-6e7f-8901-abcd-ef2345678901",
400">class="text-emerald-400">"display_name": 400">class="text-emerald-400">"Sarah Chen",
400">class="text-emerald-400">"role": 400">class="text-emerald-400">"member",
400">class="text-emerald-400">"member_type": 400">class="text-emerald-400">"user",
400">class="text-emerald-400">"joined_at": 400">class="text-emerald-400">"2026-02-15T10:00:00.000Z"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"twn_c4d5e6f7-8901-abcd-ef23-456789012345",
400">class="text-emerald-400">"display_name": 400">class="text-emerald-400">"Research Assistant",
400">class="text-emerald-400">"role": 400">class="text-emerald-400">"member",
400">class="text-emerald-400">"member_type": 400">class="text-emerald-400">"twin",
400">class="text-emerald-400">"joined_at": 400">class="text-emerald-400">"2026-02-16T08:00:00.000Z"
}
]
}
}/api/v2/conversations/:idAuthenticatedUpdate conversation properties. Only conversation admins can update.
Path Parameters
idstringrequiredThe conversation ID.
Body Parameters
namestringUpdated conversation name.
descriptionstringUpdated description.
is_archivedbooleanSet to true to archive, false to unarchive.
settingsobjectUpdated conversation settings.
Request
400">curl -X 400">PATCH https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Project Alpha - Archived",
400">class="text-emerald-400">"is_archived": true
}'Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"data": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Project Alpha - Archived",
400">class="text-emerald-400">"conversation_type": 400">class="text-emerald-400">"group",
400">class="text-emerald-400">"description": 400">class="text-emerald-400">"Planning thread for Project Alpha",
400">class="text-emerald-400">"project_id": 400">class="text-emerald-400">"proj_b2c3d4e5-f6a7-8901-bcde-f23456789012",
400">class="text-emerald-400">"is_archived": true,
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-02-15T10:00:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T15:45:00.000Z"
}
}/api/v2/conversations/:idAuthenticatedDelete or leave a conversation. If the authenticated user is an admin, the entire conversation is deleted. If they are a regular member, they leave the conversation instead.
Path Parameters
idstringrequiredThe conversation ID.
Request
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_e5f6a7b8-9012-cdef-3456-7890abcdef12 \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"deleted": true
}Note: When a non-admin member calls DELETE, the response returns {"success": true, "left": true} instead of "deleted": true. The conversation continues to exist for other members.
Messages
Send and retrieve messages within a conversation. Messages use cursor-based pagination in reverse chronological order. Sending a message also updates the conversation's updated_at timestamp and emits a real-time socket event to all connected members.
/api/v2/conversations/:id/messagesAuthenticatedList messages in a conversation with cursor-based pagination. Messages are returned in reverse chronological order (newest first).
Path Parameters
idstringrequiredThe conversation ID.
Query Parameters
cursorstringCursor from a previous response to fetch the next page. Omit for the first page.
limitinteger50Number of messages to return per page.
Request
400">curl -X 400">GET 400">class="text-emerald-400">"https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890/messages?limit=20" \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"data": [
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"msg_f7e6d5c4-b3a2-1098-7654-321fedcba098",
400">class="text-emerald-400">"conversation_id": 400">class="text-emerald-400">"conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"user_id": 400">class="text-emerald-400">"usr_8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
400">class="text-emerald-400">"content": 400">class="text-emerald-400">"Let us finalize the Q2 roadmap today.",
400">class="text-emerald-400">"message_type": 400">class="text-emerald-400">"user",
400">class="text-emerald-400">"parent_message_id": null,
400">class="text-emerald-400">"metadata": {},
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T14:22:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T14:22:00.000Z"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"msg_e6d5c4b3-a210-9876-5432-1fedcba09876",
400">class="text-emerald-400">"conversation_id": 400">class="text-emerald-400">"conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"user_id": 400">class="text-emerald-400">"usr_2a3b4c5d-6e7f-8901-abcd-ef2345678901",
400">class="text-emerald-400">"content": 400">class="text-emerald-400">"Sounds good. I will pull up the backlog.",
400">class="text-emerald-400">"message_type": 400">class="text-emerald-400">"user",
400">class="text-emerald-400">"parent_message_id": null,
400">class="text-emerald-400">"metadata": {},
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T14:20:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T14:20:00.000Z"
}
],
400">class="text-emerald-400">"pagination": {
400">class="text-emerald-400">"cursor": 400">class="text-emerald-400">"msg_e6d5c4b3-a210-9876-5432-1fedcba09876",
400">class="text-emerald-400">"hasMore": true,
400">class="text-emerald-400">"total": 128
}
}/api/v2/conversations/:id/messagesAuthenticatedSend a message in a conversation. Updates the conversation's updated_at timestamp and emits a real-time socket event to connected members.
Path Parameters
idstringrequiredThe conversation ID.
Body Parameters
contentstringrequiredThe message text content.
message_typestringuserMessage type (e.g. user, system, twin).
parent_message_idstringID of the parent message for threaded replies.
metadataobjectArbitrary metadata to attach to the message.
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890/messages \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"content": 400">class="text-emerald-400">"The revised timeline looks good. Shipping next Tuesday.",
400">class="text-emerald-400">"metadata": {
400">class="text-emerald-400">"mentions": [400">class="text-emerald-400">"usr_2a3b4c5d-6e7f-8901-abcd-ef2345678901"]
}
}'Response 201
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"data": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"msg_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"conversation_id": 400">class="text-emerald-400">"conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"user_id": 400">class="text-emerald-400">"usr_8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
400">class="text-emerald-400">"content": 400">class="text-emerald-400">"The revised timeline looks good. Shipping next Tuesday.",
400">class="text-emerald-400">"message_type": 400">class="text-emerald-400">"user",
400">class="text-emerald-400">"parent_message_id": null,
400">class="text-emerald-400">"metadata": {
400">class="text-emerald-400">"mentions": [400">class="text-emerald-400">"usr_2a3b4c5d-6e7f-8901-abcd-ef2345678901"]
},
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T15:50:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T15:50:00.000Z"
}
}Members
Add and remove members from a conversation. Adding a member uses UPSERT semantics -- if the member already exists, the operation succeeds without error. Only admins can remove other members.
/api/v2/conversations/:id/membersAuthenticatedAdd a member to the conversation. Uses UPSERT semantics, so adding an existing member is a no-op that returns success.
Path Parameters
idstringrequiredThe conversation ID.
Body Parameters
member_idstringrequiredThe user or twin ID to add.
member_typestringuserType of member: user or twin.
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890/members \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"member_id": 400">class="text-emerald-400">"usr_3b4c5d6e-7f80-9012-bcde-f34567890123",
400">class="text-emerald-400">"member_type": 400">class="text-emerald-400">"user"
}'Response 201
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"added": true,
400">class="text-emerald-400">"member_id": 400">class="text-emerald-400">"usr_3b4c5d6e-7f80-9012-bcde-f34567890123"
}/api/v2/conversations/:id/members/:memberIdAuthenticatedRemove a member from the conversation. Only conversation admins can remove other members.
Path Parameters
idstringrequiredThe conversation ID.
memberIdstringrequiredThe member ID to remove.
Request
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890/members/usr_3b4c5d6e-7f80-9012-bcde-f34567890123 \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"removed": true,
400">class="text-emerald-400">"member_id": 400">class="text-emerald-400">"usr_3b4c5d6e-7f80-9012-bcde-f34567890123"
}Read Receipts
Mark messages as read in bulk. Uses UPSERT on the read_receipts table, so marking an already-read message is idempotent.
/api/v2/conversations/:id/read-receiptsAuthenticatedMark one or more messages as read. Uses UPSERT so calling this with already-read message IDs is safe and idempotent.
Path Parameters
idstringrequiredThe conversation ID.
Body Parameters
message_idsstring[]requiredArray of message IDs to mark as read.
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/conversations/conv_a1b2c3d4-e5f6-7890-abcd-ef1234567890/read-receipts \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"message_ids": [
400">class="text-emerald-400">"msg_f7e6d5c4-b3a2-1098-7654-321fedcba098",
400">class="text-emerald-400">"msg_e6d5c4b3-a210-9876-5432-1fedcba09876"
]
}'Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"marked_read": 2
}