Skip to content

Worker API & Clerk Auth

The HTTP API is a Cloudflare Worker built with Hono and @hono/zod-openapi, assembled by createApp() in src/api/index.ts and mounted under /api.

createApp() returns an OpenAPIHono instance with .basePath('/api'). A defaultHook turns Zod validation failures into a uniform RFC 9457 422 validation_error (ADR-002) rather than Hono’s default 400. Routes are registered per feature by register*Routes(app) functions (registerListsRoutes, registerGroupsRoutes, registerTasksRoutes, registerStepsRoutes, registerMyDayRoutes, registerListMembersRoutes, registerSyncRoutes, registerMeRoute) and are versioned under /v1 (ADR-001).

  • secureHeaders — applied to every response with an enforcing default-src 'none' CSP (API responses are JSON/problem+json with no subresources). The WebSocket upgrade (GET with Upgrade: websocket) is exempted, because its immutable 101 response cannot carry headers (src/api/index.ts).
  • originCheck — cross-origin guard (src/api/middleware/origin-check.ts).
  • error middlewareonError + problem() produce the RFC 9457 envelope (src/api/middleware/error.ts, ADR-002).
  • Clerk — authentication is the single boundary (constitution §7.12); the user identity is derived from the verified session, never from client input. Auth UI uses Clerk prebuilt components (ADR-010).

Routes are declared with createRoute({ ... }) and Zod schemas, so the OpenAPI document is generated from the code (ADR-003) — it is the single source of truth shared by all clients and is rendered as this site’s API Reference. scripts/build-openapi.mjs emits it to openapi.json at build time.

Related: DB Schema & Notify-Affected (what the routes write and who they notify), SyncInbox Durable Object (the upgrade route’s target).