Skip to main content

Validate render request

POST /api/render/validate/api-key

Free preflight through the same resolution and plan-aware validation pipeline as render submission. Returns the resolved payload, estimated credits and layout warnings. No job is queued and no credits are reserved. A passing result does not guarantee a remote asset will remain accessible.

Authentication​

x-api-key: YOUR_API_KEY (header). API key for authentication. Create one in your dashboard.

Create API keys at app.zvid.io/api-keys. Keep credentials on your server.

Parameters​

This operation has no path, query, or additional header parameters.

Request​

The shell examples read credentials from ZVID_API_KEY (or ZVID_ACCESS_TOKEN for Bearer authentication). Set that variable in your environment. Replace sample project, template, job, and asset identifiers with values from your own account.

A request body is required.

application/json​

Provide either payload (a full project) or template (a stored template id) — not both.

Unknown properties are rejected. Exactly one of the listed alternatives must match.

FieldTypeRequiredDescription and constraints
body.payloadRenderPayloadNo
body.templatestringNoStored template id (tpl_…). Mutually exclusive with payload. Pattern: ^tpl_[A-Za-z0-9]{20}$.
body.variablesobjectNoRequest-time values override project defaults for BOTH inline payloads and stored templates.
body.overridesRenderOverridesNo
body.webhookUrlstringNoOne-off unsigned POST for this job on completion or failure. Use a registered webhook for HMAC signatures. The hosted API requires a public HTTPS address; private destinations are rejected. Maximum length: 2048. Format: uri.
body.jobIdstringNoOptional caller-supplied UUID. This is not a documented idempotency guarantee: do not blindly resubmit after a timeout; first check this job ID. Format: uuid.

oneOf alternative 1

Required properties: payload.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"template"
]
}
}

oneOf alternative 2

Required properties: template.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"payload"
]
}
}

Request example: video​

curl --request POST 'https://api.zvid.io/api/render/validate/api-key' \
--header "x-api-key: $ZVID_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"payload": {
"name": "Hello Zvid",
"width": 1280,
"height": 720,
"duration": 5,
"visuals": [
{
"type": "TEXT",
"text": "Hello, Zvid!",
"position": "center-center",
"style": {
"fontSize": 64,
"color": "#ffffff"
}
}
],
"backgroundColor": "#14213d"
}
}'

Request example: image​

curl --request POST 'https://api.zvid.io/api/render/validate/api-key' \
--header "x-api-key: $ZVID_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"payload": {
"type": "image",
"name": "Hello image",
"width": 1200,
"height": 630,
"outputFormat": "png",
"backgroundColor": "#14213d",
"visuals": [
{
"type": "TEXT",
"text": "Hello, Zvid!",
"position": "center-center",
"style": {
"fontSize": 64,
"color": "#ffffff"
}
}
]
}
}'

Request example: template​

curl --request POST 'https://api.zvid.io/api/render/validate/api-key' \
--header "x-api-key: $ZVID_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"template": "tpl_abcdefghijklmnopqrst",
"variables": {
"title": "Summer sale"
}
}'

Responses​

HTTP 200​

Successful response

Content type: application/json.

Required properties: valid, creditsRequired, payload, warnings, schemaVersion.

FieldTypeRequiredDescription and constraints
response.validtrueYes
response.messagestringNo
response.creditsRequiredintegerYes
response.payloadResolvedRenderPayloadYes
response.warningsarray of objectYes
response.schemaVersionstringYes

Nested field: response.warnings

Array item: response.warnings[]

Type: object.

Representative successful response response

{
"valid": true,
"message": "Payload is valid and would be accepted for rendering",
"creditsRequired": 5,
"payload": {
"duration": 5,
"width": 1280,
"height": 720
},
"warnings": [],
"schemaVersion": "1.0.0"
}

HTTP 400​

Invalid input or semantic validation error

Content type: application/json.

Required properties: error.

FieldTypeRequiredDescription and constraints
response.errorstringYes
response.messagestringNo
response.detailsarray of objectNo
response.planLimitsobjectNoPresent on render validation errors; contains the authenticated user's current render limits.

Nested field: response.details

Array item: response.details[]

Unknown properties are rejected. Required properties: field, message.

FieldTypeRequiredDescription and constraints
response.details[].fieldstringYes
response.details[].messagestringYes

HTTP 401​

Missing or invalid credentials

Content type: application/json.

Unknown properties are rejected. Required properties: error.

FieldTypeRequiredDescription and constraints
response.errorstringYesError type
response.messagestringNoHuman-readable error message

HTTP 404​

Not found for this account

Content type: application/json.

Required properties: error.

FieldTypeRequiredDescription and constraints
response.errorstringYesError type
response.messagestringNoHuman-readable error message

HTTP 500​

Server error

Content type: application/json.

Required properties: error.

FieldTypeRequiredDescription and constraints
response.errorstringYesError type
response.messagestringNoHuman-readable error message

Schema definitions​

The following definitions describe the fields referenced above. Expand a definition to inspect its complete contract.

RenderJobRequest

Provide either payload (a full project) or template (a stored template id) — not both.

Unknown properties are rejected. Exactly one of the listed alternatives must match.

FieldTypeRequiredDescription and constraints
RenderJobRequest.payloadRenderPayloadNo
RenderJobRequest.templatestringNoStored template id (tpl_…). Mutually exclusive with payload. Pattern: ^tpl_[A-Za-z0-9]{20}$.
RenderJobRequest.variablesobjectNoRequest-time values override project defaults for BOTH inline payloads and stored templates.
RenderJobRequest.overridesRenderOverridesNo
RenderJobRequest.webhookUrlstringNoOne-off unsigned POST for this job on completion or failure. Use a registered webhook for HMAC signatures. The hosted API requires a public HTTPS address; private destinations are rejected. Maximum length: 2048. Format: uri.
RenderJobRequest.jobIdstringNoOptional caller-supplied UUID. This is not a documented idempotency guarantee: do not blindly resubmit after a timeout; first check this job ID. Format: uuid.

oneOf alternative 1

Required properties: payload.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"template"
]
}
}

oneOf alternative 2

Required properties: template.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"payload"
]
}
}
RenderPayload

The payload accepted by render requests and stored templates, before variable substitution, conditions and scene iteration. Whole placeholders preserve the variable's type. Run authenticated validation to resolve values, enforce semantic rules and apply your account limits. Stored video templates require explicit positive scene durations.

Unknown properties are rejected. All listed constraints apply.

FieldTypeRequiredDescription and constraints
RenderPayload.type"video" / "image"NoRender type. "image" produces a still (png/jpg/webp) and forbids all time-domain fields. Default: "video".
RenderPayload.namestring OR stringNoAt least one listed alternative must match.
RenderPayload.resolution"sd" / "hd" / "full-hd" / "squared" / "youtube-short" / "youtube-video" / "tiktok" / "instagram-reel" / "instagram-post" / "instagram-story" / "instagram-feed" / "twitter-landscape" / "twitter-portrait" / "twitter-square" / "facebook-video" / "facebook-story" / "facebook-post" / "snapchat" / "custom" OR stringNoAt least one listed alternative must match.
RenderPayload.widthinteger OR stringNoAt least one listed alternative must match.
RenderPayload.heightinteger OR stringNoAt least one listed alternative must match.
RenderPayload.durationnumber OR stringNoAt least one listed alternative must match.
RenderPayload.durationMode"auto" / "fixed" OR stringNoAt least one listed alternative must match.
RenderPayload.frameRateinteger OR stringNoAt least one listed alternative must match.
RenderPayload.outputFormat"mp4" / "mov" / "avi" / "webm" / "png" / "jpg" / "jpeg" / "webp" OR stringNoAt least one listed alternative must match.
RenderPayload.backgroundColorstring OR stringNoAt least one listed alternative must match.
RenderPayload.snapshotTimenumber OR stringNoAt least one listed alternative must match.
RenderPayload.qualityinteger OR stringNoAt least one listed alternative must match.
RenderPayload.transparentboolean OR stringNoAt least one listed alternative must match.
RenderPayload.visualsarray of Visual OR stringNoAt least one listed alternative must match.
RenderPayload.audiosarray of AudioItem OR stringNoAt least one listed alternative must match.
RenderPayload.scenesarray of Scene OR stringNoAt least one listed alternative must match.
RenderPayload.thumbnailstring OR stringNoAt least one listed alternative must match.
RenderPayload.subtitleSubtitle OR stringNoAt least one listed alternative must match.
RenderPayload.variablesobjectNoDefault variable values; request variables override these. Scene defaults shadow project values inside that scene.

Nested field: RenderPayload.name

At least one listed alternative must match.

anyOf alternative 1

Output name. Letters, digits, space, _ and - ONLY (no punctuation).

Default: "unnamed". Maximum length: 1000. Pattern: ^[a-zA-Z0-9_\- ]+$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.resolution

At least one listed alternative must match.

anyOf alternative 1

Canvas preset. Any value except "custom" OVERRIDES width/height.

Type: "sd" / "hd" / "full-hd" / "squared" / "youtube-short" / "youtube-video" / "tiktok" / "instagram-reel" / "instagram-post" / "instagram-story" / "instagram-feed" / "twitter-landscape" / "twitter-portrait" / "twitter-square" / "facebook-video" / "facebook-story" / "facebook-post" / "snapchat" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.width

At least one listed alternative must match.

anyOf alternative 1

Canvas width in px (plan-limited).

Default: 1280. Minimum: 1.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.height

At least one listed alternative must match.

anyOf alternative 1

Canvas height in px (plan-limited).

Default: 720. Minimum: 1.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.duration

At least one listed alternative must match.

anyOf alternative 1

Video length in seconds (plan-limited). With durationMode auto this is an optional minimum. Scene projects always include the full scene sequence.

Default: 10. Minimum: 0.1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.durationMode

At least one listed alternative must match.

anyOf alternative 1

Auto derives length from scenes, explicit element ends and captions. Supply videoEnd/exitEnd and audioEnd/exit for API submission. Omit to preserve legacy timing.

Type: "auto" / "fixed".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.frameRate

At least one listed alternative must match.

anyOf alternative 1

Frames per second.

Default: 30. Minimum: 1. Maximum: 60.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.outputFormat

At least one listed alternative must match.

anyOf alternative 1

Videos: mp4 (default), mov, avi, webm. Images (type: "image"): png (default), jpg, jpeg, webp.

Type: "mp4" / "mov" / "avi" / "webm" / "png" / "jpg" / "jpeg" / "webp".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.backgroundColor

At least one listed alternative must match.

anyOf alternative 1

Canvas background color.

Default: "#ffffff". Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.snapshotTime

At least one listed alternative must match.

anyOf alternative 1

Image renders only: second of the (virtual) timeline to snapshot.

Minimum: 0. Maximum: 3600.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.quality

At least one listed alternative must match.

anyOf alternative 1

Image renders only: jpg/webp quality (NOT valid for png).

Minimum: 1. Maximum: 100.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.transparent

At least one listed alternative must match.

anyOf alternative 1

Image renders only: transparent background (png/webp only, not jpg).

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.visuals

At least one listed alternative must match.

anyOf alternative 1

Elements shown for the whole project (outside scenes).

Array item: RenderPayload.visuals[]

Schema: Visual.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.audios

At least one listed alternative must match.

anyOf alternative 1

Project-level audio tracks (video only, plan-limited count).

Array item: RenderPayload.audios[]

Schema: AudioItem.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.scenes

At least one listed alternative must match.

anyOf alternative 1

Sequential timeline segments (video only, plan-limited count).

Array item: RenderPayload.scenes[]

Schema: Scene.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.thumbnail

At least one listed alternative must match.

anyOf alternative 1

Custom thumbnail image URL (video only). Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs.

Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: RenderPayload.subtitle

At least one listed alternative must match.

anyOf alternative 1

Schema: Subtitle.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

