Schema reference
The canonical Zod schemas live in @getsurvey/schema and are consumed by the web app, the SDK, and the MCP server. The shapes below are the inferred TypeScript types.
Survey
type Survey = {
id: string;
projectId: string;
version: number;
status: "draft" | "published" | "archived";
title: string;
description?: string;
locale: string; // BCP 47, default "en"
questions: Question[];
settings: { showProgressBar: boolean; allowAnonymous: boolean; thankYou?: { title: string; body?: string } };
createdAt: string;
updatedAt: string;
};Question
Discriminated union on type. V1 ships eight types.
type Question =
| { type: "short_text"; id: string; prompt: string; required: boolean; helpText?: string; maxLength?: number }
| { type: "long_text"; id: string; prompt: string; required: boolean; helpText?: string; maxLength?: number }
| { type: "single_select"; id: string; prompt: string; required: boolean; choices: Choice[]; randomize?: boolean }
| { type: "multi_select"; id: string; prompt: string; required: boolean; choices: Choice[]; minSelections?: number; maxSelections?: number; randomize?: boolean }
| { type: "likert"; id: string; prompt: string; required: boolean; scale: 3 | 5 | 7; labels?: { low: string; mid?: string; high: string } }
| { type: "nps"; id: string; prompt: string; required: boolean; promptDetractor?: string; promptPromoter?: string }
| { type: "star_rating"; id: string; prompt: string; required: boolean; max: 3 | 5 | 7 }
| { type: "yes_no"; id: string; prompt: string; required: boolean; yesLabel?: string; noLabel?: string };
type Choice = { id: string; label: string; value?: string };Response and Answer
type Answer =
| { questionId: string; type: "short_text" | "long_text"; value: string }
| { questionId: string; type: "single_select"; choiceId: string }
| { questionId: string; type: "multi_select"; choiceIds: string[] }
| { questionId: string; type: "likert"; value: number }
| { questionId: string; type: "nps"; score: number }
| { questionId: string; type: "star_rating"; stars: number }
| { questionId: string; type: "yes_no"; value: boolean };
type Response = {
id: string;
surveyId: string;
surveyVersionId: string;
respondentId?: string;
metadata?: Record<string, string>;
startedAt: string;
submittedAt?: string;
answers: Answer[];
};SurveySummary
The shape returned by summarizeResponses. Designed to drop directly into a downstream prompt.
type SurveySummary = {
surveyId: string;
surveyVersionId: string;
totalResponses: number;
completedResponses: number;
generatedAt: string;
questions: QuestionSummary[];
};
type QuestionSummary =
| { type: "short_text"; ... samples: string[] }
| { type: "long_text"; ... clusters: { theme; count; representativeQuotes }[] }
| { type: "single_select" | "multi_select"; ... buckets: { choiceId; label; count }[] }
| { type: "likert"; ... scale; buckets: number[]; mean }
| { type: "nps"; ... score; promoters; passives; detractors }
| { type: "star_rating"; ... max; buckets: number[]; mean }
| { type: "yes_no"; ... yes; no };