Skip to content

Templates API

Templates are project-level reusable overlay compositions used by the editor. A template can contain:

  • Text overlays (titles, CTAs, lower-thirds)
  • Image overlays (logos, watermarks, badges) referencing project assets
  • Optional default transition and export settings (width, height, fps)

Templates live under a project and can be applied to any work (video pipeline) in that project.

MethodEndpointAuthScopeDescription
GET/api/projects/:projectId/templatesYesprojects:readList templates (meta only).
POST/api/projects/:projectId/templatesYesprojects:writeCreate a new template.
GET/api/projects/:projectId/templates/:templateIdYesprojects:readGet full template with content.
PUT/api/projects/:projectId/templates/:templateIdYesprojects:writeUpdate template (name, tags, content).
DELETE/api/projects/:projectId/templates/:templateIdYesprojects:writeDelete template.
POST/api/projects/:projectId/templates/:templateId/applyYesprojects:readApply template and get overlay data (does not save work).
POST/api/projects/:projectId/works/:workId/apply-templateYesworks:writeApply template to a work and persist editor state.

All endpoints require authentication. Scopes are enforced via API tokens or user JWT.

Template meta (list item) — returned by GET /api/projects/:projectId/templates:

FieldTypeDescription
idstringTemplate ID.
namestringTemplate name shown in the UI.
descriptionstring?Optional human-readable description.
thumbnailstring?Optional URL to a preview thumbnail.
createdAtnumberUnix timestamp (ms).
updatedAtnumberUnix timestamp (ms).
tagsstring[]?Optional tags for filtering/search.
textOverlayCountnumberNumber of text overlays in the template.
imageOverlayCountnumberNumber of image overlays in the template.
hasExportSettingsbooleanWhether export settings are included.

Full template — returned by GET /api/projects/:projectId/templates/:templateId and POST /api/projects/:projectId/templates:

FieldTypeDescription
idstringTemplate ID.
projectIdstringOwning project ID.
namestringTemplate name.
descriptionstring?Optional description.
thumbnailstring?Optional thumbnail URL/path.
contentobjectTemplate content (text/image overlays, default transition, exportSettings).
tagsstring[]?Optional tags.
createdAtnumberUnix timestamp (ms).
updatedAtnumberUnix timestamp (ms).

Template content (content field):

FieldTypeDescription
textOverlaysTemplateTextOverlay[]Text overlays with timing.
imageOverlaysTemplateImageOverlay[]Image overlays using project assets.
defaultTransitionobject?Optional { type, duration } applied when no per-clip transition is set.
exportSettingsobject?Optional { width, height, fps } export defaults.

Each TemplateTextOverlay:

FieldTypeDescription
idstringOverlay ID inside the template.
textstringText content (supports placeholders like {{product_name}}).
fontSizenumberFont size in pixels.
fontColorstringCSS color (e.g. #FFFFFF).
centerXnumberX position (center-relative) in pixels.
centerYnumberY position (center-relative) in pixels.
timingModestring"relative" or "absolute".
startPercentnumber?Relative start time (0–100) when timingMode = "relative".
endPercentnumber?Relative end time (0–100) when timingMode = "relative".
startSecondsnumber?Absolute start time in seconds when timingMode = "absolute".
endSecondsnumber?Absolute end time in seconds when timingMode = "absolute".

Each TemplateImageOverlay:

FieldTypeDescription
idstringOverlay ID inside the template.
assetIdstringProject asset ID (see Assets).
widthnumberWidth in pixels.
heightnumberHeight in pixels.
centerXnumberX position (center-relative).
centerYnumberY position (center-relative).
opacitynumberOpacity (0–1).
rotationnumberRotation in degrees.
maintainAspectRatiobooleanKeep original aspect ratio.
timingModestring"relative" or "absolute".
startPercentnumber?Relative start time (0–100).
endPercentnumber?Relative end time (0–100).
startSecondsnumber?Absolute start time in seconds.
endSecondsnumber?Absolute end time in seconds.

List templates (GET /api/projects/:projectId/templates)

Section titled “List templates (GET /api/projects/:projectId/templates)”

List project-level templates (meta only).

Response:

{
"templates": [
{
"id": "tmpl_123",
"name": "Brand Intro",
"description": "Logo + headline intro overlay",
"thumbnail": "/api/projects/proj_123/templates/tmpl_123/thumbnail",
"createdAt": 1700000000000,
"updatedAt": 1700000001000,
"tags": ["intro", "brand"],
"textOverlayCount": 1,
"imageOverlayCount": 1,
"hasExportSettings": true
}
],
"count": 1
}

Use this endpoint to power the Templates panel in the editor.

Create template (POST /api/projects/:projectId/templates)

Section titled “Create template (POST /api/projects/:projectId/templates)”

Save the current overlay layout as a reusable template.

Request body:

{
"name": "Brand Intro",
"description": "Logo on top, CTA text in the middle",
"tags": ["intro", "brand"],
"content": {
"textOverlays": [
{
"id": "title-1",
"text": "{{product_name}} in 30 seconds",
"fontSize": 42,
"fontColor": "#FFFFFF",
"centerX": 540,
"centerY": 300,
"timingMode": "relative",
"startPercent": 10,
"endPercent": 40
}
],
"imageOverlays": [
{
"id": "logo-1",
"assetId": "asset_logo",
"width": 160,
"height": 160,
"centerX": 180,
"centerY": 220,
"opacity": 0.9,
"rotation": 0,
"maintainAspectRatio": true,
"timingMode": "relative",
"startPercent": 0,
"endPercent": 100
}
],
"defaultTransition": {
"type": "fade",
"duration": 0.5
},
"exportSettings": {
"width": 1080,
"height": 1920,
"fps": 30
}
}
}

Response: Full EditorTemplate object including id, projectId, timestamps, and content.

  • GET /api/projects/:projectId/templates/:templateId — fetch full template with content.
  • PUT /api/projects/:projectId/templates/:templateId — update name, description, tags, or full content.
  • DELETE /api/projects/:projectId/templates/:templateId — remove the template.

All three require the project owner and the correct scopes.

POST /api/projects/:projectId/templates/:templateId/apply

Use this when you want to preview or merge a template into the current editor state without automatically saving the work. The backend:

  1. Loads the template.
  2. Uses videoDuration (seconds) to resolve relative timing.
  3. Applies placeholder values (e.g. {{product_name}}) from placeholderValues.
  4. Returns text/image overlays and track actions you can merge into the editor state.

Request body:

{
"videoDuration": 30,
"placeholderValues": {
"product_name": "EcoBottle",
"brand": "Acme Co."
}
}

Response:

{
"textOverlays": {
"title-1": {
"text": "EcoBottle in 30 seconds",
"fontSize": 42,
"fontColor": "#FFFFFF",
"centerX": 540,
"centerY": 300
}
},
"textTrackActions": [
{ "id": "title-1", "start": 3, "end": 12 }
],
"imageOverlays": {
"logo-1": {
"assetId": "asset_logo",
"width": 160,
"height": 160,
"centerX": 180,
"centerY": 220,
"opacity": 0.9,
"rotation": 0,
"maintainAspectRatio": true
}
},
"imageTrackActions": [
{ "id": "logo-1", "start": 0, "end": 30 }
],
"exportSettings": {
"width": 1080,
"height": 1920,
"fps": 30
},
"missingAssetIds": []
}

The client is responsible for:

  • Merging overlays and track actions into the current work’s editorState.
  • Persisting changes by calling PUT /api/projects/:projectId/works/:workId.

POST /api/projects/:projectId/works/:workId/apply-template

Use this to apply a template and save the updated editor state in one call. The backend:

  1. Loads the project, work, and template.
  2. Computes video duration from work.videoDuration or sum(work.scenes[].duration_seconds).
  3. Applies the template (overlays + track actions) and merges into work.editorState.
  4. Persists the work and returns the full Work object (WorkResponse).

Request body:

{
"templateId": "tmpl_123",
"placeholderValues": {
"product_name": "EcoBottle",
"brand": "Acme Co."
}
}

Response: Full Work with updated editorState (including new imageTrack / textTrack actions and overlays).

Templates can contain placeholders such as {{product_name}}, {{brand}}, or any custom key. When applying:

  • placeholderValues is a map of key -> value.
  • All occurrences of {{key}} in text overlays are replaced with the provided value.

If a placeholder is not provided, it remains as-is in the overlay text.