/api/handoff (app + AI + admin)
The session-authenticated CRUD, AI, and admin surface under /api/handoff, plus a couple of public component routes outside it.
Everything in this cluster requires a NextAuth session cookie unless noted; this is the surface
the registry's own UI is built on, not something a workspace's CLI calls directly (that's
/api/registry and /api/sync).
Content CRUD
| Resource | Endpoints | Notes |
|---|---|---|
| Pages | GET/POST/DELETE /api/handoff/pages | GET with ?slug= returns one full page; without it, all page summaries. POST upserts by slug and fires an async nav-sync. |
| Patterns | GET /api/handoff/patterns (+ /{id}, /{id}/clone) | q/group/source query filters on list. |
| Assets | GET/POST /api/handoff/assets (+ /{id}, /{id}/raw, /presign, /confirm, /collections, /usages) | presign/confirm are the two-step upload flow for new media. |
| Components | GET/PATCH /api/handoff/components, POST /api/handoff/components/build | PATCH (admin only) updates metadata; build enqueues a preview build. |
| Component validation | GET /api/handoff/components/validation | Latest validator snapshot for a component id. Returns an empty array when no database is configured (the route's residual isPostgres() check, SQLite itself was removed, see docs/SQLITE-REMOVAL-ADR.md). |
| Component history | GET /api/handoff/components/history | Push/version history, limit capped at 200. |
| Changelog | GET /api/handoff/changelog | Unified time-ordered feed across components/tokens/pages. since (ISO 8601) + limit. Postgres only. |
AI
| Endpoint | Notes |
|---|---|
POST /api/handoff/ai/chat | Streaming (SSE) chat with the design-system assistant; tool calls like show_components, navigate_component, get_recent_changes, check_validation. Accepts an optional pageContext to scope tools to a component/pattern. |
POST/GET /api/handoff/ai/generate-component | Enqueues (and polls) an AI component-generation job from a design artifact. |
Several more ai/* routes exist in code beyond what's in openapi.yaml today (design-artifact
extraction/CRUD, generate-design, generate-pattern, foundation-preview, layout-guide analysis):
internal/evolving surfaces, not detailed here; the ones above are the spec'd, stable pair.
Figma
| Endpoint | Notes |
|---|---|
POST/GET /api/handoff/figma/fetch | Enqueues a Figma fetch job (rate-limited: 3/min, max 2 concurrent); GET ?jobId= polls status, omit for connection info. The server-side counterpart to a workspace's own handoff-app fetch. |
GET /api/handoff/figma/components | Figma component audit results — the registry-side counterpart to handoff-app audit:figma-components. |
Admin
| Endpoint | Notes |
|---|---|
GET /api/handoff/admin/users | List users. |
POST /api/handoff/admin/invite | Invite a user (admin/member role). |
POST /api/handoff/admin/role | Update a user's role. |
POST /api/handoff/admin/remove | Remove a user. |
GET /api/handoff/admin/build-tasks | The merged component-build + design-asset-extraction job queue. |
GET/POST /api/handoff/admin/reference-materials | Read, or regenerate, AI reference materials (design guidelines / brand voice). Session + admin role only, no bearer path. |
All admin routes are documented as internal/subject-to-change pre-2.0. See
Registry → Auth for who holds the admin role.
Reference materials (bearer, not session)
GET /api/handoff/reference-materials is the bearer-authenticated read of the same data:
verifyHandoffApiAuth() with the reference:read scope (or the legacy sync secret), for MCP
clients and integrations rather than the admin UI. ?id= returns one material's full content;
without it, the id/size/generated-at summary list. Read-only, regeneration stays on the admin
route above. See Auth & scopes.
Account
PUT /api/account, update the signed-in user's own profile (name, image).
Public component routes
Two routes outside /api/handoff/* need no auth at all:
GET /api/components: a flat list of every component summary in the registry.GET /api/component/{path}: serves a single built component artifact (HTML preview, CSS, JS, JSON metadata, screenshot) by its path within the component bundle. Resolves from the database in registry mode, from disk in workspace mode.