Skip to main content

Overview

The Claims API manages factual claims extracted from debate transcripts. It includes both public queries and internal mutations for the fact-checking pipeline. Function Types:
  • Public Query: listByDebate - accessible from client
  • Internal Mutations: saveClaim, saveClaims, updateStatus - only callable from Convex actions/mutations
  • Internal Query: getById - only callable from Convex actions/mutations

listByDebate

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

const claims = await convex.query(api.claims.listByDebate, {
  debateId: debateId
});
Retrieves all claims associated with a specific debate, including their fact-check status and verification results.

Parameters

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

Returns

claims
Claim[]
Array of all claims for the debate

Claim Object Structure

_id
Id<'claims'>
Unique claim identifier
_creationTime
number
Convex automatic creation timestamp
debateId
Id<'debates'>
ID of the associated debate
speaker
0 | 1
Which speaker made the claim (0 = Speaker A, 1 = Speaker B)
claimText
string
The extracted factual claim statement
originalTranscriptExcerpt
string
The original transcript text from which the claim was extracted
status
'pending' | 'checking' | 'true' | 'false' | 'mixed' | 'unverifiable'
Current fact-checking status of the claim
verdict
string | undefined
Human-readable explanation of the fact-check result (optional)
correction
string | undefined
Corrected version of the claim if it was false or mixed (optional)
sources
string[] | undefined
Array of source URLs used for fact-checking (optional)
extractedAt
number
Unix timestamp when claim was extracted from transcript
checkedAt
number | undefined
Unix timestamp when fact-check was completed (optional)

saveClaims

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

await ctx.runMutation(internal.claims.saveClaims, {
  claims: [
    {
      debateId: debateId,
      speaker: 0,
      claimText: "The economy grew by 5% last year",
      originalTranscriptExcerpt: "As I said, the economy grew by 5% last year..."
    },
    {
      debateId: debateId,
      speaker: 1,
      claimText: "Unemployment is at a record low",
      originalTranscriptExcerpt: "Well, unemployment is at a record low..."
    }
  ]
});
Internal mutation to batch-save multiple claims and trigger fact-checking for each.

Parameters

claims
array
required
Array of claim objects to save
claims[].debateId
Id<'debates'>
required
The debate this claim belongs to
claims[].speaker
0 | 1
required
Which speaker made the claim
claims[].claimText
string
required
The extracted claim text
claims[].originalTranscriptExcerpt
string
required
Original transcript excerpt

Returns

return
null
Returns null on success

Behavior

  1. Inserts each claim with status "pending"
  2. Sets extractedAt to Date.now()
  3. Schedules internal.factCheck.check for each claim immediately

saveClaim

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

await ctx.runMutation(internal.claims.saveClaim, {
  debateId: debateId,
  speaker: 0,
  claimText: "The economy grew by 5% last year",
  originalTranscriptExcerpt: "As I said, the economy grew by 5% last year..."
});
Internal mutation to save a single claim and trigger fact-checking.

Parameters

debateId
Id<'debates'>
required
The debate this claim belongs to
speaker
0 | 1
required
Which speaker made the claim (0 or 1)
claimText
string
required
The extracted factual claim
originalTranscriptExcerpt
string
required
The original transcript text

Returns

return
null
Returns null on success

Behavior

Identical to saveClaims but for a single claim:
  1. Inserts claim with status "pending"
  2. Sets extractedAt timestamp
  3. Schedules immediate fact-check

getById

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

const claim = await ctx.runQuery(internal.claims.getById, {
  claimId: claimId
});
Internal query to retrieve a single claim by ID.

Parameters

claimId
Id<'claims'>
required
The ID of the claim to retrieve

Returns

claim
Claim | null
The claim object or null if not found

updateStatus

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

await ctx.runMutation(internal.claims.updateStatus, {
  claimId: claimId,
  status: "true",
  verdict: "This claim is accurate according to official statistics.",
  sources: [
    "https://example.gov/stats",
    "https://example.org/report"
  ]
});
Internal mutation to update a claim’s fact-checking status and results.

Parameters

claimId
Id<'claims'>
required
The ID of the claim to update
status
'checking' | 'true' | 'false' | 'mixed' | 'unverifiable'
required
The new status (cannot be set back to “pending”)
verdict
string
Explanation of the fact-check result
correction
string
Corrected version of the claim (typically used for “false” or “mixed” status)
sources
string[]
Array of source URLs used for verification

Returns

return
null
Returns null on success

Behavior

  • Automatically sets checkedAt to Date.now()
  • Updates all provided fields

Status Flow

Status Definitions

  • pending: Claim extracted, awaiting fact-check
  • checking: Fact-check in progress
  • true: Claim verified as accurate
  • false: Claim verified as inaccurate
  • mixed: Claim partially true/false
  • unverifiable: Cannot be verified with available sources

Validation Schema

const claimValidator = v.object({
  _id: v.id("claims"),
  _creationTime: v.number(),
  debateId: v.id("debates"),
  speaker: v.union(v.literal(0), v.literal(1)),
  claimText: v.string(),
  originalTranscriptExcerpt: v.string(),
  status: v.union(
    v.literal("pending"),
    v.literal("checking"),
    v.literal("true"),
    v.literal("false"),
    v.literal("mixed"),
    v.literal("unverifiable"),
  ),
  verdict: v.optional(v.string()),
  correction: v.optional(v.string()),
  sources: v.optional(v.array(v.string())),
  extractedAt: v.number(),
  checkedAt: v.optional(v.number()),
})

Build docs developers (and LLMs) love