Skip to main content

Overview

The Conversations API enables direct messaging between users on the platform. It supports one-on-one conversations with text messages and file attachments.

Queries

getConverstion

Retrieve a conversation between two users with all messages. Input Parameters:
userId
string
required
First user ID
otherUserId
string
required
Second user ID
Response: Returns a conversation object with:
id
string
Conversation ID
senderId
string
ID of conversation initiator
receiverId
string
ID of conversation recipient
sender
object
Sender user details (id, name, email, username)
receiver
object
Receiver user details (id, name, email, username)
messages
array
Array of message objects ordered by creation time (ascending)
createdAt
DateTime
Conversation creation timestamp
updatedAt
DateTime
Last update timestamp
Errors:
  • NOT_FOUND: Conversation not found
Example:
const conversation = await trpc.conversation.getConverstion.query({
  userId: "user_clxxx1",
  otherUserId: "user_clxxx2"
});

console.log(`Found ${conversation.messages.length} messages`);

Mutations

sendMessage

Send a new message in an existing conversation with optional file attachments. Input Parameters:
conversationId
string
required
ID of the conversation
content
string
required
Message text content
attachements
array
required
Array of attachment objects (can be empty)
attachements[].name
string
required
Attachment file name
attachements[].url
string
required
Attachment file URL
Response: Returns the created message with user details.
id
string
Message ID
content
string
Message content
conversationId
string
Parent conversation ID
userId
string
Sender user ID
user
object
Sender user details
createdAt
DateTime
Message timestamp
Example:
// Send a text message
const message = await trpc.conversation.sendMessage.mutate({
  conversationId: "conv_clxxx...",
  content: "Hi! I'm interested in your web development gig.",
  attachements: []
});

// Send a message with attachments
const messageWithFiles = await trpc.conversation.sendMessage.mutate({
  conversationId: "conv_clxxx...",
  content: "Here are the project requirements",
  attachements: [
    {
      name: "requirements.pdf",
      url: "https://khedma-market.s3.amazonaws.com/user-id/requirements.pdf"
    },
    {
      name: "mockups.fig",
      url: "https://khedma-market.s3.amazonaws.com/user-id/mockups.fig"
    }
  ]
});

Message Model

Message Fields

id
string
Unique message identifier (CUID)
content
string
Message text content
conversationId
string
Parent conversation ID
userId
string
ID of user who sent the message
createdAt
DateTime
Message creation timestamp
updatedAt
DateTime
Last update timestamp

Relations

user
User
User who sent the message
conversation
Conversation
Parent conversation
attachements
Attachement[]
Files attached to the message

Conversation Model

Conversation Fields

id
string
Unique conversation identifier (CUID)
senderId
string
ID of conversation initiator
receiverId
string
ID of conversation recipient
createdAt
DateTime
Conversation creation timestamp
updatedAt
DateTime
Last update timestamp

Relations

sender
User
User who initiated the conversation
receiver
User
User who received the conversation
messages
Message[]
All messages in the conversation

Server-Side Functions

getOrCreateConversationWithMessages(user1Id, user2Id)

Get existing conversation or create a new one if it doesn’t exist. Parameters:
  • user1Id: First user ID
  • user2Id: Second user ID
Returns: Conversation object with all messages Example:
import { getOrCreateConversationWithMessages } from "@/server/api/routers/conversation";

const conversation = await getOrCreateConversationWithMessages(
  "user_clxxx1",
  "user_clxxx2"
);

getUserConversations(userId)

Fetch all conversations for a user. Parameters:
  • userId: User ID to fetch conversations for
Returns: Array of conversations with messages and participant details Note: Automatically formats conversations so the requesting user is always the “sender”. Example:
import { getUserConversations } from "@/server/api/routers/conversation";

const conversations = await getUserConversations("user_clxxx...");

for (const conv of conversations) {
  const lastMessage = conv.messages[conv.messages.length - 1];
  console.log(`
    With: ${conv.receiver.name}
    Last message: ${lastMessage.content}
    Time: ${lastMessage.createdAt}
  `);
}

getConversationById(id)

Fetch a specific conversation by ID. Parameters:
  • id: Conversation ID
Returns: Conversation object with messages Example:
import { getConversationById } from "@/server/api/routers/conversation";

const conversation = await getConversationById("conv_clxxx...");

getOrCreateConversation(username, currentUser)

Get or create a conversation with a user by their username. Parameters:
  • username: Username of the other user
  • currentUser: Current authenticated user object
Returns: Conversation object or null if user not found Example:
import { getOrCreateConversation } from "@/server/api/routers/conversation";
import { getServerAuthSession } from "@/server/auth";

const session = await getServerAuthSession();
const conversation = await getOrCreateConversation(
  "johndoe",
  session.user
);

Attachment Model

Messages can include file attachments:
id
string
Attachment ID
name
string
File name
url
string
File URL (typically S3)
type
string
File type (e.g., “document”, “image”, “video”)
messageId
string
Associated message ID

Complete Example: Messaging Flow

// 1. Client wants to contact a freelancer
import { getOrCreateConversation } from "@/server/api/routers/conversation";
import { getServerAuthSession } from "@/server/auth";

const session = await getServerAuthSession();
const conversation = await getOrCreateConversation(
  "freelancer_username",
  session.user
);

// 2. Send initial message
const firstMessage = await trpc.conversation.sendMessage.mutate({
  conversationId: conversation.id,
  content: "Hello! I saw your React development gig and I'm interested.",
  attachements: []
});

// 3. Freelancer responds with file
const response = await trpc.conversation.sendMessage.mutate({
  conversationId: conversation.id,
  content: "Great! Here's my portfolio for your review.",
  attachements: [
    {
      name: "portfolio.pdf",
      url: "https://s3.amazonaws.com/portfolio.pdf"
    }
  ]
});

// 4. Retrieve full conversation history
const fullConversation = await trpc.conversation.getConverstion.query({
  userId: session.user.id,
  otherUserId: conversation.receiverId
});

console.log(`Total messages: ${fullConversation.messages.length}`);

// 5. List all user conversations
const allConversations = await getUserConversations(session.user.id);
console.log(`Active conversations: ${allConversations.length}`);

Build docs developers (and LLMs) love