allOf alternative 1

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
}
},
"required": [
"type"
]
},
"then": {
"properties": {
"duration": false,
"durationMode": false,
"frameRate": false,
"audios": false,
"scenes": false,
"thumbnail": false,
"subtitle": false,
"outputFormat": {
"anyOf": [
{
"enum": [
"png",
"jpg",
"jpeg",
"webp"
],
"default": "png"
},
{
"type": "string",
"pattern": "\\{\\{\\s*[A-Za-z][A-Za-z0-9_]*(?:\\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\\s*\\}\\}"
}
]
},
"visuals": {
"anyOf": [
{
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/ImageVisual"
},
{
"$ref": "#/components/schemas/TextVisual"
},
{
"$ref": "#/components/schemas/SvgVisual"
}
]
}
},
{
"type": "string",
"pattern": "\\{\\{\\s*[A-Za-z][A-Za-z0-9_]*(?:\\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\\s*\\}\\}"
}
]
}
}
},
"else": {
"properties": {
"snapshotTime": false,
"quality": false,
"transparent": false,
"outputFormat": {
"anyOf": [
{
"enum": [
"mp4",
"mov",
"avi",
"webm"
],
"default": "mp4"
},
{
"type": "string",
"pattern": "\\{\\{\\s*[A-Za-z][A-Za-z0-9_]*(?:\\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\\s*\\}\\}"
}
]
}
}
}
}

allOf alternative 2

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
},
"outputFormat": {
"enum": [
"png"
]
}
},
"required": [
"type",
"outputFormat"
]
},
"then": {
"properties": {
"quality": false
}
}
}

allOf alternative 3

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
}
},
"required": [
"type"
],
"not": {
"required": [
"outputFormat"
]
}
},
"then": {
"properties": {
"quality": false
}
}
}

allOf alternative 4

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
},
"outputFormat": {
"enum": [
"jpg",
"jpeg"
]
}
},
"required": [
"type",
"outputFormat"
]
},
"then": {
"properties": {
"transparent": {
"anyOf": [
{
"const": false
},
{
"type": "string",
"pattern": "\\{\\{\\s*[A-Za-z][A-Za-z0-9_]*(?:\\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\\s*\\}\\}"
}
]
}
}
}
}
Visual

One canvas element, discriminated by type (IMAGE | VIDEO | GIF | SVG | TEXT, case-insensitive).

Required properties: type. Exactly one of the listed alternatives must match.

oneOf alternative 1

Schema: ImageVisual.

oneOf alternative 2

Schema: VideoVisual.

oneOf alternative 3

Schema: GifVisual.

oneOf alternative 4

Schema: SvgVisual.

oneOf alternative 5

Schema: TextVisual.

ImageVisual

A raster image placed on the canvas.

Unknown properties are rejected. Required properties: type, src.

FieldTypeRequiredDescription and constraints
ImageVisual.typestringYes"IMAGE" (case-insensitive). Pattern: ^[Ii][Mm][Aa][Gg][Ee]$.
ImageVisual.xnumber OR stringNoAt least one listed alternative must match.
ImageVisual.ynumber OR stringNoAt least one listed alternative must match.
ImageVisual.widthnumber OR stringNoAt least one listed alternative must match.
ImageVisual.heightnumber OR stringNoAt least one listed alternative must match.
ImageVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
ImageVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
ImageVisual.resize"contain" / "cover" OR stringNoAt least one listed alternative must match.
ImageVisual.enterBeginnumber OR stringNoAt least one listed alternative must match.
ImageVisual.enterEndnumber OR stringNoAt least one listed alternative must match.
ImageVisual.exitBeginnumber OR stringNoAt least one listed alternative must match.
ImageVisual.exitEndnumber OR stringNoAt least one listed alternative must match.
ImageVisual.opacitynumber OR stringNoAt least one listed alternative must match.
ImageVisual.anglenumber OR stringNoAt least one listed alternative must match.
ImageVisual.flipVboolean OR stringNoAt least one listed alternative must match.
ImageVisual.flipHboolean OR stringNoAt least one listed alternative must match.
ImageVisual.trackinteger OR stringNoAt least one listed alternative must match.
ImageVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
ImageVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
ImageVisual.srcstring OR stringYesAt least one listed alternative must match.
ImageVisual.cropParamsCropParams OR stringNoAt least one listed alternative must match.
ImageVisual.filterFilter OR stringNoAt least one listed alternative must match.
ImageVisual.chromaKeyChromaKey OR stringNoAt least one listed alternative must match.
ImageVisual.zoomZoom OR stringNoAt least one listed alternative must match.
ImageVisual.radiusRadius OR stringNoAt least one listed alternative must match.
ImageVisual.conditionany JSON valueNoA literal flag or placeholder. false, 0, an empty string, null or an absent resolved value prune this item. Expressions are not supported.

Nested field: ImageVisual.x

At least one listed alternative must match.

anyOf alternative 1

Anchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.y

At least one listed alternative must match.

anyOf alternative 1

Anchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.width

At least one listed alternative must match.

anyOf alternative 1

Element width in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.height

At least one listed alternative must match.

anyOf alternative 1

Element height in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.position

At least one listed alternative must match.

anyOf alternative 1

Placement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.anchor

At least one listed alternative must match.

anyOf alternative 1

Which point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.resize

At least one listed alternative must match.

anyOf alternative 1

How media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.

Type: "contain" / "cover".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.enterBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element starts appearing (enter animation start).

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.enterEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the enter animation finishes. Must be >= enterBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.exitBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the exit animation starts.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.exitEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element is fully gone. Must be >= exitBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.opacity

At least one listed alternative must match.

anyOf alternative 1

Element opacity, 0..1.

Minimum: 0. Maximum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.angle

At least one listed alternative must match.

anyOf alternative 1

Rotation in degrees.

Minimum: -360. Maximum: 360.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.flipV

At least one listed alternative must match.

anyOf alternative 1

Flip vertically.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.flipH

At least one listed alternative must match.

anyOf alternative 1

Flip horizontally.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.track

At least one listed alternative must match.

anyOf alternative 1

Z-order track; higher tracks render on top.

Minimum: 0. Maximum: 1000000.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.enterAnimation

At least one listed alternative must match.

anyOf alternative 1

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.exitAnimation

At least one listed alternative must match.

anyOf alternative 1

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.src

At least one listed alternative must match.

anyOf alternative 1

Source media URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs.

Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.cropParams

At least one listed alternative must match.

anyOf alternative 1

Schema: CropParams.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.filter

At least one listed alternative must match.

anyOf alternative 1

Schema: Filter.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.chromaKey

At least one listed alternative must match.

anyOf alternative 1

Schema: ChromaKey.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.zoom

At least one listed alternative must match.

anyOf alternative 1

Schema: Zoom.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ImageVisual.radius

At least one listed alternative must match.

anyOf alternative 1

Schema: Radius.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

CropParams

Source crop rectangle in source-media pixels.

Unknown properties are rejected. Required properties: x, y, width, height.

FieldTypeRequiredDescription and constraints
CropParams.xnumber OR stringYesAt least one listed alternative must match.
CropParams.ynumber OR stringYesAt least one listed alternative must match.
CropParams.widthnumber OR stringYesAt least one listed alternative must match.
CropParams.heightnumber OR stringYesAt least one listed alternative must match.

Nested field: CropParams.x

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: CropParams.y

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: CropParams.width

At least one listed alternative must match.

anyOf alternative 1

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: CropParams.height

At least one listed alternative must match.

anyOf alternative 1

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Filter

CSS-like color filters.

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Filter.brightnessnumber OR stringNoAt least one listed alternative must match.
Filter.contrastnumber OR stringNoAt least one listed alternative must match.
Filter.saturatenumber OR stringNoAt least one listed alternative must match.
Filter.hue-rotatestring OR stringNoAt least one listed alternative must match.
Filter.blurnumber OR string OR stringNoAt least one listed alternative must match.
Filter.invertboolean OR number OR stringNoAt least one listed alternative must match.
Filter.colorTintstring OR stringNoAt least one listed alternative must match.

Nested field: Filter.brightness

At least one listed alternative must match.

anyOf alternative 1

Minimum: -100. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Filter.contrast

At least one listed alternative must match.

anyOf alternative 1

Minimum: -100. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Filter.saturate

At least one listed alternative must match.

anyOf alternative 1

Minimum: -100. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Filter.hue-rotate

At least one listed alternative must match.

anyOf alternative 1

Degrees, preferably with a "deg" suffix (e.g. "90deg"). Legacy numeric strings such as "90" remain accepted.

Pattern: ^-?(?:\d+(?:\.\d+)?|\.\d+)(?:deg)?$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Filter.blur

At least one listed alternative must match.

anyOf alternative 1

Unitless 0..100 amount. Numeric strings remain accepted for backward compatibility; CSS lengths such as 4px are not supported.

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: ^(?:0*(?:100(?:\.0+)?|\d{1,2}(?:\.\d+)?|\.\d+))$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Filter.invert

At least one listed alternative must match.

anyOf alternative 1

Boolean or partial inversion amount from 0 to 1.

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Minimum: 0. Maximum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Filter.colorTint

At least one listed alternative must match.

anyOf alternative 1

