4.4 KiB
ComparAIson — API Reference
Base URL
Development: http://localhost:3000
Production: https://comparaison.tophermayor.com
Authentication
All authenticated endpoints use Better Auth session cookies.
POST /api/auth/sign-up
Create a new account.
Request:
{
"name": "Alex Johnson",
"email": "alex@example.com",
"password": "securepassword123"
}
Response: 200 OK — Sets session cookie, returns user object
POST /api/auth/sign-in
Sign in to existing account.
Request:
{
"email": "alex@example.com",
"password": "securepassword123"
}
Response: 200 OK — Sets session cookie, redirects to callbackUrl
POST /api/auth/sign-out
Sign out, clears session.
Response: 200 OK — Redirects to /
Comparison Endpoints
POST /api/compare
Start a new comparison research. Returns a Server-Sent Events stream.
Authentication: Required
Request:
{
"query": "for modern web development",
"items": ["React", "Vue", "Svelte"],
"dimensions": ["Performance", "Developer Experience"]
}
| Field | Type | Required | Description |
|---|---|---|---|
query |
string | No | Context/focus for the comparison |
items |
string[] | Yes | Items to compare (2-10) |
dimensions |
string[] | No | Optional dimension hints |
Response: 200 OK — text/event-stream
SSE event format:
event: progress
data: {"status":"researching","message":"Analyzing comparison request...","itemsCompleted":0,"totalItems":3,"currentStep":"Analyzing comparison request..."}
event: progress
data: {"status":"researching","message":"Researching React...","itemsCompleted":1,"totalItems":3,"currentStep":"Analyzing React"}
event: progress
data: {"status":"completed","message":"Research complete!","itemsCompleted":3,"totalItems":3,"currentStep":"Done"}
event: done
data: {"id":"clx123abc","slug":"react-vs-vue-vs-svelte-clx123","data":{...full comparison data...}}
Error Response: 400 Bad Request
{ "error": "At least 2 items are required" }
Page Routes
GET /
Landing page. Public. Shows hero, example comparisons, features.
GET /sign-in
Sign in form. Public. Redirects to /compare on success.
GET /sign-up
Sign up form. Public. Redirects to /compare on success.
GET /compare
Comparison creation page. Protected. Shows item input form + streaming progress.
GET /compare/[slug]
Comparison results page. Public (if comparison is public). Shows tabbed visualization layout.
URL format: /compare/react-vs-vue-vs-svelte-clx123a
GET /explore
Public comparisons feed. Public. Grid layout with search + category filter.
GET /profile
User profile page. Protected. Shows user info, stats, and saved comparisons.
TypeScript Types
ComparisonRequest
interface ComparisonRequest {
query: string;
items: string[];
dimensions?: string[];
}
ComparisonResult
interface ComparisonResult {
items: ItemResearch[];
dimensions: string[];
summary: string;
recommendation: string;
}
ItemResearch
interface ItemResearch {
name: string;
description: string;
overallScore: number;
dimensions: Record<string, DimensionResult>;
pros: string[];
cons: string[];
sources: { title: string; url: string; snippet: string }[];
}
DimensionResult
interface DimensionResult {
score: number; // 1-10
summary: string;
details: string;
pros: string[];
cons: string[];
}
ResearchProgress (SSE)
type ResearchProgress =
| { stage: "parsing"; message: string }
| { stage: "searching"; item: string; results: number }
| { stage: "researching"; item: string; progress: number }
| { stage: "synthesizing"; message: string }
| { stage: "complete"; result: ComparisonResult }
| { stage: "error"; error: string };
ComparisonData (Frontend)
interface ComparisonData {
id: string;
userId: string;
title: string;
query: string;
slug: string;
status: "researching" | "completed" | "failed";
summary: string;
items: {
name: string;
description: string;
overallScore: number;
dimensions: Record<string, DimensionResult>;
pros: string[];
cons: string[];
}[];
dimensions: string[];
tags: string[];
isPublic: boolean;
viewCount: number;
createdAt: string;
updatedAt: string;
}