Skip to content

System

API Routes

Next.js route handlers under src/app/api.

API Routes

Handlers live in src/app/api/<...>/route.ts. Most JSON responses go through src/lib/* helpers; planner reads/writes use Prisma and @/lib/planner-session rather than ad-hoc fs for session state.

Below is a grouped index. For a full list, search the tree:

find src/app/api -name route.ts (from the veyra app root).

Audio & projects

RouteMethodsPurpose
/api/audio-filesGETList projects (folders under public/projects/ with a mix file).
/api/analyze-audioPOSTSong structure: segments (sections), beat/downbeat hints, no_beat_regions when present. Consumed by the Audio Analysis pane for grouping lyrics.
/api/beat-gridPOSTProxy to beat service beat grid.
/api/audio-stagingGET, POSTRead/write per-project audio staging document.
/api/tap-gridsGET, POSTTap grid calibration.
/api/tap-grids/quantizePOSTQuantize tap input.

Lyrics

RouteMethodsPurpose
/api/lyricsGET, POSTLyrics fetch / job kickoff.
/api/lyrics-stagingGET, POSTStaged / edited lyrics.
/api/lyrics-statusGETPoll long jobs.
/api/lyrics-stemPOSTRe-stem or bypass cache.
/api/lyrics-vs-referencePOSTAlign pasted reference lyrics with persisted transcript segments for the planner compare UI (DP pairing; body: reference text + segments).

Planner (Video Plan)

All under /api/planner/…session, inputs, and one route per major step. Examples:

RouteMethodsPurpose
/api/planner/sessionGET, POST, …Load or persist the planner session.
/api/planner/inputsStep: inputs / upload.
/api/planner/song-readSong read / early narrative.
/api/planner/conceptConcept step.
/api/planner/actsActs.
/api/planner/locationsLocations.
/api/planner/audio-analysisHook analysis into the session.
/api/planner/environment-promptEnvironment prompt.
/api/planner/environment-chatEnvironment chat.
/api/planner/filming-styleGlobal filming style.
/api/planner/promptsPer-shot prompts.
/api/planner/scaffoldShot scaffold.
/api/planner/generate-notesProject-wide generate notes.
/api/planner/generate-chatRender-help chat on the Generate step.

(Exact method lists live next to each route.ts.)

Generation & assets

RouteMethodsPurpose
/api/generate-imagePOSTStills (Gemini / catalog in src/config/gemini-image-models.ts).
/api/generate-videoPOSTVideo (Veo / fal, etc. — src/config/video-models.ts).
/api/shot-assetsGETList generated assets for a shot.
/api/shot-assets/streamGETStream asset bytes where applicable.
/api/lip-sync-videoPOSTLip-sync post-process.
/api/render-timelinePOSTComposites shots + mix to exports/*.mp4. Body: mixSrc, includeStills?, burnSubtitles?, exportSubtitlesZip?. When burning lyrics, prefers ASS (writeAssKaraokeFromLyrics, same per-word windowing as the client) via subtitles=filename=…; fallbacks: precomposed RGBA line overlay, SRT+force_style, or mov_text soft-mux. With exportSubtitlesZip, a sidecar .en.srt is written when a transcript exists and the streamed done URL points at a *.zip (MP4 + .en.srt inside). See src/app/api/render-timeline/route.ts file header.
/api/project-image-indexProject image library index.
/api/project-still-lockPOSTPromote a still to generated/<shot>.jpg. Gallery strip sends imageBase64 (thumbnail pixels). See Gallery hero strip.
/api/refs/resolveResolve ref URLs.

Dashboard

RouteMethodsPurpose
/api/dashboardGETDashboard payload; ?refresh=1 bypasses in-memory cache.
/api/dashboard/invalidatePOSTClear dashboard cache.

Conventions

  • Handlers return JSON; Gemini errors are normalised in src/lib/gemini-api-error.ts where used.
  • Long work (lyrics, transcoding) uses async jobs and poll endpoints.
  • dynamic = "force-dynamic" / revalidate = 0 are common on routes that must reflect DB and disk on every request.