Tint color (#rgb or #rrggbb).

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

ChromaKey

Green-screen keying.

Unknown properties are rejected. Required properties: color.

FieldTypeRequiredDescription and constraints
ChromaKey.colorstring OR stringYesAt least one listed alternative must match.
ChromaKey.similaritynumber OR stringNoAt least one listed alternative must match.
ChromaKey.blendnumber OR stringNoAt least one listed alternative must match.

Nested field: ChromaKey.color

At least one listed alternative must match.

anyOf alternative 1

Key color to remove (required).

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ChromaKey.similarity

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: ChromaKey.blend

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Zoom

Ken Burns zoom: true (default 1.2x depth) or { "depth": 1..10 }.

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Zoom.depthnumber OR stringNoAt least one listed alternative must match.

Nested field: Zoom.depth

At least one listed alternative must match.

anyOf alternative 1

Minimum: 1. Maximum: 10.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Radius

Rounded-corner radii in px (tl/tr/bl/br).

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Radius.tlnumber OR stringNoAt least one listed alternative must match.
Radius.trnumber OR stringNoAt least one listed alternative must match.
Radius.blnumber OR stringNoAt least one listed alternative must match.
Radius.brnumber OR stringNoAt least one listed alternative must match.

Nested field: Radius.tl

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Radius.tr

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Radius.bl

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Radius.br

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

VideoVisual

A video clip placed on the canvas (video projects only).

Unknown properties are rejected. Required properties: type, src.

FieldTypeRequiredDescription and constraints
VideoVisual.typestringYes"VIDEO" (case-insensitive). Pattern: ^[Vv][Ii][Dd][Ee][Oo]$.
VideoVisual.xnumber OR stringNoAt least one listed alternative must match.
VideoVisual.ynumber OR stringNoAt least one listed alternative must match.
VideoVisual.widthnumber OR stringNoAt least one listed alternative must match.
VideoVisual.heightnumber OR stringNoAt least one listed alternative must match.
VideoVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
VideoVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
VideoVisual.resize"contain" / "cover" OR stringNoAt least one listed alternative must match.
VideoVisual.enterBeginnumber OR stringNoAt least one listed alternative must match.
VideoVisual.enterEndnumber OR stringNoAt least one listed alternative must match.
VideoVisual.exitBeginnumber OR stringNoAt least one listed alternative must match.
VideoVisual.exitEndnumber OR stringNoAt least one listed alternative must match.
VideoVisual.opacitynumber OR stringNoAt least one listed alternative must match.
VideoVisual.anglenumber OR stringNoAt least one listed alternative must match.
VideoVisual.flipVboolean OR stringNoAt least one listed alternative must match.
VideoVisual.flipHboolean OR stringNoAt least one listed alternative must match.
VideoVisual.trackinteger OR stringNoAt least one listed alternative must match.
VideoVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
VideoVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
VideoVisual.srcstring OR stringYesAt least one listed alternative must match.
VideoVisual.cropParamsCropParams OR stringNoAt least one listed alternative must match.
VideoVisual.filterFilter OR stringNoAt least one listed alternative must match.
VideoVisual.chromaKeyChromaKey OR stringNoAt least one listed alternative must match.
VideoVisual.zoomZoom OR stringNoAt least one listed alternative must match.
VideoVisual.radiusRadius OR stringNoAt least one listed alternative must match.
VideoVisual.videoBeginnumber OR stringNoAt least one listed alternative must match.
VideoVisual.videoEndnumber OR stringNoAt least one listed alternative must match.
VideoVisual.videoDurationnumber OR stringNoAt least one listed alternative must match.
VideoVisual.volumenumber OR stringNoAt least one listed alternative must match.
VideoVisual.speednumber OR stringNoAt least one listed alternative must match.
VideoVisual.transition"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
VideoVisual.transitionDurationnumber OR stringNoAt least one listed alternative must match.
VideoVisual.transitionIdstring OR stringNoAt least one listed alternative must match.
VideoVisual.frameRateinteger OR stringNoAt least one listed alternative must match.
VideoVisual.idstring OR stringNoAt least one listed alternative must match.
VideoVisual.hasAudioboolean OR stringNoAt least one listed alternative must match.
VideoVisual.conditionany JSON valueNoA literal flag or placeholder. false, 0, an empty string, null or an absent resolved value prune this item. Expressions are not supported.

Nested field: VideoVisual.x

At least one listed alternative must match.

anyOf alternative 1

Anchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.y

At least one listed alternative must match.

anyOf alternative 1

Anchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.width

At least one listed alternative must match.

anyOf alternative 1

Element width in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.height

At least one listed alternative must match.

anyOf alternative 1

Element height in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.position

At least one listed alternative must match.

anyOf alternative 1

Placement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.anchor

At least one listed alternative must match.

anyOf alternative 1

Which point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.resize

At least one listed alternative must match.

anyOf alternative 1

How media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.

Type: "contain" / "cover".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.enterBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element starts appearing (enter animation start).

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.enterEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the enter animation finishes. Must be >= enterBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.exitBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the exit animation starts.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.exitEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element is fully gone. Must be >= exitBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.opacity

At least one listed alternative must match.

anyOf alternative 1

Element opacity, 0..1.

Minimum: 0. Maximum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.angle

At least one listed alternative must match.

anyOf alternative 1

Rotation in degrees.

Minimum: -360. Maximum: 360.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.flipV

At least one listed alternative must match.

anyOf alternative 1

Flip vertically.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.flipH

At least one listed alternative must match.

anyOf alternative 1

Flip horizontally.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.track

At least one listed alternative must match.

anyOf alternative 1

Z-order track; higher tracks render on top.

Minimum: 0. Maximum: 1000000.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.enterAnimation

At least one listed alternative must match.

anyOf alternative 1

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.exitAnimation

At least one listed alternative must match.

anyOf alternative 1

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.src

At least one listed alternative must match.

anyOf alternative 1

Source media URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs.

Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.cropParams

At least one listed alternative must match.

anyOf alternative 1

Schema: CropParams.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.filter

At least one listed alternative must match.

anyOf alternative 1

Schema: Filter.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.chromaKey

At least one listed alternative must match.

anyOf alternative 1

Schema: ChromaKey.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.zoom

At least one listed alternative must match.

anyOf alternative 1

Schema: Zoom.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.radius

At least one listed alternative must match.

anyOf alternative 1

Schema: Radius.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.videoBegin

At least one listed alternative must match.

anyOf alternative 1

Trim: source time (s) where playback starts.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.videoEnd

At least one listed alternative must match.

anyOf alternative 1

Trim: source time (s) where playback ends.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.videoDuration

At least one listed alternative must match.

anyOf alternative 1

Play only this many seconds of the source.

Minimum: 0.1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.volume

At least one listed alternative must match.

anyOf alternative 1

Clip audio volume, 0..2 (1 = original level).

Minimum: 0. Maximum: 2.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.speed

At least one listed alternative must match.

anyOf alternative 1

Playback speed multiplier, 0.1..10.

Minimum: 0.1. Maximum: 10.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.transition

At least one listed alternative must match.

anyOf alternative 1

Transition into the linked clip (see transitionId).

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.transitionDuration

At least one listed alternative must match.

anyOf alternative 1

Transition length in seconds.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.transitionId

At least one listed alternative must match.

anyOf alternative 1

id of the clip this transition links to.

Maximum length: 100. Pattern: ^[a-zA-Z0-9_-]+$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.frameRate

At least one listed alternative must match.

anyOf alternative 1

Override source frame rate (1..60).

Minimum: 1. Maximum: 60.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.id

At least one listed alternative must match.

anyOf alternative 1

Clip id (referenced by transitionId).

Pattern: ^[a-zA-Z0-9_-]+$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: VideoVisual.hasAudio

At least one listed alternative must match.

anyOf alternative 1

Hint that the source has an audio stream.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

GifVisual

An animated GIF placed on the canvas (video projects only).

Unknown properties are rejected. Required properties: type, src.

FieldTypeRequiredDescription and constraints
GifVisual.typestringYes"GIF" (case-insensitive). Pattern: ^[Gg][Ii][Ff]$.
GifVisual.xnumber OR stringNoAt least one listed alternative must match.
GifVisual.ynumber OR stringNoAt least one listed alternative must match.
GifVisual.widthnumber OR stringNoAt least one listed alternative must match.
GifVisual.heightnumber OR stringNoAt least one listed alternative must match.
GifVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
GifVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
GifVisual.resize"contain" / "cover" OR stringNoAt least one listed alternative must match.
GifVisual.enterBeginnumber OR stringNoAt least one listed alternative must match.
GifVisual.enterEndnumber OR stringNoAt least one listed alternative must match.
GifVisual.exitBeginnumber OR stringNoAt least one listed alternative must match.
GifVisual.exitEndnumber OR stringNoAt least one listed alternative must match.
GifVisual.opacitynumber OR stringNoAt least one listed alternative must match.
GifVisual.anglenumber OR stringNoAt least one listed alternative must match.
GifVisual.flipVboolean OR stringNoAt least one listed alternative must match.
GifVisual.flipHboolean OR stringNoAt least one listed alternative must match.
GifVisual.trackinteger OR stringNoAt least one listed alternative must match.
GifVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
GifVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
GifVisual.srcstring OR stringYesAt least one listed alternative must match.
GifVisual.cropParamsCropParams OR stringNoAt least one listed alternative must match.
GifVisual.filterFilter OR stringNoAt least one listed alternative must match.
GifVisual.chromaKeyChromaKey OR stringNoAt least one listed alternative must match.
GifVisual.zoomZoom OR stringNoAt least one listed alternative must match.
GifVisual.radiusRadius OR stringNoAt least one listed alternative must match.
GifVisual.conditionany JSON valueNoA literal flag or placeholder. false, 0, an empty string, null or an absent resolved value prune this item. Expressions are not supported.

Nested field: GifVisual.x

At least one listed alternative must match.

anyOf alternative 1

Anchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.y

At least one listed alternative must match.

anyOf alternative 1

Anchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.width

At least one listed alternative must match.

anyOf alternative 1

Element width in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.height

At least one listed alternative must match.

anyOf alternative 1

Element height in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.position

At least one listed alternative must match.

anyOf alternative 1

Placement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.anchor

At least one listed alternative must match.

anyOf alternative 1

Which point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.resize

At least one listed alternative must match.

anyOf alternative 1

How media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.

Type: "contain" / "cover".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.enterBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element starts appearing (enter animation start).

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.enterEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the enter animation finishes. Must be >= enterBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.exitBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the exit animation starts.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.exitEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element is fully gone. Must be >= exitBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.opacity

At least one listed alternative must match.

anyOf alternative 1

Element opacity, 0..1.

Minimum: 0. Maximum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.angle

At least one listed alternative must match.

anyOf alternative 1

Rotation in degrees.

Minimum: -360. Maximum: 360.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.flipV

At least one listed alternative must match.

anyOf alternative 1

Flip vertically.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.flipH

At least one listed alternative must match.

anyOf alternative 1

Flip horizontally.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.track

At least one listed alternative must match.

anyOf alternative 1

Z-order track; higher tracks render on top.

Minimum: 0. Maximum: 1000000.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.enterAnimation

At least one listed alternative must match.

anyOf alternative 1

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.exitAnimation

At least one listed alternative must match.

anyOf alternative 1

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.src

At least one listed alternative must match.

anyOf alternative 1

Source media URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs.

Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.cropParams

At least one listed alternative must match.

anyOf alternative 1

Schema: CropParams.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.filter

At least one listed alternative must match.

anyOf alternative 1

Schema: Filter.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.chromaKey

At least one listed alternative must match.

anyOf alternative 1

Schema: ChromaKey.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.zoom

At least one listed alternative must match.

anyOf alternative 1

Schema: Zoom.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: GifVisual.radius

At least one listed alternative must match.

anyOf alternative 1

Schema: Radius.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

SvgVisual

Inline SVG markup drawn on the canvas.

Unknown properties are rejected. Required properties: type, svg.

FieldTypeRequiredDescription and constraints
SvgVisual.typestringYes"SVG" (case-insensitive). Pattern: ^[Ss][Vv][Gg]$.
SvgVisual.xnumber OR stringNoAt least one listed alternative must match.
SvgVisual.ynumber OR stringNoAt least one listed alternative must match.
SvgVisual.widthnumber OR stringNoAt least one listed alternative must match.
SvgVisual.heightnumber OR stringNoAt least one listed alternative must match.
SvgVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
SvgVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
SvgVisual.resize"contain" / "cover" OR stringNoAt least one listed alternative must match.
SvgVisual.enterBeginnumber OR stringNoAt least one listed alternative must match.
SvgVisual.enterEndnumber OR stringNoAt least one listed alternative must match.
SvgVisual.exitBeginnumber OR stringNoAt least one listed alternative must match.
SvgVisual.exitEndnumber OR stringNoAt least one listed alternative must match.
SvgVisual.opacitynumber OR stringNoAt least one listed alternative must match.
SvgVisual.anglenumber OR stringNoAt least one listed alternative must match.
SvgVisual.flipVboolean OR stringNoAt least one listed alternative must match.
SvgVisual.flipHboolean OR stringNoAt least one listed alternative must match.
SvgVisual.trackinteger OR stringNoAt least one listed alternative must match.
SvgVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
SvgVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
SvgVisual.svgstring OR stringYesAt least one listed alternative must match.
SvgVisual.filterFilter OR stringNoAt least one listed alternative must match.
SvgVisual.chromaKeyChromaKey OR stringNoAt least one listed alternative must match.
SvgVisual.customCodeCustomCode OR stringNoAt least one listed alternative must match.
SvgVisual.designerDesigner OR stringNoAt least one listed alternative must match.
SvgVisual.conditionany JSON valueNoA literal flag or placeholder. false, 0, an empty string, null or an absent resolved value prune this item. Expressions are not supported.

Nested field: SvgVisual.x

At least one listed alternative must match.

anyOf alternative 1

Anchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.y

At least one listed alternative must match.

anyOf alternative 1

Anchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.width

At least one listed alternative must match.

anyOf alternative 1

Element width in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.height

At least one listed alternative must match.

anyOf alternative 1

Element height in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.position

At least one listed alternative must match.

anyOf alternative 1

Placement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.anchor

At least one listed alternative must match.

anyOf alternative 1

Which point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.resize

At least one listed alternative must match.

anyOf alternative 1

How media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.

Type: "contain" / "cover".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.enterBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element starts appearing (enter animation start).

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.enterEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the enter animation finishes. Must be >= enterBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.exitBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the exit animation starts.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.exitEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element is fully gone. Must be >= exitBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.opacity

At least one listed alternative must match.

anyOf alternative 1

Element opacity, 0..1.

Minimum: 0. Maximum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.angle

At least one listed alternative must match.

anyOf alternative 1

Rotation in degrees.

Minimum: -360. Maximum: 360.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.flipV

At least one listed alternative must match.

anyOf alternative 1

Flip vertically.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.flipH

At least one listed alternative must match.

anyOf alternative 1

Flip horizontally.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.track

At least one listed alternative must match.

anyOf alternative 1

Z-order track; higher tracks render on top.

Minimum: 0. Maximum: 1000000.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.enterAnimation

At least one listed alternative must match.

anyOf alternative 1

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.exitAnimation

At least one listed alternative must match.

anyOf alternative 1

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.svg

At least one listed alternative must match.

anyOf alternative 1

Inline SVG markup starting with "<svg". Sanitized: no <script>/<foreignObject>/<iframe>/<object>/<embed>/<audio>/<video>, no on* event attributes, no external url()/href/src (only "#id" fragment refs), dimensions <= 4096px, no integers with 8+ digits.

Minimum length: 1. Maximum length: 200000.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.filter

At least one listed alternative must match.

anyOf alternative 1

Schema: Filter.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.chromaKey

At least one listed alternative must match.

anyOf alternative 1

Schema: ChromaKey.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.customCode

At least one listed alternative must match.

anyOf alternative 1

Schema: CustomCode.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: SvgVisual.designer

At least one listed alternative must match.

anyOf alternative 1

Schema: Designer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

CustomCode

Sandboxed styling/animation code run inside the render browser (Design Studio). No network/filesystem/storage/navigation APIs — see validation notes.

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
CustomCode.cssstring OR stringNoAt least one listed alternative must match.
CustomCode.jsstring OR stringNoAt least one listed alternative must match.
CustomCode.animationDurationnumber OR stringNoAt least one listed alternative must match.

Nested field: CustomCode.css

At least one listed alternative must match.

anyOf alternative 1

Maximum length: 200000.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: CustomCode.js

At least one listed alternative must match.

anyOf alternative 1

Maximum length: 200000.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: CustomCode.animationDuration

At least one listed alternative must match.

anyOf alternative 1

Seconds the customCode animation runs (max 15).

Maximum: 15. Greater than: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Designer

Opaque Design Studio round-trip metadata (max 200k chars serialized). Never rendered; keeps 'edit design' working.

Type: object.

TextVisual

Styled text. Provide plain text (no < or > characters) and/or limited html. At least one of text/html must be non-empty.

Unknown properties are rejected. Required properties: type. At least one listed alternative must match.

FieldTypeRequiredDescription and constraints
TextVisual.typestringYes"TEXT" (case-insensitive). Pattern: ^[Tt][Ee][Xx][Tt]$.
TextVisual.xnumber OR stringNoAt least one listed alternative must match.
TextVisual.ynumber OR stringNoAt least one listed alternative must match.
TextVisual.widthnumber OR stringNoAt least one listed alternative must match.
TextVisual.heightnumber OR stringNoAt least one listed alternative must match.
TextVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
TextVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom" OR stringNoAt least one listed alternative must match.
TextVisual.resize"contain" / "cover" OR stringNoAt least one listed alternative must match.
TextVisual.enterBeginnumber OR stringNoAt least one listed alternative must match.
TextVisual.enterEndnumber OR stringNoAt least one listed alternative must match.
TextVisual.exitBeginnumber OR stringNoAt least one listed alternative must match.
TextVisual.exitEndnumber OR stringNoAt least one listed alternative must match.
TextVisual.opacitynumber OR stringNoAt least one listed alternative must match.
TextVisual.anglenumber OR stringNoAt least one listed alternative must match.
TextVisual.flipVboolean OR stringNoAt least one listed alternative must match.
TextVisual.flipHboolean OR stringNoAt least one listed alternative must match.
TextVisual.trackinteger OR stringNoAt least one listed alternative must match.
TextVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
TextVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
TextVisual.textstring OR stringNoAt least one listed alternative must match.
TextVisual.htmlstring OR stringNoAt least one listed alternative must match.
TextVisual.styleobject OR stringNoAt least one listed alternative must match.
TextVisual.fitToBoxboolean OR stringNoAt least one listed alternative must match.
TextVisual.customCodeCustomCode OR stringNoAt least one listed alternative must match.
TextVisual.designerDesigner OR stringNoAt least one listed alternative must match.
TextVisual.conditionany JSON valueNoA literal flag or placeholder. false, 0, an empty string, null or an absent resolved value prune this item. Expressions are not supported.

Nested field: TextVisual.x

At least one listed alternative must match.

anyOf alternative 1

Anchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.y

At least one listed alternative must match.

anyOf alternative 1

Anchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.width

At least one listed alternative must match.

anyOf alternative 1

Element width in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.height

At least one listed alternative must match.

anyOf alternative 1

Element height in px (plan-limited).

Minimum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.position

At least one listed alternative must match.

anyOf alternative 1

Placement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.anchor

At least one listed alternative must match.

anyOf alternative 1

Which point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).

