Documentation
API Reference
Overview

API Overview

Conventions

  • All request and response bodies use JSON (unless streaming).
  • Board-scoped endpoints include boardId in the path: /api/boards/{boardId}/....
  • AI endpoints that produce streamed content use Server-Sent Events via the Vercel AI SDK toUIMessageStreamResponse() or plain text streams.
  • All timestamps are ISO 8601 strings.

Authentication

Most endpoints require a valid session cookie (session HttpOnly cookie set after OTP login).

Exceptions (no auth required):

EndpointReason
POST /api/auth/send-otpInitiates the login flow
POST /api/auth/verify-otpCompletes login
POST /api/billing/webhookStripe uses its own signature verification

Board access

Board-scoped endpoints validate both the session and the user's board access level using a centralised boardGuard() middleware. A valid session is not sufficient — the user must also be the owner or an invited collaborator.

Error codes

CodeMeaningCommon cause
400Bad requestInvalid or missing payload field; Zod validation failure
401UnauthorisedMissing or expired session cookie
403ForbiddenValid session but no board access
429Too many requestsAI rate limit or monthly quota exceeded
500Server errorUnexpected runtime error
503Service unavailableCloudflare context unavailable (production config issue)

Request patterns

Authenticated board request

GET /api/boards/{boardId}/sync?since=42
Cookie: session=<token>

AI streaming request

POST /api/canvas/chat
Cookie: session=<token>
Content-Type: application/json

{
  "boardId": "abc123",
  "messages": [...],
  "boardState": { ... }
}

Response: SSE stream (text/event-stream).

Quota-limited AI request

When a quota is exceeded, the response is:

HTTP 429
{ "error": "AI quota exceeded", "used": 20, "limit": 20, "plan": "free" }

See also