Skip to main content

Overview

The Debates API provides functions to create, end, retrieve, and list debate sessions. All mutations require user authentication via Convex Auth.

create

import { api } from "@/convex/_generated/api";

const debateId = await convex.mutation(api.debates.create, {
  speakerAName: "Alice",
  speakerBName: "Bob"
});
Creates a new debate session with two speakers. The debate is automatically set to “active” status and associated with the authenticated user.

Parameters

speakerAName
string
required
Name of the first speaker in the debate
speakerBName
string
required
Name of the second speaker in the debate

Returns

debateId
Id<'debates'>
The unique identifier for the newly created debate

Authentication

Requires authenticated user. Throws Error("Not authenticated") if user is not logged in.

Behavior

  • Sets initial status to "active"
  • Records startedAt timestamp using Date.now()
  • Associates debate with current authenticated user’s ID

end

import { api } from "@/convex/_generated/api";

await convex.mutation(api.debates.end, {
  debateId: debateId
});
Ends an active debate session and triggers claim extraction from the transcript.

Parameters

debateId
Id<'debates'>
required
The ID of the debate to end

Returns

return
null
Returns null on success

Authentication

Requires authenticated user who owns the debate. Throws:
  • Error("Not authenticated") if user is not logged in
  • Error("Not found") if debate doesn’t exist or user doesn’t own it

Behavior

  1. Validates user owns the debate
  2. Updates debate status to "ended"
  3. Records endedAt timestamp
  4. Schedules internal.claimExtraction.extract to run immediately

get

import { api } from "@/convex/_generated/api";

const debate = await convex.query(api.debates.get, {
  debateId: debateId
});
Retrieves a single debate by ID. No authentication required - debates are publicly readable.

Parameters

debateId
Id<'debates'>
required
The ID of the debate to retrieve

Returns

debate
Debate | null
The debate object or null if not found

Debate Object Structure

_id
Id<'debates'>
Unique debate identifier
_creationTime
number
Convex automatic creation timestamp
userId
Id<'users'>
ID of the user who created the debate
speakerAName
string
Name of speaker A
speakerBName
string
Name of speaker B
status
'active' | 'ended'
Current debate status
startedAt
number
Unix timestamp when debate started
endedAt
number | undefined
Unix timestamp when debate ended (optional, only present for ended debates)

list

import { api } from "@/convex/_generated/api";

const debates = await convex.query(api.debates.list, {});
Lists all debates for the authenticated user, ordered by most recent first.

Parameters

No parameters required.

Returns

debates
Debate[]
Array of debate objects owned by the current user, ordered by creation time (descending)

Authentication

Optional. Returns empty array [] if user is not authenticated.

Behavior

  • Uses by_user index for efficient querying
  • Returns debates in descending order (newest first)
  • Only returns debates owned by the authenticated user

Validation Schema

The debate validator used for type safety:
const debateValidator = v.object({
  _id: v.id("debates"),
  _creationTime: v.number(),
  userId: v.id("users"),
  speakerAName: v.string(),
  speakerBName: v.string(),
  status: v.union(v.literal("active"), v.literal("ended")),
  startedAt: v.number(),
  endedAt: v.optional(v.number()),
})

Status Transitions

  • Debates start as "active" when created
  • Only transition is from "active" to "ended" via the end mutation
  • Ended debates cannot be reactivated

Build docs developers (and LLMs) love