Type: "top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.resize

At least one listed alternative must match.

anyOf alternative 1

How media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.

Type: "contain" / "cover".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.enterBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element starts appearing (enter animation start).

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.enterEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the enter animation finishes. Must be >= enterBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.exitBegin

At least one listed alternative must match.

anyOf alternative 1

Seconds when the exit animation starts.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.exitEnd

At least one listed alternative must match.

anyOf alternative 1

Seconds when the element is fully gone. Must be >= exitBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.opacity

At least one listed alternative must match.

anyOf alternative 1

Element opacity, 0..1.

Minimum: 0. Maximum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.angle

At least one listed alternative must match.

anyOf alternative 1

Rotation in degrees.

Minimum: -360. Maximum: 360.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.flipV

At least one listed alternative must match.

anyOf alternative 1

Flip vertically.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.flipH

At least one listed alternative must match.

anyOf alternative 1

Flip horizontally.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.track

At least one listed alternative must match.

anyOf alternative 1

Z-order track; higher tracks render on top.

Minimum: 0. Maximum: 1000000.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.enterAnimation

At least one listed alternative must match.

anyOf alternative 1

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.exitAnimation

At least one listed alternative must match.

anyOf alternative 1

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.text

At least one listed alternative must match.

anyOf alternative 1

Plain text content. HTML markup (< or >) is rejected — use html for markup.

Maximum length: 20000.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.html

At least one listed alternative must match.

anyOf alternative 1

Limited HTML. Allowed tags: b, strong, i, em, u, s, br, span, div, p, ul, ol, li, img, canvas, svg (+ svg geometry). Allowed attributes: style, class, src, alt, width, height. No <script>/<style>, no event handlers, no external CSS url().

Maximum length: 200000.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.style

At least one listed alternative must match.

anyOf alternative 1

CSS style object applied to the text container (camelCase or kebab-case keys, and --custom-properties). LAYOUT MODEL: the container uses box-sizing: content-box, so padding/border render OUTSIDE the declared width/height and overflow gets cut — for cards/pills set the full size via width/height and center content with display:flex + alignItems:center + justifyContent:center instead of padding. Text sits at the TOP of the box unless flex-centered. Values must not contain url(), @import, expression(), comments or other dangerous tokens. Max value length 4000 chars.

Maximum properties: 120.

Type: object.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.fitToBox

At least one listed alternative must match.

anyOf alternative 1

Scale the typography down just enough that the painted text stays inside the declared width/height instead of being clipped at the element's edge. No effect when the content already fits, so an unchanged template renders identically.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.customCode

At least one listed alternative must match.

anyOf alternative 1

Schema: CustomCode.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: TextVisual.designer

At least one listed alternative must match.

anyOf alternative 1

Schema: Designer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 1

Required properties: text.

FieldTypeRequiredDescription and constraints
TextVisual.textstring OR stringYesAt least one listed alternative must match.

Nested field: TextVisual.text

At least one listed alternative must match.

anyOf alternative 1

Pattern: \S.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Required properties: html.

FieldTypeRequiredDescription and constraints
TextVisual.htmlstring OR stringYesAt least one listed alternative must match.

Nested field: TextVisual.html

At least one listed alternative must match.

anyOf alternative 1

Pattern: \S.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 3

Required properties: condition.

Type: any JSON value.

AudioItem

A soundtrack / voice-over entry for audios (video projects only).

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
AudioItem.srcstring OR stringNoAt least one listed alternative must match.
AudioItem.matchDurationboolean OR stringNoAt least one listed alternative must match.
AudioItem.enternumber OR stringNoAt least one listed alternative must match.
AudioItem.exitnumber OR stringNoAt least one listed alternative must match.
AudioItem.volumenumber OR stringNoAt least one listed alternative must match.
AudioItem.speednumber OR stringNoAt least one listed alternative must match.
AudioItem.audioBeginnumber OR stringNoAt least one listed alternative must match.
AudioItem.audioEndnumber OR stringNoAt least one listed alternative must match.
AudioItem.audioDurationnumber OR stringNoAt least one listed alternative must match.
AudioItem.trackinteger OR stringNoAt least one listed alternative must match.
AudioItem.conditionany JSON valueNoA literal flag or placeholder. false, 0, an empty string, null or an absent resolved value prune this item. Expressions are not supported.

Nested field: AudioItem.src

At least one listed alternative must match.

anyOf alternative 1

Audio file URL (mp3/wav/...). Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs.

Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.matchDuration

At least one listed alternative must match.

anyOf alternative 1

Follow the containing scene/project length without extending automatic duration. Overrides exit.

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.enter

At least one listed alternative must match.

anyOf alternative 1

Timeline second the audio starts playing.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.exit

At least one listed alternative must match.

anyOf alternative 1

Timeline second the audio stops. Must be >= enter.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.volume

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 2.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.speed

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.1. Maximum: 10.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.audioBegin

At least one listed alternative must match.

anyOf alternative 1

Trim: source second where playback starts.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.audioEnd

At least one listed alternative must match.

anyOf alternative 1

Trim: source second where playback ends. Must be >= audioBegin.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.audioDuration

At least one listed alternative must match.

anyOf alternative 1

Play only this many seconds of the source.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: AudioItem.track

At least one listed alternative must match.

anyOf alternative 1

Mix track index; audio tracks mix together.

Minimum: 0. Maximum: 1000000.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Scene

A timeline segment. Scenes play sequentially; a scene's transition blends into the NEXT scene (xfade overlap is subtracted from the total duration).

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Scene.idstring OR stringNoAt least one listed alternative must match.
Scene.duration-1 OR number OR stringNoAt least one listed alternative must match.
Scene.transition"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR null OR stringNoAt least one listed alternative must match.
Scene.transitionIdstring OR null OR stringNoAt least one listed alternative must match.
Scene.transitionDurationnumber OR stringNoAt least one listed alternative must match.
Scene.backgroundColorstring OR stringNoAt least one listed alternative must match.
Scene.visualsarray of Visual OR stringNoAt least one listed alternative must match.
Scene.audiosarray of AudioItem OR stringNoAt least one listed alternative must match.
Scene.variablesobjectNoDefault variable values; request variables override these. Scene defaults shadow project values inside that scene.
Scene.iteratestringNoName or dotted path of an array variable; one scene is generated per item.
Scene.iterateAsstringNoDefault: "item". Pattern: ^[A-Za-z][A-Za-z0-9_]*$.
Scene.conditionany JSON valueNoA literal flag or placeholder. false, 0, an empty string, null or an absent resolved value prune this item. Expressions are not supported.

Nested field: Scene.id

At least one listed alternative must match.

anyOf alternative 1

Optional scene ID. Explicit IDs must be unique within the project.

Maximum length: 100. Pattern: ^[a-zA-Z0-9_-]+$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Scene.duration

At least one listed alternative must match.

anyOf alternative 1

Seconds; -1 (or omitted) auto-computes from the scene's content.

At least one listed alternative must match.

anyOf alternative 1

Type: -1.

anyOf alternative 2

Minimum: 0.1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Scene.transition

At least one listed alternative must match.

anyOf alternative 1

Transition into the next scene.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Scene.transitionId

At least one listed alternative must match.

anyOf alternative 1

At least one listed alternative must match.

anyOf alternative 1

Maximum length: 100. Pattern: ^[a-zA-Z0-9_-]+$.

Type: string.

anyOf alternative 2

Type: null.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Scene.transitionDuration

At least one listed alternative must match.

anyOf alternative 1

Transition overlap in seconds (default 0.5).

Minimum: 0. Maximum: 60.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Scene.backgroundColor

At least one listed alternative must match.

anyOf alternative 1

