API Reference

DevFrame's API surface is small on purpose.

Most product work flows through server components, services, and one save action. API routes exist where JSON or direct upload handshakes are the right boundary.

DevFrame system map

The same App Router shell powers marketing, Studio, Builder, Dashboard, and public portfolio routes.

Templates

GET

/api/templates

Public data

GET

/api/portfolios/[slug]

Uploads

POST

/api/portfolio-uploads

Publishing

Action

savePortfolioAction

GET

/api/templates

Returns the current template catalog used by the template gallery and editing surfaces.

Backed by `getTemplates()` in the template service.
Catalog entries map to Nova, Vertex, and Drift metadata.
The renderer still resolves templates through the registry, not through API conditionals.
GET /api/templates

GET

/api/portfolios/[slug]

Fetches a public portfolio by slug for integrations or client-side previews that need JSON.

Uses `getPublicPortfolioBySlug()` and only returns published Supabase rows for public reads.
Preview cookies receive private no-store cache headers.
Published public responses receive short shared cache headers with stale-while-revalidate.
GET /api/portfolios/regie
Allow: GET, HEAD, OPTIONS

POST

/api/portfolio-uploads

Creates a signed Supabase Storage upload target for profile and gallery images.

Requires an authenticated non-demo viewer.
Validates file type and size before creating the signed upload URL.
The client uploads directly to Supabase Storage; save actions receive only URLs and storage paths.
POST /api/portfolio-uploads
{ fileName, fileSize, fileType, kind, slug }

Server Action

savePortfolioAction

Persists Studio and Builder submissions through the shared portfolio service.

Parses `PortfolioFormValues` with Zod before persistence.
Uses rate limiting and server-side viewer checks.
Writes to the existing owner portfolio record when Supabase is configured, otherwise stores a preview draft cookie.
savePortfolioAction(previousState, formData)

Service

Portfolio loading

Studio, Builder, Dashboard, public pages, and API routes should reuse the portfolio service instead of creating new data paths.

Owner reads use the current primary portfolio row.
Public reads validate slugs and require published rows before falling back to preview or seed data.
Hydration preserves template settings, sections, profile image, gallery assets, projects, and experience.
getPortfolioByOwner(ownerId)
getPublicPortfolioBySlug(slug)
savePortfolioDraft(values, ownerId, options)

Guardrails

Request and persistence boundaries

Mutation paths stay small and server-safe while public reads remain cacheable.

Large image blobs should never be posted through Server Actions.
Upload routes must stay allowed by the request guard to avoid method errors.
Template switches update `template_slug` and `template_settings` on the same portfolio record.