Nova Studio

API

The HTTP endpoints this application exposes. Everything listed here exists in the running app; nothing is planned or illustrative.

Authentication

Canvas and community endpoints authenticate with the session cookie set at sign-in, so a request from the app carries credentials automatically.

Billing endpoints authenticate with a bearer token instead — the Supabase access token from the browser session — because they are also reachable from server-side integrations.

Guest sessions are accepted only where a run costs nothing. Publishing, liking, sharing and live generation all require an account.

Generation

A run is synchronous: the request stays open until the provider finishes or the deadline passes. Video allows a longer deadline than image.

Aborting the request cancels the run.

GET /api/canvas/generate
What this session can run: provider id, node kinds, and the available models with their capabilities.
POST /api/canvas/generate
Runs one node. Enforces authorization and spend limits, then re-hosts the result and returns an asset reference.
GET /api/canvas/usage
Runs used today, the daily limit, in-flight count, and when the window resets.
POST /api/canvas/generate
{
  "nodeId": "n1",
  "kind": "image",
  "prompt": "a lighthouse in fog",
  "settings": { "model": "auto", "modelId": "", "aspectRatio": "16:9" },
  "inputs": []
}

200 OK
{
  "ok": true,
  "asset": {
    "kind": "image",
    "url": "/api/canvas/assets/<owner>/2026/08/<uuid>.png",
    "sample": false,
    "label": "fal-ai/flux/dev"
  }
}

Assets

Stored assets are served from a private bucket. The redirect means video range requests go straight to storage, so seeking works and large files do not stream through the application server.

GET /api/canvas/assets
Lists the generations this account owns, newest first.
GET /api/canvas/assets/{key}
Redirects to a short-lived signed URL after checking the key belongs to the caller.

Community

Counters are maintained by database triggers over the like and use tables, and are not writable by any client — including the work’s owner.

GET /api/community/works
The feed. Accepts category, sort, q and mine.
POST /api/community/works
Publishes one stored generation. Rejects media the caller does not own.
DELETE /api/community/works/{id}
Unpublishes. Restricted to the owner by row level security.
POST · DELETE /api/community/works/{id}/like
Likes or unlikes; returns the count read back after the write.
POST /api/community/works/{id}/use
Records a use and returns the prompt and model so the caller can build on it.

Projects and sharing

Invitations are keyed by email address and are never confirmed or denied against the user table, so the endpoint cannot be used to discover which addresses are registered.

GET · POST /api/canvas/projects
Lists and creates cloud projects.
GET · PATCH /api/canvas/projects/{id}
Reads and updates one project and its workflow document.
GET · POST · DELETE /api/canvas/projects/{id}/members
Members and pending invitations.
POST /api/canvas/invitations
Claims any invitations addressed to the signed-in account.

Deployment configuration

Generation is off until a provider key is present. Setting one is what turns it on; NOVA_LIVE_GENERATION_ENABLED=false is the kill switch that overrides it without removing the key.

Model identifiers are overridable per kind and tier, because hosted models are renamed and retired on the provider’s schedule.

FAL_KEY=...                     # or REPLICATE_API_TOKEN
NOVA_GENERATION_PROVIDER=       # pin one when several keys are set
NOVA_LIVE_GENERATION_ENABLED=true

NOVA_MAX_CONCURRENT_RUNS=3
NOVA_MAX_RUNS_PER_MINUTE=10
NOVA_MAX_RUNS_PER_DAY=50

# NOVA_<PROVIDER>_MODEL_<KIND>_<ROUTE>
NOVA_FAL_MODEL_VIDEO_QUALITY=fal-ai/kling-video/v1.6/pro/text-to-video