Scene background (#rgb or #rrggbb).

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Scene.visuals

At least one listed alternative must match.

anyOf alternative 1

Array item: Scene.visuals[]

Schema: Visual.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Scene.audios

At least one listed alternative must match.

anyOf alternative 1

Array item: Scene.audios[]

Schema: AudioItem.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Subtitle

Burned-in subtitles. Content: EXACTLY ONE of src (SRT/VTT URL) or captions. Style: v2 flat keys (animation/font/stroke/background/...) OR the legacy styles block — not both.

Unknown properties are rejected. Exactly one of the listed alternatives must match.

FieldTypeRequiredDescription and constraints
Subtitle.srcstring OR stringNoAt least one listed alternative must match.
Subtitle.captionsarray of any JSON value OR any JSON value OR stringNoAt least one listed alternative must match.
Subtitle.maxWordsPerLineinteger OR stringNoAt least one listed alternative must match.
Subtitle.animation"normal" / "none" / "one-word" / "karaoke" / "progressive" / "highlight" / "fill" / "pop" / "bounce" / "fade" / "slide" / "typewriter" OR stringNoAt least one listed alternative must match.
Subtitle.direction"up" / "down" / "left" / "right" OR stringNoAt least one listed alternative must match.
Subtitle.fontobject OR stringNoAt least one listed alternative must match.
Subtitle.strokeobject OR stringNoAt least one listed alternative must match.
Subtitle.backgroundobject OR stringNoAt least one listed alternative must match.
Subtitle.activeWordobject OR stringNoAt least one listed alternative must match.
Subtitle.position"top-left" / "top-center" / "top-right" / "bottom-left" / "bottom-center" / "bottom-right" / "center-center" / "center-left" / "center-right" / "top" / "center" / "bottom" OR stringNoAt least one listed alternative must match.
Subtitle.marginobject OR stringNoAt least one listed alternative must match.
Subtitle.stylesobject OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.src

At least one listed alternative must match.

anyOf alternative 1

SRT or VTT file URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs.

Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.captions

At least one listed alternative must match.

anyOf alternative 1

Inline captions (plan-limited count).

Minimum items: 1.

Array item: Subtitle.captions[]

Unknown properties are rejected. Required properties: start, end. At least one listed alternative must match.

FieldTypeRequiredDescription and constraints
Subtitle.captions[].startnumber OR stringYesAt least one listed alternative must match.
Subtitle.captions[].endnumber OR stringYesAt least one listed alternative must match.
Subtitle.captions[].textstring OR stringNoAt least one listed alternative must match.
Subtitle.captions[].wordsarray of object OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.captions[].start

At least one listed alternative must match.

anyOf alternative 1

Caption start time in seconds.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.captions[].end

At least one listed alternative must match.

anyOf alternative 1

Caption end time in seconds.

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.captions[].text

At least one listed alternative must match.

anyOf alternative 1

Minimum length: 1. Maximum length: 1000.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.captions[].words

At least one listed alternative must match.

anyOf alternative 1

Per-word timings; auto-distributed from text when omitted.

Minimum items: 1.

Array item: Subtitle.captions[].words[]

Unknown properties are rejected. Required properties: start, end, text.

FieldTypeRequiredDescription and constraints
Subtitle.captions[].words[].startnumber OR stringYesAt least one listed alternative must match.
Subtitle.captions[].words[].endnumber OR stringYesAt least one listed alternative must match.
Subtitle.captions[].words[].textstring OR stringYesAt least one listed alternative must match.

Nested field: Subtitle.captions[].words[].start

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.captions[].words[].end

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.captions[].words[].text

At least one listed alternative must match.

anyOf alternative 1

Minimum length: 1. Maximum length: 100.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 1

Required properties: text.

Type: any JSON value.

anyOf alternative 2

Required properties: words.

Type: any JSON value.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.maxWordsPerLine

At least one listed alternative must match.

anyOf alternative 1

Re-chunk captions to at most N words per line.

Minimum: 1. Maximum: 20.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.animation

At least one listed alternative must match.

anyOf alternative 1

Caption animation mode.

Type: "normal" / "none" / "one-word" / "karaoke" / "progressive" / "highlight" / "fill" / "pop" / "bounce" / "fade" / "slide" / "typewriter".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.direction

At least one listed alternative must match.

anyOf alternative 1

Slide direction when animation is "slide".

Type: "up" / "down" / "left" / "right".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.font

At least one listed alternative must match.

anyOf alternative 1

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Subtitle.font.familystring OR stringNoAt least one listed alternative must match.
Subtitle.font.sizenumber OR stringNoAt least one listed alternative must match.
Subtitle.font.colorstring OR stringNoAt least one listed alternative must match.
Subtitle.font.boldboolean OR stringNoAt least one listed alternative must match.
Subtitle.font.italicboolean OR stringNoAt least one listed alternative must match.
Subtitle.font.transform"uppercase" / "lowercase" / "capitalize" OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.font.family

At least one listed alternative must match.

anyOf alternative 1

Maximum length: 1000. Pattern: ^[a-zA-Z0-9_\- ]+$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.font.size

At least one listed alternative must match.

anyOf alternative 1

Minimum: 1. Maximum: 1000.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.font.color

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.font.bold

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.font.italic

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.font.transform

At least one listed alternative must match.

anyOf alternative 1

Type: "uppercase" / "lowercase" / "capitalize".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.stroke

At least one listed alternative must match.

anyOf alternative 1

Unknown properties are rejected. Required properties: color, width.

FieldTypeRequiredDescription and constraints
Subtitle.stroke.colorstring OR stringYesAt least one listed alternative must match.
Subtitle.stroke.widthnumber OR stringYesAt least one listed alternative must match.

Nested field: Subtitle.stroke.color

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.stroke.width

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.background

At least one listed alternative must match.

anyOf alternative 1

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Subtitle.background.colorstring OR stringNoAt least one listed alternative must match.
Subtitle.background.opacitynumber OR stringNoAt least one listed alternative must match.
Subtitle.background.paddingnumber OR stringNoAt least one listed alternative must match.
Subtitle.background.radiusnumber OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.background.color

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.background.opacity

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 1.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.background.padding

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 200.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.background.radius

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 200.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.activeWord

At least one listed alternative must match.

anyOf alternative 1

Highlight styling for the currently spoken word.

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Subtitle.activeWord.colorstring OR stringNoAt least one listed alternative must match.
Subtitle.activeWord.backgroundstring OR stringNoAt least one listed alternative must match.
Subtitle.activeWord.radiusnumber OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.activeWord.color

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.activeWord.background

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.activeWord.radius

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 200.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.position

At least one listed alternative must match.

anyOf alternative 1

Type: "top-left" / "top-center" / "top-right" / "bottom-left" / "bottom-center" / "bottom-right" / "center-center" / "center-left" / "center-right" / "top" / "center" / "bottom".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.margin

At least one listed alternative must match.

anyOf alternative 1

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Subtitle.margin.xinteger OR stringNoAt least one listed alternative must match.
Subtitle.margin.yinteger OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.margin.x

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.margin.y

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles

At least one listed alternative must match.

anyOf alternative 1

LEGACY style block — prefer the flat v2 keys. Cannot be combined with them.

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Subtitle.styles.colorstring OR stringNoAt least one listed alternative must match.
Subtitle.styles.backgroundstring OR stringNoAt least one listed alternative must match.
Subtitle.styles.backgroundPaddingnumber OR stringNoAt least one listed alternative must match.
Subtitle.styles.backgroundRadiusnumber OR stringNoAt least one listed alternative must match.
Subtitle.styles.isBoldboolean OR stringNoAt least one listed alternative must match.
Subtitle.styles.isItalicboolean OR stringNoAt least one listed alternative must match.
Subtitle.styles.fontSizenumber OR stringNoAt least one listed alternative must match.
Subtitle.styles.fontFamilystring OR stringNoAt least one listed alternative must match.
Subtitle.styles.textTransform"uppercase" / "lowercase" / "capitalize" OR stringNoAt least one listed alternative must match.
Subtitle.styles.outlineobject OR stringNoAt least one listed alternative must match.
Subtitle.styles.position"top-left" / "top-center" / "top-right" / "bottom-left" / "bottom-center" / "bottom-right" / "center-center" / "center-left" / "center-right" OR stringNoAt least one listed alternative must match.
Subtitle.styles.marginVinteger OR stringNoAt least one listed alternative must match.
Subtitle.styles.marginHinteger OR stringNoAt least one listed alternative must match.
Subtitle.styles.mode"normal" / "none" / "one-word" / "karaoke" / "progressive" / "highlight" / "fill" / "pop" / "bounce" / "fade" / "slide" / "typewriter" OR stringNoAt least one listed alternative must match.
Subtitle.styles.slideDirection"up" / "down" / "left" / "right" OR stringNoAt least one listed alternative must match.
Subtitle.styles.activeWordobject OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.styles.color

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.background

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.backgroundPadding

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 200.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.backgroundRadius

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 200.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.isBold

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.isItalic

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.fontSize

At least one listed alternative must match.

anyOf alternative 1

Minimum: 1. Maximum: 1000.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.fontFamily

At least one listed alternative must match.

anyOf alternative 1

Maximum length: 1000. Pattern: ^[a-zA-Z0-9_\- ]+$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.textTransform

At least one listed alternative must match.

anyOf alternative 1

Type: "uppercase" / "lowercase" / "capitalize".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.outline

At least one listed alternative must match.

anyOf alternative 1

Unknown properties are rejected. Required properties: width, color.

FieldTypeRequiredDescription and constraints
Subtitle.styles.outline.widthnumber OR stringYesAt least one listed alternative must match.
Subtitle.styles.outline.colorstring OR stringYesAt least one listed alternative must match.

Nested field: Subtitle.styles.outline.width

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.outline.color

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.position

At least one listed alternative must match.

anyOf alternative 1

Type: "top-left" / "top-center" / "top-right" / "bottom-left" / "bottom-center" / "bottom-right" / "center-center" / "center-left" / "center-right".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.marginV

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.marginH

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0.

Type: integer.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.mode

At least one listed alternative must match.

anyOf alternative 1

Type: "normal" / "none" / "one-word" / "karaoke" / "progressive" / "highlight" / "fill" / "pop" / "bounce" / "fade" / "slide" / "typewriter".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.slideDirection

At least one listed alternative must match.

anyOf alternative 1

Type: "up" / "down" / "left" / "right".

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.activeWord

At least one listed alternative must match.

anyOf alternative 1

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
Subtitle.styles.activeWord.colorstring OR stringNoAt least one listed alternative must match.
Subtitle.styles.activeWord.backgroundstring OR stringNoAt least one listed alternative must match.
Subtitle.styles.activeWord.radiusnumber OR stringNoAt least one listed alternative must match.

Nested field: Subtitle.styles.activeWord.color

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.activeWord.background

At least one listed alternative must match.

anyOf alternative 1

#rrggbb or #rrggbbaa

Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

Nested field: Subtitle.styles.activeWord.radius

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 200.

Type: number.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

anyOf alternative 2

Pattern: \{\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.(?:[A-Za-z][A-Za-z0-9_]*|[0-9]+))*\s*\}\}.

Type: string.

oneOf alternative 1

Required properties: src.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"captions"
]
}
}

oneOf alternative 2

Required properties: captions.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"src"
]
}
}

Additional JSON Schema constraints:

{
"dependentSchemas": {
"styles": {
"properties": {
"animation": false,
"direction": false,
"font": false,
"stroke": false,
"background": false,
"activeWord": false,
"position": false,
"margin": false
}
}
}
}
RenderOverrides

Output knobs applied after template/variable resolution.

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
RenderOverrides.namestringNoMaximum length: 1000.
RenderOverrides.widthintegerNoMinimum: 1.
RenderOverrides.heightintegerNoMinimum: 1.
RenderOverrides.outputFormatstringNomp4/mov/avi/webm for video; png/jpg/jpeg/webp for image renders.
RenderOverrides.frameRateintegerNoMinimum: 1. Maximum: 60.
RenderOverrides.backgroundColorstringNo
RenderOverrides.snapshotTimenumberNoImage renders only. Minimum: 0.
RenderOverrides.qualityintegerNoImage renders only (jpg/webp). Minimum: 1. Maximum: 100.
RenderOverrides.transparentbooleanNoImage renders only (png/webp).
RenderOverrides.resolutionstringNoResolution preset. Explicit width/height overrides force custom unless resolution is also provided.
ValidationResult

Required properties: valid, creditsRequired, payload, warnings, schemaVersion.

FieldTypeRequiredDescription and constraints
ValidationResult.validtrueYes
ValidationResult.messagestringNo
ValidationResult.creditsRequiredintegerYes
ValidationResult.payloadResolvedRenderPayloadYes
ValidationResult.warningsarray of objectYes
ValidationResult.schemaVersionstringYes

Nested field: ValidationResult.warnings

Array item: ValidationResult.warnings[]

Type: object.

ResolvedRenderPayload

A project after variable substitution, iteration and conditions. Account-specific ceilings and semantic rules are checked by POST /api/render/validate/api-key. This portable schema does not imply entitlement to any resolution, duration or element count.

Unknown properties are rejected. All listed constraints apply.

