Method Reference
Complete reference for all AskVerdict SDK client methods — signatures, parameters, return types, and examples.
Complete reference for every public method on AskVerdictClient. Methods are grouped by domain. All methods are async and return a Promise unless noted otherwise.
All methods throw an AskVerdictError on API or network failure. See Error Handling at the end of this page for catch patterns.
Verdicts
createVerdict
Create a new AI debate and receive its ID and SSE stream URL. The debate runs asynchronously — use streamVerdict to follow progress in real time.
async createVerdict(params: CreateDebateParams): Promise<CreateDebateResult>| Name | Type | Required | Description |
|---|---|---|---|
params.question | string | Required | The question or proposition to debate. |
params.mode | "fast" | "balanced" | "thorough" | "analytical" | Optional | Debate depth. Defaults to "fast". |
params.agentCount | number | Optional | Number of AI agents to involve (2–6). |
params.maxRounds | number | Optional | Maximum debate rounds before forced synthesis. |
params.enableSearch | boolean | Optional | Allow agents to run web searches during the debate. |
params.context | string | Optional | Background information provided to all agents. |
params.preset | string | Optional | Named debate preset (e.g. "business-decision"). |
params.skipCache | boolean | Optional | Force a fresh debate even if a cached result exists. |
Returns CreateDebateResult
| Field | Type | Description |
|---|---|---|
id | string | Debate ID (use this for all subsequent calls) |
status | string | Initial status ("pending") |
streamUrl | string | Full SSE URL to stream events |
debateId | string | Deprecated alias for id |
const result = await client.createVerdict({
question: "Should we adopt Kubernetes?",
mode: "balanced",
});
console.log(result.id); // "dbt_abc123"
console.log(result.streamUrl); // "https://api.askverdict.ai/v1/verdicts/dbt_abc123/stream"getVerdict
Retrieve a single debate by ID, including its full verdict when complete.
async getVerdict(id: string): Promise<{ verdict: DebateResponse }>| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The debate ID. |
Returns { verdict: DebateResponse } — see the DebateResponse shape below.
DebateResponse fields:
| Field | Type | Description |
|---|---|---|
id | string | Debate ID |
question | string | Original question |
status | DebateStatus | active | completed | failed | paused | pending | running |
verdict | Verdict | null | Full verdict (null if not yet completed) |
cost | DebateCostRecord | null | Token cost breakdown |
mode | string | null | Debate mode used |
agentCount | number | null | Number of agents |
roundCount | number | null | Actual rounds completed |
fundingSource | "free_tier" | "user_credits" | "byok" | null | How the debate was funded |
isPublic | boolean | Whether the debate is publicly visible |
createdAt | string | ISO 8601 timestamp |
completedAt | string | null | ISO 8601 completion timestamp |
const { verdict } = await client.getVerdict("dbt_abc123");
if (verdict.status === "completed" && verdict.verdict) {
console.log(verdict.verdict.recommendation.recommendation);
console.log(`Confidence: ${Math.round(verdict.verdict.confidence * 100)}%`);
}listVerdicts
List debates for the authenticated user with pagination and status filtering.
async listVerdicts(params?: ListDebatesParams): Promise<ListDebatesResult>| Name | Type | Required | Description |
|---|---|---|---|
params.page | number | Optional | Page number (1-indexed). Defaults to 1. |
params.pageSize | number | Optional | Results per page. Defaults to 20. |
params.limit | number | Optional | Alias for pageSize. |
params.status | DebateStatus | Optional | Filter by status: active, completed, failed, paused, pending, running. |
Returns ListDebatesResult:
| Field | Type | Description |
|---|---|---|
debates | DebateResponse[] | Array of debate objects |
total | number | Total matching debates |
page | number | Current page |
pageSize | number | Results per page |
hasMore | boolean | Whether more pages exist |
const result = await client.listVerdicts({ pageSize: 20 });
for (const debate of result.debates) {
console.log(debate.id, debate.status, debate.question);
}deleteVerdict
Permanently delete a debate. This action cannot be undone.
async deleteVerdict(id: string): Promise<void>| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The debate ID to delete. |
await client.deleteVerdict("dbt_abc123");
// Resolves with void; throws AskVerdictError on failurestreamVerdict
Stream SSE events for a running or completed debate. Returns an AsyncGenerator — iterate with for await.
async *streamVerdict(id: string): AsyncGenerator<StreamEvent>| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The debate ID to stream. |
StreamEvent shape:
| Field | Type | Description |
|---|---|---|
id | string | SSE event ID |
type | string | Event type (see table below) |
data | unknown | Event payload (usually an object) |
timestamp | number | Client-side Date.now() when received |
Common event types:
type | When fired |
|---|---|
debate:start | Debate begins processing |
agent:thinking | An agent is composing a turn |
agent:argument | An agent published an argument |
agent:search | An agent performed a web search |
verdict:start | Synthesis phase begins |
verdict:complete | Full verdict is ready |
debate:complete | Debate is fully done |
debate:error | Fatal error during debate |
cost:update | Running token cost update |
stream:end | Stream closed by server |
for await (const event of client.streamVerdict("dbt_abc123")) {
if (event.type === "agent:argument") {
const data = event.data as { agentName: string; content: string };
console.log(`${data.agentName}: ${data.content}`);
}
if (event.type === "debate:complete") break;
}streamVerdict uses the native fetch SSE reader. Ensure your environment supports fetch (Node 18+, Bun, or browsers). The generator does not automatically reconnect on drop — wrap in retry logic for long-running streams.
Voting
getVotes
Get vote tallies for all argument claims in a debate. If authenticated, each tally includes the caller's own vote.
async getVotes(debateId: string): Promise<VoteMap>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
Returns VoteMap — a Record<string, ClaimVoteTally> keyed by claim ID.
ClaimVoteTally:
| Field | Type | Description |
|---|---|---|
agree | number | Total agree votes |
disagree | number | Total disagree votes |
userVote | VoteValue | undefined | Caller's own vote (authenticated only) |
const votes = await client.getVotes("dbt_abc123");
for (const [claimId, tally] of Object.entries(votes)) {
console.log(`${claimId}: +${tally.agree} / -${tally.disagree}`);
if (tally.userVote) {
console.log(` Your vote: ${tally.userVote}`);
}
}castVote
Cast or update a vote on an argument claim. Pass "neutral" to remove an existing vote.
async castVote(debateId: string, claimId: string, vote: VoteValue): Promise<void>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
claimId | string | Required | The claim ID to vote on. |
vote | "agree" | "disagree" | "neutral" | Required | Your vote. Use "neutral" to remove a previous vote. |
await client.castVote("dbt_abc123", "claim_xyz", "agree");removeVote
Remove the authenticated user's vote on a specific claim.
async removeVote(debateId: string, claimId: string): Promise<void>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
claimId | string | Required | The claim ID to remove the vote from. |
await client.removeVote("dbt_abc123", "claim_xyz");Polls
getPolls
Get all polls for a debate, with vote tallies and (if authenticated) the caller's own vote per poll.
async getPolls(debateId: string): Promise<Poll[]>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
Returns Poll[]. Each Poll:
| Field | Type | Description |
|---|---|---|
id | string | Poll ID |
debateId | string | Parent debate |
question | string | Poll question |
options | PollOption[] | Array of { id, label } |
status | "open" | "closed" | Whether voting is open |
tallies | Record<string, number> | Vote counts keyed by option ID |
totalVotes | number | Sum of all votes |
userVote | string | null | Option ID the caller voted for |
createdAt | string | ISO 8601 |
closedAt | string | null | ISO 8601 or null if still open |
const polls = await client.getPolls("dbt_abc123");
for (const poll of polls) {
console.log(`${poll.question} (${poll.status})`);
for (const option of poll.options) {
const votes = poll.tallies[option.id] ?? 0;
console.log(` ${option.label}: ${votes} votes`);
}
}createPoll
Create a poll on a debate. Requires debate ownership.
async createPoll(debateId: string, question: string, options: string[]): Promise<Poll>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
question | string | Required | The poll question. |
options | string[] | Required | Poll option labels. Minimum 2, maximum 6. |
const poll = await client.createPoll(
"dbt_abc123",
"Which argument was most convincing?",
["The pro side — scalability wins", "The con side — cost is too high", "Neither"],
);
console.log(poll.id); // "poll_pqr789"votePoll
Vote on a poll option.
async votePoll(debateId: string, pollId: string, optionId: string): Promise<void>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
pollId | string | Required | The poll ID. |
optionId | string | Required | The ID of the option to vote for. |
await client.votePoll("dbt_abc123", "poll_pqr789", "opt_001");closePoll
Close a poll to prevent further votes. Requires debate ownership.
async closePoll(debateId: string, pollId: string): Promise<void>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
pollId | string | Required | The poll ID to close. |
await client.closePoll("dbt_abc123", "poll_pqr789");deletePoll
Delete a poll. Requires debate ownership.
async deletePoll(debateId: string, pollId: string): Promise<void>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
pollId | string | Required | The poll ID to delete. |
await client.deletePoll("dbt_abc123", "poll_pqr789");Outcomes
getOutcome
Get the recorded real-world outcome for a debate.
async getOutcome(debateId: string): Promise<OutcomeRecord>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
Returns OutcomeRecord:
| Field | Type | Description |
|---|---|---|
id | string | Outcome record ID |
debateId | string | Parent debate |
actualOutcome | string | Text description of what actually happened |
notes | string | null | Optional notes |
verdictWasCorrect | boolean | null | Whether the AI verdict matched reality |
recordedAt | string | ISO 8601 timestamp |
const outcome = await client.getOutcome("dbt_abc123");
if (outcome.verdictWasCorrect !== null) {
console.log(`Verdict was ${outcome.verdictWasCorrect ? "correct" : "incorrect"}`);
}submitOutcome
Submit a real-world outcome for a completed debate. Used to track AI prediction accuracy over time.
async submitOutcome(debateId: string, params: SubmitOutcomeParams): Promise<OutcomeRecord>| Name | Type | Required | Description |
|---|---|---|---|
debateId | string | Required | The debate ID. |
params.actualOutcome | string | Required | Description of what actually happened. |
params.notes | string | Optional | Additional context or notes. |
params.verdictWasCorrect | boolean | Optional | Whether the AI verdict matched the actual outcome. |
const outcome = await client.submitOutcome("dbt_abc123", {
actualOutcome: "Adopted Kubernetes — deployment time down 40%",
verdictWasCorrect: true,
notes: "The scalability argument proved decisive.",
});getPendingOutcomes
List debates with completed verdicts that have no outcome recorded yet.
async getPendingOutcomes(): Promise<OutcomeRecord[]>const pending = await client.getPendingOutcomes();
console.log(`${pending.length} debates awaiting outcome recording`);
for (const p of pending) {
console.log(p.debateId);
}getOutcomeHistory
Get paginated outcome recording history, optionally filtered by domain.
async getOutcomeHistory(
opts?: { limit?: number; offset?: number; domain?: string }
): Promise<OutcomeRecord[]>| Name | Type | Required | Description |
|---|---|---|---|
opts.limit | number | Optional | Maximum number of records to return. |
opts.offset | number | Optional | Number of records to skip (for pagination). |
opts.domain | string | Optional | Filter outcomes by domain tag. |
const history = await client.getOutcomeHistory({ limit: 50, domain: "business" });Billing
getBalance
Get the authenticated user's credit balance and plan.
async getBalance(): Promise<BalanceInfo>Returns BalanceInfo:
| Field | Type | Description |
|---|---|---|
creditBalance | number | Remaining credits |
plan | string | Current plan (free, byok, byok_pro, etc.) |
const balance = await client.getBalance();
console.log(`${balance.creditBalance} credits remaining on the ${balance.plan} plan`);Search
search
Search your debates by keyword with sorting and filtering.
async search(query: string, opts?: SearchParams): Promise<SearchResult>| Name | Type | Required | Description |
|---|---|---|---|
query | string | Required | Full-text search query. |
opts.type | "debates" | "verdicts" | Optional | Restrict results to debates or verdicts. |
opts.sort | "relevance" | "date" | "popularity" | Optional | Sort order. Defaults to "relevance". |
opts.page | number | Optional | Page number. Defaults to 1. |
opts.limit | number | Optional | Results per page. Defaults to 20. |
opts.status | string | Optional | Filter by debate status. |
opts.mode | string | Optional | Filter by debate mode. |
Returns SearchResult:
| Field | Type | Description |
|---|---|---|
results | SearchResultItem[] | Matching debates |
total | number | Total matches |
page | number | Current page |
totalPages | number | Total page count |
const result = await client.search("kubernetes microservices");
for (const item of result.results) {
console.log(item.question, item.status);
}User
getMe
Get the authenticated user's profile.
async getMe(): Promise<UserProfile>Returns UserProfile:
| Field | Type | Description |
|---|---|---|
id | string | User ID |
name | string | Display name |
email | string | Email address |
image | string | null | Avatar URL |
plan | string | Current plan |
bio | string | null | Profile bio |
location | string | null | Location string |
createdAt | string | ISO 8601 join date |
const me = await client.getMe();
console.log(`Hello, ${me.name} (${me.plan} plan)`);getUsage
Get debate and credit usage for the authenticated user's current billing period.
async getUsage(): Promise<UsageInfo>Returns UsageInfo:
| Field | Type | Description |
|---|---|---|
plan | string | Current plan |
debatesThisMonth | number | Debates run this month |
debatesLimit | number | null | Monthly cap (null = unlimited) |
creditsRemaining | number | Credits left this period |
freeDebateResetAt | string | null | When free allowance resets |
const usage = await client.getUsage();
const cap = usage.debatesLimit ?? "unlimited";
console.log(`${usage.debatesThisMonth} / ${cap} debates this month`);getApiUser
Get the user profile associated with the current API key (v1 endpoint, no session required).
async getApiUser(): Promise<UserProfile>const user = await client.getApiUser();getApiUsage
Get API key request usage stats for the current billing period.
async getApiUsage(): Promise<ApiKeyUsage>Returns ApiKeyUsage:
| Field | Type | Description |
|---|---|---|
keyId | string | The API key ID |
period | string | Billing period label |
totalRequests | number | Total requests this period |
byEndpoint | Record<string, number> | Per-endpoint request counts |
rateLimit | number | Requests per minute limit |
const usage = await client.getApiUsage();
console.log(`${usage.totalRequests} total API requests this period`);Stats
getDashboard
Get aggregated dashboard statistics, optionally scoped to a workspace.
async getDashboard(workspaceId?: string): Promise<DashboardStats>| Name | Type | Required | Description |
|---|---|---|---|
workspaceId | string | Optional | Scope stats to a specific workspace. |
Returns DashboardStats:
| Field | Type | Description |
|---|---|---|
totalDebates | number | All-time debate count |
debatesThisWeek | number | Debates in the last 7 days |
weeklyActivity | number[] | Daily counts for the last 7 days |
modeDistribution | Record<string, number> | Debate count per mode |
averageCost | number | Average USD cost per debate |
currentStreak | number | Current daily debate streak |
const stats = await client.getDashboard();
console.log(`${stats.totalDebates} debates total, ${stats.currentStreak} day streak`);getScore
Get the authenticated user's decision accuracy score.
async getScore(): Promise<DecisionScore>Returns DecisionScore:
| Field | Type | Description |
|---|---|---|
overallAccuracy | number | Fraction correct (0–1) |
totalDecisions | number | Total decisions tracked |
correctPredictions | number | Number correct |
brierScore | number | null | Calibration score (lower is better) |
calibrationScore | number | null | Calibration fraction (0–1) |
const score = await client.getScore();
console.log(`Accuracy: ${Math.round(score.overallAccuracy * 100)}%`);getStreak
Get the authenticated user's debate streak information and milestones.
async getStreak(): Promise<StreakInfo>Returns StreakInfo:
| Field | Type | Description |
|---|---|---|
currentStreak | number | Current consecutive-day streak |
longestStreak | number | All-time longest streak |
totalDebates | number | All-time debate count |
milestones | Array<{ count, reached, reachedAt? }> | Streak milestone records |
const streak = await client.getStreak();
console.log(`Current streak: ${streak.currentStreak} days`);
console.log(`Longest ever: ${streak.longestStreak} days`);Utility
health
Check API health. No authentication required.
async health(): Promise<HealthResponse>Returns HealthResponse:
| Field | Type | Description |
|---|---|---|
status | "ok" | "degraded" | "down" | API health status |
service | string | Service name |
version | string | API version |
timestamp | string | Server timestamp |
const client = new AskVerdictClient(); // no auth needed
const health = await client.health();
if (health.status !== "ok") {
console.warn(`API is ${health.status}`);
}Deprecated Aliases
These methods still work but are deprecated. Use their replacements.
| Deprecated | Replacement |
|---|---|
createDebate(params) | createVerdict(params) |
getDebate(id) | getVerdict(id) — note: returns DebateResponse directly, not wrapped |
listDebates(params) | listVerdicts(params) |
deleteDebate(id) | deleteVerdict(id) |
streamDebate(id) | streamVerdict(id) |
Error Handling
All methods throw AskVerdictError on failure. Inspect .code and .status for structured handling.
import { AskVerdictClient, AskVerdictError } from "@askverdict/sdk";
const client = new AskVerdictClient({ apiKey: process.env.ASKVERDICT_API_KEY });
try {
const result = await client.createVerdict({ question: "..." });
} catch (error) {
if (error instanceof AskVerdictError) {
console.error(`[${error.code}] ${error.message}`);
// error.status → HTTP status (401, 422, 429, etc.)
// error.details → extra context from the API
} else {
throw error; // re-throw unexpected errors
}
}Common error codes:
| Code | HTTP | Meaning |
|---|---|---|
NETWORK_ERROR | — | Fetch failed (DNS, timeout, offline) |
PARSE_ERROR | — | Non-JSON API response |
HTTP_ERROR | varies | Generic HTTP error |
API_ERROR | varies | Structured API error with code from server |
STREAM_ERROR | — | SSE stream failed to open or body was empty |
Rate limit errors arrive as HTTP 429. Inspect error.status === 429 to implement exponential back-off.
Was this page helpful?