> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.videogen.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.videogen.io/_mcp/server.

## v2.0.5 — Timed-word transcripts, script-to-video scene ranges, and assistant API refinements

This release reshapes transcripts around timed words, exposes both the structured transcript and its plain text on file reads, adds caller-provided scene ranges to script-to-video, marks the upload transcript and voiceover scene-range fields as stable, and refines the Assistant API.

### Added

- **`transcriptText` on file reads:** `GET /v1/files/{fileId}` now returns a plain `transcriptText` string alongside the structured `transcript` object, for audio and video files that have a transcript. It is the flattened spoken text (no timing) and is `null` for images or when no transcript has been generated. Use `transcriptText` when you only need the words and `transcript` when you need per-word timing.
- **Scene ranges on script-to-video:** `POST /v1/workflows/script-to-video` accepts optional `scenes` (`SceneDescriptionRange[]`: `startSeconds`, `endSeconds`, `description`) to direct what appears on screen over absolute time ranges, matching the existing field on voiceover-to-video. Passed ranges override the automatic scene split only where they are defined; the workflow fills the gaps and keeps section boundaries off your range edges. Ranges must be sorted by `startSeconds` and non-overlapping, and timings may extend past the finished video (they are cropped). Omit to let the workflow choose visuals automatically.

### Changed

- **Breaking: transcripts are now timed `words` instead of `segments`.** The `Transcript` type used by the optional `transcript` on `POST /v1/files/upload` now carries `words` (`{ startSeconds, endSeconds, word }`) instead of `segments` (`{ startSeconds, endSeconds, text }`), with an optional `languageCode`. Each entry is a single spoken word, so caption timing is pinned at word granularity. Words must be sorted by `startSeconds` and non-overlapping. Update any upload requests that previously sent `segments`.
- **Breaking: `GET /v1/files/{fileId}` returns a structured `transcript`.** The `transcript` field is now a `Transcript` object (timed `words` plus optional `languageCode`) rather than a plain string. The previous plain-string value now lives on the new `transcriptText` field. `transcript` is `null` for images or when no transcript has been generated.
- **Pre-computed transcript on upload is stable.** The optional `transcript` field on `POST /v1/files/upload` is supported for production use. Provide it for an audio or video upload to skip re-transcription so caption timing matches your transcript exactly.
- **Voiceover scene ranges are stable.** The optional `scenes` field on `POST /v1/workflows/voiceover-to-video` is supported for production use. Ranges must be sorted by `startSeconds` and non-overlapping; omit to let the workflow choose visuals automatically.
- **Assistant message polling endpoint renamed:** `GET /v1/assistant/messages/{messageId}` is now `GET /v1/assistant-messages/{messageId}`, consistent with the other `/v1/assistants` routes. Update any hard-coded polling URLs; the SDKs, CLI, and `assistant_message.*` webhook subscribers are unaffected.
- **Nullable `assistantId` on projects:** `ProjectResponse.assistantId` is now nullable. New API projects include an assistant chat, so `assistantId` is set; older projects without one return `null`.
- **`generation` and `error` on assistant messages:** polled and webhook payloads now reliably include `generation` (the workflow run a turn kicked off) and `error` (on `failed` / `cancelled` turns).