FieldTypeRequiredDescription and constraints
ResolvedRenderPayload.type"video" / "image"NoRender type. "image" produces a still (png/jpg/webp) and forbids all time-domain fields. Default: "video".
ResolvedRenderPayload.namestringNoOutput name. Letters, digits, space, _ and - ONLY (no punctuation). Default: "unnamed". Maximum length: 1000. Pattern: ^[a-zA-Z0-9_\- ]+$.
ResolvedRenderPayload.resolution"sd" / "hd" / "full-hd" / "squared" / "youtube-short" / "youtube-video" / "tiktok" / "instagram-reel" / "instagram-post" / "instagram-story" / "instagram-feed" / "twitter-landscape" / "twitter-portrait" / "twitter-square" / "facebook-video" / "facebook-story" / "facebook-post" / "snapchat" / "custom"NoCanvas preset. Any value except "custom" OVERRIDES width/height.
ResolvedRenderPayload.widthintegerNoCanvas width in px (plan-limited). Default: 1280. Minimum: 1.
ResolvedRenderPayload.heightintegerNoCanvas height in px (plan-limited). Default: 720. Minimum: 1.
ResolvedRenderPayload.durationnumberNoVideo length in seconds (plan-limited). With durationMode auto this is an optional minimum. Scene projects always include the full scene sequence. Default: 10. Minimum: 0.1.
ResolvedRenderPayload.durationMode"auto" / "fixed"NoAuto derives length from scenes, explicit element ends and captions. Supply videoEnd/exitEnd and audioEnd/exit for API submission. Omit to preserve legacy timing.
ResolvedRenderPayload.frameRateintegerNoFrames per second. Default: 30. Minimum: 1. Maximum: 60.
ResolvedRenderPayload.outputFormat"mp4" / "mov" / "avi" / "webm" / "png" / "jpg" / "jpeg" / "webp"NoVideos: mp4 (default), mov, avi, webm. Images (type: "image"): png (default), jpg, jpeg, webp.
ResolvedRenderPayload.backgroundColorstringNoCanvas background color. Default: "#ffffff". Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.
ResolvedRenderPayload.snapshotTimenumberNoImage renders only: second of the (virtual) timeline to snapshot. Minimum: 0. Maximum: 3600.
ResolvedRenderPayload.qualityintegerNoImage renders only: jpg/webp quality (NOT valid for png). Minimum: 1. Maximum: 100.
ResolvedRenderPayload.transparentbooleanNoImage renders only: transparent background (png/webp only, not jpg).
ResolvedRenderPayload.visualsarray of ResolvedVisualNoElements shown for the whole project (outside scenes).
ResolvedRenderPayload.audiosarray of ResolvedAudioItemNoProject-level audio tracks (video only, plan-limited count).
ResolvedRenderPayload.scenesarray of ResolvedSceneNoSequential timeline segments (video only, plan-limited count).
ResolvedRenderPayload.thumbnailstringNoCustom thumbnail image URL (video only). Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs. Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.
ResolvedRenderPayload.subtitleResolvedSubtitleNo

Nested field: ResolvedRenderPayload.visuals

Elements shown for the whole project (outside scenes).

Array item: ResolvedRenderPayload.visuals[]

Schema: ResolvedVisual.

Nested field: ResolvedRenderPayload.audios

Project-level audio tracks (video only, plan-limited count).

Array item: ResolvedRenderPayload.audios[]

Schema: ResolvedAudioItem.

Nested field: ResolvedRenderPayload.scenes

Sequential timeline segments (video only, plan-limited count).

Array item: ResolvedRenderPayload.scenes[]

Schema: ResolvedScene.

allOf alternative 1

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
}
},
"required": [
"type"
]
},
"then": {
"properties": {
"duration": false,
"durationMode": false,
"frameRate": false,
"audios": false,
"scenes": false,
"thumbnail": false,
"subtitle": false,
"outputFormat": {
"enum": [
"png",
"jpg",
"jpeg",
"webp"
],
"default": "png"
},
"visuals": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/ResolvedImageVisual"
},
{
"$ref": "#/components/schemas/ResolvedTextVisual"
},
{
"$ref": "#/components/schemas/ResolvedSvgVisual"
}
]
}
}
}
},
"else": {
"properties": {
"snapshotTime": false,
"quality": false,
"transparent": false,
"outputFormat": {
"enum": [
"mp4",
"mov",
"avi",
"webm"
],
"default": "mp4"
}
}
}
}

allOf alternative 2

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
},
"outputFormat": {
"enum": [
"png"
]
}
},
"required": [
"type",
"outputFormat"
]
},
"then": {
"properties": {
"quality": false
}
}
}

allOf alternative 3

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
}
},
"required": [
"type"
],
"not": {
"required": [
"outputFormat"
]
}
},
"then": {
"properties": {
"quality": false
}
}
}

allOf alternative 4

Type: any JSON value.

Additional JSON Schema constraints:

{
"if": {
"properties": {
"type": {
"const": "image"
},
"outputFormat": {
"enum": [
"jpg",
"jpeg"
]
}
},
"required": [
"type",
"outputFormat"
]
},
"then": {
"properties": {
"transparent": {
"const": false
}
}
}
}
ResolvedVisual

One canvas element, discriminated by type (IMAGE | VIDEO | GIF | SVG | TEXT, case-insensitive).

Required properties: type. Exactly one of the listed alternatives must match.

oneOf alternative 1

Schema: ResolvedImageVisual.

oneOf alternative 2

Schema: ResolvedVideoVisual.

oneOf alternative 3

Schema: ResolvedGifVisual.

oneOf alternative 4

Schema: ResolvedSvgVisual.

oneOf alternative 5

Schema: ResolvedTextVisual.

ResolvedImageVisual

A raster image placed on the canvas.

Unknown properties are rejected. Required properties: type, src.

FieldTypeRequiredDescription and constraints
ResolvedImageVisual.typestringYes"IMAGE" (case-insensitive). Pattern: ^[Ii][Mm][Aa][Gg][Ee]$.
ResolvedImageVisual.xnumberNoAnchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedImageVisual.ynumberNoAnchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedImageVisual.widthnumberNoElement width in px (plan-limited). Minimum: 1.
ResolvedImageVisual.heightnumberNoElement height in px (plan-limited). Minimum: 1.
ResolvedImageVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoPlacement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.
ResolvedImageVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoWhich point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).
ResolvedImageVisual.resize"contain" / "cover"NoHow media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.
ResolvedImageVisual.enterBeginnumberNoSeconds when the element starts appearing (enter animation start). Minimum: 0.
ResolvedImageVisual.enterEndnumberNoSeconds when the enter animation finishes. Must be >= enterBegin. Minimum: 0.
ResolvedImageVisual.exitBeginnumberNoSeconds when the exit animation starts. Minimum: 0.
ResolvedImageVisual.exitEndnumberNoSeconds when the element is fully gone. Must be >= exitBegin. Minimum: 0.
ResolvedImageVisual.opacitynumberNoElement opacity, 0..1. Minimum: 0. Maximum: 1.
ResolvedImageVisual.anglenumberNoRotation in degrees. Minimum: -360. Maximum: 360.
ResolvedImageVisual.flipVbooleanNoFlip vertically.
ResolvedImageVisual.flipHbooleanNoFlip horizontally.
ResolvedImageVisual.trackintegerNoZ-order track; higher tracks render on top. Minimum: 0. Maximum: 1000000.
ResolvedImageVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoEnter animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedImageVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoExit animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedImageVisual.srcstringYesSource media URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs. Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.
ResolvedImageVisual.cropParamsResolvedCropParamsNo
ResolvedImageVisual.filterResolvedFilterNo
ResolvedImageVisual.chromaKeyResolvedChromaKeyNo
ResolvedImageVisual.zoomResolvedZoomNo
ResolvedImageVisual.radiusResolvedRadiusNo

Nested field: ResolvedImageVisual.enterAnimation

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

Nested field: ResolvedImageVisual.exitAnimation

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

ResolvedCropParams

Source crop rectangle in source-media pixels.

Unknown properties are rejected. Required properties: x, y, width, height.

FieldTypeRequiredDescription and constraints
ResolvedCropParams.xnumberYesMinimum: 0.
ResolvedCropParams.ynumberYesMinimum: 0.
ResolvedCropParams.widthnumberYesMinimum: 1.
ResolvedCropParams.heightnumberYesMinimum: 1.
ResolvedFilter

CSS-like color filters.

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedFilter.brightnessnumberNoMinimum: -100. Maximum: 100.
ResolvedFilter.contrastnumberNoMinimum: -100. Maximum: 100.
ResolvedFilter.saturatenumberNoMinimum: -100. Maximum: 100.
ResolvedFilter.hue-rotatestringNoDegrees, preferably with a "deg" suffix (e.g. "90deg"). Legacy numeric strings such as "90" remain accepted. Pattern: ^-?(?:\d+(?:\.\d+)?|\.\d+)(?:deg)?$.
ResolvedFilter.blurnumber OR stringNoUnitless 0..100 amount. Numeric strings remain accepted for backward compatibility; CSS lengths such as 4px are not supported. At least one listed alternative must match.
ResolvedFilter.invertboolean OR numberNoBoolean or partial inversion amount from 0 to 1. At least one listed alternative must match.
ResolvedFilter.colorTintstringNoTint color (#rgb or #rrggbb). Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.

Nested field: ResolvedFilter.blur

Unitless 0..100 amount. Numeric strings remain accepted for backward compatibility; CSS lengths such as 4px are not supported.

At least one listed alternative must match.

anyOf alternative 1

Minimum: 0. Maximum: 100.

Type: number.

anyOf alternative 2

Pattern: ^(?:0*(?:100(?:\.0+)?|\d{1,2}(?:\.\d+)?|\.\d+))$.

Type: string.

Nested field: ResolvedFilter.invert

Boolean or partial inversion amount from 0 to 1.

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Minimum: 0. Maximum: 1.

Type: number.

ResolvedChromaKey

Green-screen keying.

Unknown properties are rejected. Required properties: color.

FieldTypeRequiredDescription and constraints
ResolvedChromaKey.colorstringYesKey color to remove (required). Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.
ResolvedChromaKey.similaritynumberNoMinimum: 0. Maximum: 100.
ResolvedChromaKey.blendnumberNoMinimum: 0. Maximum: 100.
ResolvedZoom

Ken Burns zoom: true (default 1.2x depth) or { "depth": 1..10 }.

At least one listed alternative must match.

anyOf alternative 1

Type: boolean.

anyOf alternative 2

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedZoom.depthnumberNoMinimum: 1. Maximum: 10.
ResolvedRadius

Rounded-corner radii in px (tl/tr/bl/br).

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedRadius.tlnumberNoMinimum: 0.
ResolvedRadius.trnumberNoMinimum: 0.
ResolvedRadius.blnumberNoMinimum: 0.
ResolvedRadius.brnumberNoMinimum: 0.
ResolvedVideoVisual

A video clip placed on the canvas (video projects only).

Unknown properties are rejected. Required properties: type, src.

FieldTypeRequiredDescription and constraints
ResolvedVideoVisual.typestringYes"VIDEO" (case-insensitive). Pattern: ^[Vv][Ii][Dd][Ee][Oo]$.
ResolvedVideoVisual.xnumberNoAnchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedVideoVisual.ynumberNoAnchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedVideoVisual.widthnumberNoElement width in px (plan-limited). Minimum: 1.
ResolvedVideoVisual.heightnumberNoElement height in px (plan-limited). Minimum: 1.
ResolvedVideoVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoPlacement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.
ResolvedVideoVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoWhich point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).
ResolvedVideoVisual.resize"contain" / "cover"NoHow media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.
ResolvedVideoVisual.enterBeginnumberNoSeconds when the element starts appearing (enter animation start). Minimum: 0.
ResolvedVideoVisual.enterEndnumberNoSeconds when the enter animation finishes. Must be >= enterBegin. Minimum: 0.
ResolvedVideoVisual.exitBeginnumberNoSeconds when the exit animation starts. Minimum: 0.
ResolvedVideoVisual.exitEndnumberNoSeconds when the element is fully gone. Must be >= exitBegin. Minimum: 0.
ResolvedVideoVisual.opacitynumberNoElement opacity, 0..1. Minimum: 0. Maximum: 1.
ResolvedVideoVisual.anglenumberNoRotation in degrees. Minimum: -360. Maximum: 360.
ResolvedVideoVisual.flipVbooleanNoFlip vertically.
ResolvedVideoVisual.flipHbooleanNoFlip horizontally.
ResolvedVideoVisual.trackintegerNoZ-order track; higher tracks render on top. Minimum: 0. Maximum: 1000000.
ResolvedVideoVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoEnter animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedVideoVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoExit animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedVideoVisual.srcstringYesSource media URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs. Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.
ResolvedVideoVisual.cropParamsResolvedCropParamsNo
ResolvedVideoVisual.filterResolvedFilterNo
ResolvedVideoVisual.chromaKeyResolvedChromaKeyNo
ResolvedVideoVisual.zoomResolvedZoomNo
ResolvedVideoVisual.radiusResolvedRadiusNo
ResolvedVideoVisual.videoBeginnumberNoTrim: source time (s) where playback starts. Minimum: 0.
ResolvedVideoVisual.videoEndnumberNoTrim: source time (s) where playback ends. Minimum: 0.
ResolvedVideoVisual.videoDurationnumberNoPlay only this many seconds of the source. Minimum: 0.1.
ResolvedVideoVisual.volumenumberNoClip audio volume, 0..2 (1 = original level). Minimum: 0. Maximum: 2.
ResolvedVideoVisual.speednumberNoPlayback speed multiplier, 0.1..10. Minimum: 0.1. Maximum: 10.
ResolvedVideoVisual.transition"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoTransition into the linked clip (see transitionId). At least one listed alternative must match.
ResolvedVideoVisual.transitionDurationnumberNoTransition length in seconds. Minimum: 0.
ResolvedVideoVisual.transitionIdstringNoid of the clip this transition links to. Maximum length: 100. Pattern: ^[a-zA-Z0-9_-]+$.
ResolvedVideoVisual.frameRateintegerNoOverride source frame rate (1..60). Minimum: 1. Maximum: 60.
ResolvedVideoVisual.idstringNoClip id (referenced by transitionId). Pattern: ^[a-zA-Z0-9_-]+$.
ResolvedVideoVisual.hasAudiobooleanNoHint that the source has an audio stream.

