API Reference
All API routes live under /api and follow REST conventions. Authenticated endpoints require a valid NextAuth session.
Authentication
| Endpoint | Description |
|---|
GET/POST /api/auth/* | NextAuth.js endpoints (Google OAuth). Managed automatically. |
Constitutions
| Method | Endpoint | Auth | Description |
|---|
GET | /api/constitutions | Yes | List all constitutions for the current user. |
POST | /api/constitutions | Yes | Create a new constitution. Body: { title, description? } |
GET | /api/constitutions/[id] | Yes | Get a single constitution with its active clauses. |
Clauses
| Method | Endpoint | Auth | Description |
|---|
POST | /api/clauses | Yes | Create a new clause. Includes duplicate detection (returns 409 on conflict). Body: { constitutionId, type, naturalLanguage, irData, rationale? } |
GET | /api/clauses/[id]/history | Yes | Get the chat session history for a specific clause. |
Chat
| Method | Endpoint | Auth | Description |
|---|
POST | /api/chat | Yes | Send a message to the AI chatbot. Returns a streaming response. Body: { messages, constitutionId, mode } |
Chat Sessions
| Method | Endpoint | Auth | Description |
|---|
POST | /api/chat-sessions | Yes | Create a new chat session. Body: { constitutionId, mode, messages } |
GET | /api/chat-sessions | Yes | List chat sessions (filter by constitutionId query param). |
GET | /api/chat-sessions/[id] | Yes | Get a single chat session with linked clauses. |
PATCH | /api/chat-sessions/[id] | Yes | Update session messages. Body: { messages } |
POST | /api/chat-sessions/[id]/clauses | Yes | Link a clause to a session. Body: { clauseId, relation } |
Deployments
| Method | Endpoint | Auth | Description |
|---|
POST | /api/deployments | Yes | Create deployment. Body: { constitutionId, region?, size? }. On success, returns deployment row in PROVISIONING. |
GET | /api/deployments | Yes | List non-destroyed deployments for a constitution. Query: constitutionId. |
GET | /api/deployments/[id] | Yes | Poll deployment status and progress. Drives state transitions:PROVISIONING -> CONFIGURING -> ACTIVE, or ERROR. |
DELETE | /api/deployments/[id] | Yes | Destroy a deployment and its DigitalOcean Droplet. |
GET | /api/deployments/[id]/launch | Yes | Redirect to Guacamole launch URL with encrypted short-lived token. Optional query: target=ip to force direct IP host. |
GET | /api/deployments/preview | Yes | Optional helper route: generate a DNS blocklist preview using AI. Query: constitutionId. Returns an array of domains with sources and snippets. |
GET /api/deployments/[id] includes a computed progress object while provisioning/configuring: { stage, message, percent, checks? } . Probe checks may include vnc5901, http80, guacHttp8080, guacHttps443.
Launch route errors:
409 when deployment is not ACTIVE.500 when IP/password metadata is unavailable.
Gateway host strategy: docs/ops default is stream.the-next-lab.com, override via NEXT_PUBLIC_STREAM_GATEWAY_HOST. If empty, or when target=ip is requested, launch uses deployment IP.
Groups
| Method | Endpoint | Auth | Description |
|---|
GET | /api/groups | No | List groups ordered by updatedAt desc, including members, member count, and constitution titles. |
POST | /api/groups | Yes | Create a new group. The creator is added as an ADMIN member. |
GET | /api/groups/[id] | No | Fetch one group with members, constitutions, clauses, proposals, votes, and comments. |
POST | /api/groups/[id]/join | Yes | Join a group by submitting the group invite code. |
POST /api/groups
Request body: { name: string, description?: string }
201: Returns the created group with creator membership.400: { error: "Name is required" }401: { error: "Unauthorized" }
GET /api/groups/[id]
Response includes nested data for group deliberation screens:
- Members with user identity fields (
id, name, email). - Constitutions and their clauses ordered by clause
order. - Proposals per clause (with votes, comments, and proposal authors), ordered by
createdAt desc.
404 when the group id does not exist.
POST /api/groups/[id]/join
Request body: { inviteCode: string }
201: Returns the created GroupMember row (default role VOTER).200: { message: "Already a member" } if membership already exists.401: { error: "Unauthorized" }403: { error: "Invalid invite code" }
Export
| Method | Endpoint | Auth | Description |
|---|
GET | /api/export | Yes | Export a constitution. Query params: constitutionId, format (json, yaml, markdown, dns, llm-prompt). |
Other Endpoints
| Method | Endpoint | Description |
|---|
POST | /api/research | Run AI-powered research for a clause. |
POST | /api/proposals | Create an amendment proposal. |
GET/PATCH | /api/proposals/[id] | Fetch one proposal or update proposal state actions. |
POST | /api/proposals/[id]/vote | Cast a vote on a proposal. |
POST | /api/proposals/[id]/comment | Add a comment to a proposal. |
GET/POST | /api/versions | List and create constitution version snapshots. |
GET | /api/templates | List available constitution templates. |
POST | /api/templates/fork | Fork a template into a new constitution. |