# Video Configs API Base path: `/api/v1/video-configs` All endpoints require `Authorization: Bearer `. Related: [[02 - Videos API]], [[07 - Render Engine]], [[04 - Templates API]] --- ## GET /video-configs/:videoId Returns the current `VideoConfig` for a video. **Response:** ```json { "id": "cuid", "videoId": "cuid", "templateId": "cuid or null", "blockOrder": ["blockId1", "freetext:abc123"], "blockOverrides": { "blockId1": { "content": "override text", "active": true, "compact": false } }, "variableValues": { "sponsor_name": "Acme Corp" }, "version": 3, "renderHash": "sha256hex or null", "renderedAt": "ISO datetime or null", "createdAt": "ISO datetime", "updatedAt": "ISO datetime" } ``` Returns `null` if the video has no config yet. --- ## PUT /video-configs/:videoId Save (create or update) the description config for a video. Requires `EDITOR` role. This is the endpoint the video editor calls when the user saves their block configuration. **Request body:** ```json { "blockOrder": ["blockId1", "freetext:abc123"], "blockOverrides": { "blockId1": { "content": "override text", "active": true, "compact": false }, "freetext:abc123": { "content": "free text content", "compact": false } }, "variableValues": { "sponsor_name": "Acme Corp" }, "templateId": "cuid", "collaboratorIds": ["collabId1"], "autoRender": true } ``` | Field | Required | Notes | |---|---|---| | `blockOrder` | Yes | Ordered array of block IDs. May include `freetext:` entries — these have no DB block; content comes from `blockOverrides`. | | `blockOverrides` | Yes | Per-block overrides for content, active state, and compact flag. | | `variableValues` | Yes | Video-level custom variable values. Override team variables on name collision. | | `templateId` | No | Associates the config with a template. Does not re-apply template defaults — it is a reference only. | | `collaboratorIds` | No | Updates `Video.collaboratorIds` on the video row. Controls which collaborators are resolved during description rendering. | | `autoRender` | No | If `true`, enqueues a background render job after saving. Updates `Video.renderedDescription` asynchronously. | **Response:** The saved `VideoConfig` row (same shape as GET response above). **Notes:** - `version` is auto-incremented on every save. - `collaboratorIds` in the request body updates `Video.collaboratorIds` — this is handled separately from the `VideoConfig` fields. The VideoConfig row itself does not store collaborator IDs. - If `autoRender` is omitted or `false`, the description is not re-rendered immediately. The rendered description updates only when a sync job runs or the render queue processes a background render. --- ## POST /video-configs/:videoId/render-preview Render the description using the provided config, without saving anything. Used by the video editor's live preview panel. **Request body:** Same shape as `PUT /video-configs/:videoId`. **Response:** ```json { "rendered": "Full rendered description string", "hash": "sha256hex" } ``` **Notes:** - Nothing is persisted. The video's `renderedDescription`, `lastSyncedHash`, and `VideoConfig` row are all unchanged. - The preview renders against live data: the video's current metadata, active campaigns, and team variables at the time of the call. - `collaboratorIds` in the request body is used for the preview render directly — it does not need to match the currently saved `Video.collaboratorIds`. This allows the editor to preview with a collaborator selection before saving. - Active campaign blocks are appended automatically if their date window is currently active.