Nested field: ResolvedVideoVisual.enterAnimation

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

Nested field: ResolvedVideoVisual.exitAnimation

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

Nested field: ResolvedVideoVisual.transition

Transition into the linked clip (see transitionId).

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

ResolvedGifVisual

An animated GIF placed on the canvas (video projects only).

Unknown properties are rejected. Required properties: type, src.

FieldTypeRequiredDescription and constraints
ResolvedGifVisual.typestringYes"GIF" (case-insensitive). Pattern: ^[Gg][Ii][Ff]$.
ResolvedGifVisual.xnumberNoAnchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedGifVisual.ynumberNoAnchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedGifVisual.widthnumberNoElement width in px (plan-limited). Minimum: 1.
ResolvedGifVisual.heightnumberNoElement height in px (plan-limited). Minimum: 1.
ResolvedGifVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoPlacement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.
ResolvedGifVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoWhich point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).
ResolvedGifVisual.resize"contain" / "cover"NoHow media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.
ResolvedGifVisual.enterBeginnumberNoSeconds when the element starts appearing (enter animation start). Minimum: 0.
ResolvedGifVisual.enterEndnumberNoSeconds when the enter animation finishes. Must be >= enterBegin. Minimum: 0.
ResolvedGifVisual.exitBeginnumberNoSeconds when the exit animation starts. Minimum: 0.
ResolvedGifVisual.exitEndnumberNoSeconds when the element is fully gone. Must be >= exitBegin. Minimum: 0.
ResolvedGifVisual.opacitynumberNoElement opacity, 0..1. Minimum: 0. Maximum: 1.
ResolvedGifVisual.anglenumberNoRotation in degrees. Minimum: -360. Maximum: 360.
ResolvedGifVisual.flipVbooleanNoFlip vertically.
ResolvedGifVisual.flipHbooleanNoFlip horizontally.
ResolvedGifVisual.trackintegerNoZ-order track; higher tracks render on top. Minimum: 0. Maximum: 1000000.
ResolvedGifVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoEnter animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedGifVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoExit animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedGifVisual.srcstringYesSource media URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs. Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.
ResolvedGifVisual.cropParamsResolvedCropParamsNo
ResolvedGifVisual.filterResolvedFilterNo
ResolvedGifVisual.chromaKeyResolvedChromaKeyNo
ResolvedGifVisual.zoomResolvedZoomNo
ResolvedGifVisual.radiusResolvedRadiusNo

Nested field: ResolvedGifVisual.enterAnimation

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

Nested field: ResolvedGifVisual.exitAnimation

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

ResolvedSvgVisual

Inline SVG markup drawn on the canvas.

Unknown properties are rejected. Required properties: type, svg.

FieldTypeRequiredDescription and constraints
ResolvedSvgVisual.typestringYes"SVG" (case-insensitive). Pattern: ^[Ss][Vv][Gg]$.
ResolvedSvgVisual.xnumberNoAnchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedSvgVisual.ynumberNoAnchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedSvgVisual.widthnumberNoElement width in px (plan-limited). Minimum: 1.
ResolvedSvgVisual.heightnumberNoElement height in px (plan-limited). Minimum: 1.
ResolvedSvgVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoPlacement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.
ResolvedSvgVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoWhich point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).
ResolvedSvgVisual.resize"contain" / "cover"NoHow media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.
ResolvedSvgVisual.enterBeginnumberNoSeconds when the element starts appearing (enter animation start). Minimum: 0.
ResolvedSvgVisual.enterEndnumberNoSeconds when the enter animation finishes. Must be >= enterBegin. Minimum: 0.
ResolvedSvgVisual.exitBeginnumberNoSeconds when the exit animation starts. Minimum: 0.
ResolvedSvgVisual.exitEndnumberNoSeconds when the element is fully gone. Must be >= exitBegin. Minimum: 0.
ResolvedSvgVisual.opacitynumberNoElement opacity, 0..1. Minimum: 0. Maximum: 1.
ResolvedSvgVisual.anglenumberNoRotation in degrees. Minimum: -360. Maximum: 360.
ResolvedSvgVisual.flipVbooleanNoFlip vertically.
ResolvedSvgVisual.flipHbooleanNoFlip horizontally.
ResolvedSvgVisual.trackintegerNoZ-order track; higher tracks render on top. Minimum: 0. Maximum: 1000000.
ResolvedSvgVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoEnter animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedSvgVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoExit animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedSvgVisual.svgstringYesInline SVG markup starting with "<svg". Sanitized: no <script>/<foreignObject>/<iframe>/<object>/<embed>/<audio>/<video>, no on* event attributes, no external url()/href/src (only "#id" fragment refs), dimensions <= 4096px, no integers with 8+ digits. Minimum length: 1. Maximum length: 200000.
ResolvedSvgVisual.filterResolvedFilterNo
ResolvedSvgVisual.chromaKeyResolvedChromaKeyNo
ResolvedSvgVisual.customCodeResolvedCustomCodeNo
ResolvedSvgVisual.designerResolvedDesignerNo

Nested field: ResolvedSvgVisual.enterAnimation

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

Nested field: ResolvedSvgVisual.exitAnimation

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

ResolvedCustomCode

Sandboxed styling/animation code run inside the render browser (Design Studio). No network/filesystem/storage/navigation APIs — see validation notes.

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedCustomCode.cssstringNoMaximum length: 200000.
ResolvedCustomCode.jsstringNoMaximum length: 200000.
ResolvedCustomCode.animationDurationnumberNoSeconds the customCode animation runs (max 15). Maximum: 15. Greater than: 0.
ResolvedDesigner

Opaque Design Studio round-trip metadata (max 200k chars serialized). Never rendered; keeps 'edit design' working.

Type: object.

ResolvedTextVisual

Styled text. Provide plain text (no < or > characters) and/or limited html. At least one of text/html must be non-empty.

Unknown properties are rejected. Required properties: type. At least one listed alternative must match.

FieldTypeRequiredDescription and constraints
ResolvedTextVisual.typestringYes"TEXT" (case-insensitive). Pattern: ^[Tt][Ee][Xx][Tt]$.
ResolvedTextVisual.xnumberNoAnchor-point X in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedTextVisual.ynumberNoAnchor-point Y in canvas px (may be negative). ONLY used when position is "custom" — every other preset OVERWRITES x/y.
ResolvedTextVisual.widthnumberNoElement width in px (plan-limited). Minimum: 1.
ResolvedTextVisual.heightnumberNoElement height in px (plan-limited). Minimum: 1.
ResolvedTextVisual.position"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoPlacement preset. Sets BOTH the canvas point AND the default anchor (e.g. "bottom-center" puts the element's bottom edge flush with the frame bottom — no margin). x/y are IGNORED unless "custom". Two elements with the same preset render exactly stacked.
ResolvedTextVisual.anchor"top-left" / "top-center" / "top-right" / "center-left" / "center-center" / "center-right" / "bottom-right" / "bottom-center" / "bottom-left" / "custom"NoWhich point of the ELEMENT sits at the position point. Defaults to the position preset itself ("custom" defaults to top-left).
ResolvedTextVisual.resize"contain" / "cover"NoHow media fits its frame: contain (letterbox) or cover (center-crop). With explicit width/height the media fits INTO that box (CSS object-fit); without a box it is sized against the full canvas.
ResolvedTextVisual.enterBeginnumberNoSeconds when the element starts appearing (enter animation start). Minimum: 0.
ResolvedTextVisual.enterEndnumberNoSeconds when the enter animation finishes. Must be >= enterBegin. Minimum: 0.
ResolvedTextVisual.exitBeginnumberNoSeconds when the exit animation starts. Minimum: 0.
ResolvedTextVisual.exitEndnumberNoSeconds when the element is fully gone. Must be >= exitBegin. Minimum: 0.
ResolvedTextVisual.opacitynumberNoElement opacity, 0..1. Minimum: 0. Maximum: 1.
ResolvedTextVisual.anglenumberNoRotation in degrees. Minimum: -360. Maximum: 360.
ResolvedTextVisual.flipVbooleanNoFlip vertically.
ResolvedTextVisual.flipHbooleanNoFlip horizontally.
ResolvedTextVisual.trackintegerNoZ-order track; higher tracks render on top. Minimum: 0. Maximum: 1000000.
ResolvedTextVisual.enterAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoEnter animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedTextVisual.exitAnimation"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoExit animation effect (xfade family) or null. At least one listed alternative must match.
ResolvedTextVisual.textstringNoPlain text content. HTML markup (< or >) is rejected — use html for markup. Maximum length: 20000.
ResolvedTextVisual.htmlstringNoLimited HTML. Allowed tags: b, strong, i, em, u, s, br, span, div, p, ul, ol, li, img, canvas, svg (+ svg geometry). Allowed attributes: style, class, src, alt, width, height. No <script>/<style>, no event handlers, no external CSS url(). Maximum length: 200000.
ResolvedTextVisual.styleobjectNoCSS style object applied to the text container (camelCase or kebab-case keys, and --custom-properties). LAYOUT MODEL: the container uses box-sizing: content-box, so padding/border render OUTSIDE the declared width/height and overflow gets cut — for cards/pills set the full size via width/height and center content with display:flex + alignItems:center + justifyContent:center instead of padding. Text sits at the TOP of the box unless flex-centered. Values must not contain url(), @import, expression(), comments or other dangerous tokens. Max value length 4000 chars. Maximum properties: 120.
ResolvedTextVisual.fitToBoxbooleanNoScale the typography down just enough that the painted text stays inside the declared width/height instead of being clipped at the element's edge. No effect when the content already fits, so an unchanged template renders identically.
ResolvedTextVisual.customCodeResolvedCustomCodeNo
ResolvedTextVisual.designerResolvedDesignerNo

Nested field: ResolvedTextVisual.enterAnimation

Enter animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

Nested field: ResolvedTextVisual.exitAnimation

Exit animation effect (xfade family) or null.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

anyOf alternative 1

Required properties: text.

FieldTypeRequiredDescription and constraints
ResolvedTextVisual.textstringYesPattern: \S.

anyOf alternative 2

Required properties: html.

FieldTypeRequiredDescription and constraints
ResolvedTextVisual.htmlstringYesPattern: \S.
ResolvedAudioItem

