Skip to main content

Schema Definition

The conversations table stores AI chat conversations within projects.

Fields

_id
Id<'conversations'>
required
Unique conversation identifier
projectId
Id<'projects'>
required
ID of the project this conversation belongs to
title
string
required
Conversation title (typically auto-generated based on first message)
updatedAt
number
required
Unix timestamp (in milliseconds) of last update

Indexes

by_project
index
Index on projectId for retrieving all conversations in a projectFields: ["projectId"]

Queries

getById

Retrieve a specific conversation by ID.
id
Id<'conversations'>
required
Conversation identifier
import { api } from "@/convex/_generated/api";
import { useQuery } from "convex/react";

function ConversationHeader({ conversationId }) {
  const conversation = useQuery(api.conversations.getById, { 
    id: conversationId 
  });
  return <h1>{conversation?.title}</h1>;
}
Returns: Conversation object Errors:
  • "Conversation not found" - Conversation doesn’t exist
  • "Project not found" - Associated project doesn’t exist
  • "Unauthorized to access this project" - User is not the project owner

getByProject

Retrieve all conversations in a project.
projectId
Id<'projects'>
required
Project identifier
import { api } from "@/convex/_generated/api";
import { useQuery } from "convex/react";

function ConversationList({ projectId }) {
  const conversations = useQuery(api.conversations.getByProject, { 
    projectId 
  });
  
  return (
    <div>
      {conversations?.map(conv => (
        <div key={conv._id}>
          <h3>{conv.title}</h3>
          <small>{new Date(conv.updatedAt).toLocaleDateString()}</small>
        </div>
      ))}
    </div>
  );
}
Returns: Array of conversations, ordered by most recent first Errors:
  • "Project not found" - Project doesn’t exist
  • "Unauthorized to access this project" - User is not the owner

getMessages

Retrieve all messages in a conversation.
conversationId
Id<'conversations'>
required
Conversation identifier
import { api } from "@/convex/_generated/api";
import { useQuery } from "convex/react";

function ChatThread({ conversationId }) {
  const messages = useQuery(api.conversations.getMessages, { 
    conversationId 
  });
  
  return (
    <div>
      {messages?.map(msg => (
        <div key={msg._id} className={msg.role}>
          {msg.content}
        </div>
      ))}
    </div>
  );
}
Returns: Array of messages in chronological order (oldest first) Errors:
  • "Conversation not found" - Conversation doesn’t exist
  • "Project not found" - Associated project doesn’t exist
  • "Unauthorized to access this project" - User is not the project owner

Mutations

create

Create a new conversation in a project.
projectId
Id<'projects'>
required
Project identifier
title
string
required
Conversation title
import { api } from "@/convex/_generated/api";
import { useMutation } from "convex/react";

function NewConversation({ projectId }) {
  const createConversation = useMutation(api.conversations.create);
  
  const handleCreate = async () => {
    const conversationId = await createConversation({
      projectId,
      title: "New Chat"
    });
    console.log("Created conversation:", conversationId);
  };
  
  return <button onClick={handleCreate}>New Chat</button>;
}
Returns: Id<'conversations'> - ID of the newly created conversation Errors:
  • "Project not found" - Project doesn’t exist
  • "Unauthorized to access this project" - User is not the project owner

Messages

Each conversation contains multiple messages. See the Messages schema for details.

Source Reference

  • Schema definition: convex/schema.ts:46-50
  • Queries and mutations: convex/conversations.ts

Build docs developers (and LLMs) love