Skip to main content

Template Basics

Templates turn one project into many videos: author the design once with variables, then render it with different data every time — one render at a time or batches within your plan's item limit.

Variables and placeholders​

Declare defaults under variables and reference them with {{name}}. The following is a project payload, placed under payload in a render or template-create request:

{
"variables": {
"title": "Aurora Sneakers",
"accent": "#a78bfa",
"price": "$129"
},
"visuals": [
{
"type": "TEXT",
"html": "<div class=\"name\">{{title}}</div><div class=\"price\">{{price}}</div>",
"customCode": {
"css": ".price { color: {{accent}}; }"
}
}
]
}
  • Placeholders work in text, HTML, CSS, URLs, colors, and numeric fields.
  • {{name.path.to.field}} reaches into object and array variables ({{product.title}}, {{sizes.0}}).
  • Variables can be strings, numbers, booleans, arrays, or objects.
  • Scenes can declare their own variables block, which shadows project variables inside that scene.
  • Unresolvable placeholders are rejected at submit time with a field-level validation error — you can't accidentally ship {{title}} on screen.
  • An exact placeholder such as "{{price}}" preserves the resolved value's type; surrounding text produces a string. Validate the resolved output, especially when variables control dimensions, colors, or URLs.

Rendering with data​

Submit template or payload (never both) to the render endpoint. Request-time variables override the declared defaults:

curl -X POST https://api.zvid.io/api/render/api-key \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template": "tpl_xxxxxxxxxxxxxxxxxxxx",
"variables": { "title": "Nimbus Backpack", "accent": "#f59e0b", "price": "$89" },
"overrides": { "name": "nimbus-backpack" }
}'
  • template — a stored template id (tpl_…). Save one from the editor (Save → Save as template) or via POST /api/templates; find ids on the dashboard's Templates page.
  • variables — per-render values merged over the template's defaults.
  • overrides — output knobs applied before variable resolution: name, resolution, width, height, outputFormat, frameRate, backgroundColor, and the image-render fields (snapshotTime, quality, transparent).

You can also send a full payload containing variables — templates don't have to be stored to use placeholders.

Only the listed output fields are allowed in a render request's overrides. It cannot replace visuals, scenes, duration, or project type. Overriding width or height without a resolution switches to resolution: "custom". For stored video templates, every scene must resolve to an explicit positive duration; scene auto-fit (-1 or omitted) is not supported on this path.

Save and preview a template​

Create a template with POST /api/templates, an API key, JSON Content-Type, and a body containing name and payload. Defaults must make the template valid at save time. For example, this is a complete request body:

{
"name": "Greeting",
"payload": {
"duration": 3,
"variables": { "title": "Hello" },
"visuals": [
{ "type": "TEXT", "text": "{{title}}", "position": "center-center" }
]
}
}

Read the new ID from template.id in the create response. To inspect a new dataset without rendering or spending credits, call:

curl -X POST https://api.zvid.io/api/templates/TEMPLATE_ID/preview \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "variables": { "title": "Hello, Cairo" } }'

Replace TEMPLATE_ID with the returned tpl_… ID. Preview returns HTTP 200 with project (resolved, validated project JSON) and stats (resolution statistics). It returns no job ID or media URL. Use Validate and estimate for creditsRequired, then the render endpoint to produce media.

Same template, two datasets​

The same visual design rendered with two variable sets. These recorded fixtures include their full project settings and additional card styling:

{
"name": "docs-template-var-a",
"width": 960,
"height": 540,
"duration": 5,
"backgroundColor": "#140b2e",
"variables": {
"title": "Aurora Sneakers",
"accent": "#a78bfa",
"price": "$129"
},
"visuals": [
{
"type": "TEXT",
"html": "<div class=\"card\"><div class=\"name\">{{title}}</div><div class=\"price\">{{price}}</div></div>",
"position": "center-center",
"enterBegin": 0,
"exitEnd": 5,
"customCode": {
"css": ".card { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 40px 80px; background: rgba(255,255,255,0.06); border: 2px solid {{accent}}; border-radius: 24px; } .name { color: #ffffff; font-family: Montserrat; font-size: 56px; font-weight: 800; } .price { color: {{accent}}; font-family: Poppins; font-size: 44px; font-weight: 700; animation: pop 1.4s ease-in-out infinite; } @keyframes pop { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }",
"animationDuration": 1.4
}
}
]
}
Rendered by Zvid
variables: { "title": "Aurora Sneakers", "accent": "#a78bfa", "price": "$129" }
Watch video
{
"name": "docs-template-var-b",
"width": 960,
"height": 540,
"duration": 5,
"backgroundColor": "#140b2e",
"variables": {
"title": "Nimbus Backpack",
"accent": "#f59e0b",
"price": "$89"
},
"visuals": [
{
"type": "TEXT",
"html": "<div class=\"card\"><div class=\"name\">{{title}}</div><div class=\"price\">{{price}}</div></div>",
"position": "center-center",
"enterBegin": 0,
"exitEnd": 5,
"customCode": {
"css": ".card { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 40px 80px; background: rgba(255,255,255,0.06); border: 2px solid {{accent}}; border-radius: 24px; } .name { color: #ffffff; font-family: Montserrat; font-size: 56px; font-weight: 800; } .price { color: {{accent}}; font-family: Poppins; font-size: 44px; font-weight: 700; animation: pop 1.4s ease-in-out infinite; } @keyframes pop { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }",
"animationDuration": 1.4
}
}
]
}
Rendered by Zvid
The same template with { "title": "Nimbus Backpack", "accent": "#f59e0b", "price": "$89" }
Watch video

Template API​

EndpointAuthPurpose
GET /api/templatesJWT or API keyList your templates
POST /api/templatesJWT or API keyCreate a template from a project
GET /api/templates/{id}JWT or API keyFetch a template (inspect variables)
PUT /api/templates/{id}JWT or API keyUpdate
DELETE /api/templates/{id}JWT or API keyArchive
POST /api/templates/{id}/duplicateJWT or API keyDuplicate
POST /api/templates/{id}/previewJWT or API keyFree dry run; returns resolved project and stats

Next​