A soundtrack / voice-over entry for audios (video projects only).

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedAudioItem.srcstringNoAudio file URL (mp3/wav/...). Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs. Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.
ResolvedAudioItem.matchDurationbooleanNoFollow the containing scene/project length without extending automatic duration. Overrides exit.
ResolvedAudioItem.enternumberNoTimeline second the audio starts playing. Minimum: 0.
ResolvedAudioItem.exitnumberNoTimeline second the audio stops. Must be >= enter. Minimum: 0.
ResolvedAudioItem.volumenumberNoMinimum: 0. Maximum: 2.
ResolvedAudioItem.speednumberNoMinimum: 0.1. Maximum: 10.
ResolvedAudioItem.audioBeginnumberNoTrim: source second where playback starts. Minimum: 0.
ResolvedAudioItem.audioEndnumberNoTrim: source second where playback ends. Must be >= audioBegin. Minimum: 0.
ResolvedAudioItem.audioDurationnumberNoPlay only this many seconds of the source. Minimum: 0.
ResolvedAudioItem.trackintegerNoMix track index; audio tracks mix together. Minimum: 0. Maximum: 1000000.
ResolvedScene

A timeline segment. Scenes play sequentially; a scene's transition blends into the NEXT scene (xfade overlap is subtracted from the total duration).

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedScene.idstringNoOptional scene ID. Explicit IDs must be unique within the project. Maximum length: 100. Pattern: ^[a-zA-Z0-9_-]+$.
ResolvedScene.duration-1 OR numberNoSeconds; -1 (or omitted) auto-computes from the scene's content. At least one listed alternative must match.
ResolvedScene.transition"fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown" OR nullNoTransition into the next scene. At least one listed alternative must match.
ResolvedScene.transitionIdstring OR nullNoAt least one listed alternative must match.
ResolvedScene.transitionDurationnumberNoTransition overlap in seconds (default 0.5). Minimum: 0. Maximum: 60.
ResolvedScene.backgroundColorstringNoScene background (#rgb or #rrggbb). Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$.
ResolvedScene.visualsarray of ResolvedVisualNo
ResolvedScene.audiosarray of ResolvedAudioItemNo

Nested field: ResolvedScene.duration

Seconds; -1 (or omitted) auto-computes from the scene's content.

At least one listed alternative must match.

anyOf alternative 1

Type: -1.

anyOf alternative 2

Minimum: 0.1.

Type: number.

Nested field: ResolvedScene.transition

Transition into the next scene.

At least one listed alternative must match.

anyOf alternative 1

Type: "fade" / "fadeblack" / "fadewhite" / "distance" / "wipeleft" / "wiperight" / "wipeup" / "wipedown" / "slideleft" / "slideright" / "slideup" / "slidedown" / "smoothleft" / "smoothright" / "smoothup" / "smoothdown" / "circlecrop" / "rectcrop" / "circleclose" / "circleopen" / "horzclose" / "horzopen" / "vertclose" / "vertopen" / "diagbl" / "diagbr" / "diagtl" / "diagtr" / "hlslice" / "hrslice" / "vuslice" / "vdslice" / "dissolve" / "pixelize" / "radial" / "hblur" / "wipetl" / "wipetr" / "wipebl" / "wipebr" / "fadegrays" / "zoomin" / "hlwind" / "hrwind" / "squeezeh" / "squeezev" / "fadefast" / "fadeslow" / "vuwind" / "vdwind" / "coverleft" / "coverright" / "coverup" / "coverdown" / "revealleft" / "revealright" / "revealup" / "revealdown".

anyOf alternative 2

Type: null.

Nested field: ResolvedScene.transitionId

At least one listed alternative must match.

anyOf alternative 1

Maximum length: 100. Pattern: ^[a-zA-Z0-9_-]+$.

Type: string.

anyOf alternative 2

Type: null.

Nested field: ResolvedScene.visuals

Array item: ResolvedScene.visuals[]

Schema: ResolvedVisual.

Nested field: ResolvedScene.audios

Array item: ResolvedScene.audios[]

Schema: ResolvedAudioItem.

ResolvedSubtitle

Burned-in subtitles. Content: EXACTLY ONE of src (SRT/VTT URL) or captions. Style: v2 flat keys (animation/font/stroke/background/...) OR the legacy styles block — not both.

Unknown properties are rejected. Exactly one of the listed alternatives must match.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.srcstringNoSRT or VTT file URL. Must be a PUBLIC http(s) URL: no credentials, no spaces/backslashes, port 80/443 only, no localhost/.local, no private IPs. Minimum length: 1. Maximum length: 2048. Pattern: ^https?://.
ResolvedSubtitle.captionsarray of any JSON value OR any JSON valueNoInline captions (plan-limited count). Minimum items: 1.
ResolvedSubtitle.maxWordsPerLineintegerNoRe-chunk captions to at most N words per line. Minimum: 1. Maximum: 20.
ResolvedSubtitle.animation"normal" / "none" / "one-word" / "karaoke" / "progressive" / "highlight" / "fill" / "pop" / "bounce" / "fade" / "slide" / "typewriter"NoCaption animation mode.
ResolvedSubtitle.direction"up" / "down" / "left" / "right"NoSlide direction when animation is "slide".
ResolvedSubtitle.fontobjectNoMinimum properties: 1. Unknown properties are rejected.
ResolvedSubtitle.strokeobjectNoUnknown properties are rejected. Required properties: color, width.
ResolvedSubtitle.backgroundobjectNoMinimum properties: 1. Unknown properties are rejected.
ResolvedSubtitle.activeWordobjectNoHighlight styling for the currently spoken word. Minimum properties: 1. Unknown properties are rejected.
ResolvedSubtitle.position"top-left" / "top-center" / "top-right" / "bottom-left" / "bottom-center" / "bottom-right" / "center-center" / "center-left" / "center-right" / "top" / "center" / "bottom"No
ResolvedSubtitle.marginobjectNoMinimum properties: 1. Unknown properties are rejected.
ResolvedSubtitle.stylesobjectNoLEGACY style block — prefer the flat v2 keys. Cannot be combined with them. Unknown properties are rejected.

Nested field: ResolvedSubtitle.captions

Inline captions (plan-limited count).

Minimum items: 1.

Array item: ResolvedSubtitle.captions[]

Unknown properties are rejected. Required properties: start, end. At least one listed alternative must match.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.captions[].startnumberYesCaption start time in seconds. Minimum: 0.
ResolvedSubtitle.captions[].endnumberYesCaption end time in seconds. Minimum: 0.
ResolvedSubtitle.captions[].textstringNoMinimum length: 1. Maximum length: 1000.
ResolvedSubtitle.captions[].wordsarray of objectNoPer-word timings; auto-distributed from text when omitted. Minimum items: 1.

Nested field: ResolvedSubtitle.captions[].words

Per-word timings; auto-distributed from text when omitted.

Minimum items: 1.

Array item: ResolvedSubtitle.captions[].words[]

Unknown properties are rejected. Required properties: start, end, text.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.captions[].words[].startnumberYesMinimum: 0.
ResolvedSubtitle.captions[].words[].endnumberYesMinimum: 0.
ResolvedSubtitle.captions[].words[].textstringYesMinimum length: 1. Maximum length: 100.

anyOf alternative 1

Required properties: text.

Type: any JSON value.

anyOf alternative 2

Required properties: words.

Type: any JSON value.

Nested field: ResolvedSubtitle.font

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.font.familystringNoMaximum length: 1000. Pattern: ^[a-zA-Z0-9_\- ]+$.
ResolvedSubtitle.font.sizenumberNoMinimum: 1. Maximum: 1000.
ResolvedSubtitle.font.colorstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.font.boldbooleanNo
ResolvedSubtitle.font.italicbooleanNo
ResolvedSubtitle.font.transform"uppercase" / "lowercase" / "capitalize"No

Nested field: ResolvedSubtitle.stroke

Unknown properties are rejected. Required properties: color, width.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.stroke.colorstringYes#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.stroke.widthnumberYesMinimum: 0. Maximum: 100.

Nested field: ResolvedSubtitle.background

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.background.colorstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.background.opacitynumberNoMinimum: 0. Maximum: 1.
ResolvedSubtitle.background.paddingnumberNoMinimum: 0. Maximum: 200.
ResolvedSubtitle.background.radiusnumberNoMinimum: 0. Maximum: 200.

Nested field: ResolvedSubtitle.activeWord

Highlight styling for the currently spoken word.

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.activeWord.colorstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.activeWord.backgroundstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.activeWord.radiusnumberNoMinimum: 0. Maximum: 200.

Nested field: ResolvedSubtitle.margin

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.margin.xintegerNoMinimum: 0.
ResolvedSubtitle.margin.yintegerNoMinimum: 0.

Nested field: ResolvedSubtitle.styles

LEGACY style block — prefer the flat v2 keys. Cannot be combined with them.

Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.styles.colorstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.styles.backgroundstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.styles.backgroundPaddingnumberNoMinimum: 0. Maximum: 200.
ResolvedSubtitle.styles.backgroundRadiusnumberNoMinimum: 0. Maximum: 200.
ResolvedSubtitle.styles.isBoldbooleanNo
ResolvedSubtitle.styles.isItalicbooleanNo
ResolvedSubtitle.styles.fontSizenumberNoMinimum: 1. Maximum: 1000.
ResolvedSubtitle.styles.fontFamilystringNoMaximum length: 1000. Pattern: ^[a-zA-Z0-9_\- ]+$.
ResolvedSubtitle.styles.textTransform"uppercase" / "lowercase" / "capitalize"No
ResolvedSubtitle.styles.outlineobjectNoUnknown properties are rejected. Required properties: width, color.
ResolvedSubtitle.styles.position"top-left" / "top-center" / "top-right" / "bottom-left" / "bottom-center" / "bottom-right" / "center-center" / "center-left" / "center-right"No
ResolvedSubtitle.styles.marginVintegerNoMinimum: 0.
ResolvedSubtitle.styles.marginHintegerNoMinimum: 0.
ResolvedSubtitle.styles.mode"normal" / "none" / "one-word" / "karaoke" / "progressive" / "highlight" / "fill" / "pop" / "bounce" / "fade" / "slide" / "typewriter"No
ResolvedSubtitle.styles.slideDirection"up" / "down" / "left" / "right"No
ResolvedSubtitle.styles.activeWordobjectNoMinimum properties: 1. Unknown properties are rejected.

Nested field: ResolvedSubtitle.styles.outline

Unknown properties are rejected. Required properties: width, color.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.styles.outline.widthnumberYesMinimum: 0. Maximum: 100.
ResolvedSubtitle.styles.outline.colorstringYes#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.

Nested field: ResolvedSubtitle.styles.activeWord

Minimum properties: 1. Unknown properties are rejected.

FieldTypeRequiredDescription and constraints
ResolvedSubtitle.styles.activeWord.colorstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.styles.activeWord.backgroundstringNo#rrggbb or #rrggbbaa Pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$.
ResolvedSubtitle.styles.activeWord.radiusnumberNoMinimum: 0. Maximum: 200.

oneOf alternative 1

Required properties: src.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"captions"
]
}
}

oneOf alternative 2

Required properties: captions.

Type: any JSON value.

Additional JSON Schema constraints:

{
"not": {
"required": [
"src"
]
}
}

Additional JSON Schema constraints:

{
"dependentSchemas": {
"styles": {
"properties": {
"animation": false,
"direction": false,
"font": false,
"stroke": false,
"background": false,
"activeWord": false,
"position": false,
"margin": false
}
}
}
}
ValidationError

Required properties: error.

FieldTypeRequiredDescription and constraints
ValidationError.errorstringYes
ValidationError.messagestringNo
ValidationError.detailsarray of objectNo
ValidationError.planLimitsobjectNoPresent on render validation errors; contains the authenticated user's current render limits.

Nested field: ValidationError.details

Array item: ValidationError.details[]

Unknown properties are rejected. Required properties: field, message.

FieldTypeRequiredDescription and constraints
ValidationError.details[].fieldstringYes
ValidationError.details[].messagestringYes
AuthenticationError

Unknown properties are rejected. Required properties: error.

FieldTypeRequiredDescription and constraints
AuthenticationError.errorstringYesError type
AuthenticationError.messagestringNoHuman-readable error message
Error

Required properties: error.

FieldTypeRequiredDescription and constraints
Error.errorstringYesError type
Error.messagestringNoHuman-readable error message