<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mina Ramzy</title>
    <description>The latest articles on DEV Community by Mina Ramzy (@mena234).</description>
    <link>https://dev.to/mena234</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F566021%2Fe3934c3b-6559-4301-bd26-3b22dbeb12c0.jpeg</url>
      <title>DEV Community: Mina Ramzy</title>
      <link>https://dev.to/mena234</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mena234"/>
    <language>en</language>
    <item>
      <title>Bulk AI Video Generation API: How to Generate 1,000 Videos</title>
      <dc:creator>Mina Ramzy</dc:creator>
      <pubDate>Tue, 09 Jun 2026 21:00:00 +0000</pubDate>
      <link>https://dev.to/mena234/bulk-ai-video-generation-api-how-to-generate-1000-videos-2m2i</link>
      <guid>https://dev.to/mena234/bulk-ai-video-generation-api-how-to-generate-1000-videos-2m2i</guid>
      <description>&lt;p&gt;To generate 1,000 videos automatically with a bulk AI video generation API workflow, start with one reusable JSON video template, map each row of source data into that template, submit one render job per output, and poll each job until it completes or fails. The important architecture is not just "send 1,000 requests." A reliable bulk video generation API workflow needs idempotent job IDs, queue-aware submission, retry rules, payload versioning, and a place to store the final render URLs.&lt;/p&gt;

&lt;p&gt;Zvid is built for the rendering layer of this pattern because each video can be described as structured JSON and submitted to &lt;code&gt;POST https://api.zvid.io/api/render/api-key&lt;/code&gt;. Your application then polls &lt;code&gt;GET https://api.zvid.io/api/jobs/{id}&lt;/code&gt; for progress and result URLs. If AI models generate scripts, prompts, reference images, or source clips upstream, Zvid can still provide the repeatable video creation endpoint that assembles approved assets into completed videos. Keep the &lt;a href="https://docs.zvid.io/docs/getting-started?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Getting Started guide&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/endpoints/submit-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Submit render job reference&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/endpoints/get-render-job" rel="noopener noreferrer"&gt;Get render job status reference&lt;/a&gt;, and &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt; open while you design the workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjao6xudx2hzhlx3vctm1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjao6xudx2hzhlx3vctm1.webp" alt="Bulk video generation API workflow for JSON video templates" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bulk video generation works best when data mapping, render submission, and job polling are separate steps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are new to JSON-driven rendering, start with &lt;a href="https://zvid.io/blog/developer-tutorials/how-to-generate-a-video-from-json?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Generate a Video from JSON&lt;/a&gt;, then compare this bulk workflow with the broader &lt;a href="https://zvid.io/blog/developer-guides/json-to-video-api-complete-guide-for-developers?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON to Video API guide&lt;/a&gt;, the feed-driven pattern in &lt;a href="https://zvid.io/blog/e-commerce-automation/how-to-create-product-videos-from-a-csv-or-product-feed?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Create Product Videos from a CSV or Product Feed&lt;/a&gt;, and the timed media model in &lt;a href="https://zvid.io/blog/developer-tutorials/how-to-add-b-roll-automatically-with-json?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Add B-roll Automatically with JSON&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The public API loop is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.zvid.io/api/render/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @render-job.json

curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bulk version of that loop adds orchestration around the API call: validate data, generate payloads, submit jobs at a controlled pace, poll active jobs, store completed URLs, and retry failures only when the failure is retryable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bulk video generation architecture
&lt;/h2&gt;

&lt;p&gt;A high-volume video workflow has five parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A data source, such as a CSV export, product feed, CRM list, campaign table, or database query.&lt;/li&gt;
&lt;li&gt;A template mapper that turns each record into a Zvid JSON payload.&lt;/li&gt;
&lt;li&gt;A submission queue that controls how many render jobs are created at once.&lt;/li&gt;
&lt;li&gt;A polling worker that checks job status and records final results.&lt;/li&gt;
&lt;li&gt;A review and delivery layer that stores URLs, thumbnails, errors, and source payload versions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvvkmx4rgatwgv2vgrhgb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvvkmx4rgatwgv2vgrhgb.webp" alt="Workflow diagram for bulk video generation with the Zvid API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Separate data mapping, queue control, rendering, polling, and delivery so each stage can be retried independently.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This architecture helps teams avoid the main failure mode in bulk rendering: losing track of which source record produced which job, which payload version was used, and whether a failure should be fixed in data, template logic, media assets, or orchestration code.&lt;/p&gt;

&lt;p&gt;For a production system, store at least the source record ID, template version, generated payload, submitted job ID, current job state, error details, completed video URL, and timestamps. That record becomes the audit trail for every generated video.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy-paste Zvid bulk render payload
&lt;/h2&gt;

&lt;p&gt;The renderable payload below demonstrates a single output from a bulk campaign. In a real 1,000-video workflow, your application would generate a variation of this payload for each source record by changing the title, audience segment, CTA, accent color, media URLs, or output format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bulk-video-generation-api-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#07111F"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='1280' height='720' viewBox='0 0 1280 720' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='bg' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#07111F'/&amp;gt;&amp;lt;stop offset='1' stop-color='#17233D'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;linearGradient id='accent' x1='0' y1='0' x2='1' y2='0'&amp;gt;&amp;lt;stop offset='0' stop-color='#2DD4BF'/&amp;gt;&amp;lt;stop offset='1' stop-color='#FADD46'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect width='1280' height='720' fill='url(#bg)'/&amp;gt;&amp;lt;rect x='64' y='70' width='1152' height='580' rx='30' fill='rgba(255,255,255,0.045)' stroke='rgba(255,255,255,0.14)'/&amp;gt;&amp;lt;text x='104' y='136' fill='#FFFFFF' font-family='Arial' font-size='32' font-weight='800'&amp;gt;Bulk render run&amp;lt;/text&amp;gt;&amp;lt;text x='104' y='176' fill='#BFC7DE' font-family='Arial' font-size='20'&amp;gt;One template becomes many API jobs&amp;lt;/text&amp;gt;&amp;lt;rect x='104' y='232' width='250' height='290' rx='24' fill='rgba(7,13,30,0.8)' stroke='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;text x='229' y='284' text-anchor='middle' fill='#2DD4BF' font-family='Arial' font-size='24' font-weight='800'&amp;gt;Data rows&amp;lt;/text&amp;gt;&amp;lt;circle cx='156' cy='340' r='14' fill='#2DD4BF'/&amp;gt;&amp;lt;rect x='190' y='326' width='110' height='16' rx='8' fill='rgba(255,255,255,0.35)'/&amp;gt;&amp;lt;circle cx='156' cy='394' r='14' fill='#2DD4BF'/&amp;gt;&amp;lt;rect x='190' y='380' width='128' height='16' rx='8' fill='rgba(255,255,255,0.35)'/&amp;gt;&amp;lt;circle cx='156' cy='448' r='14' fill='#2DD4BF'/&amp;gt;&amp;lt;rect x='190' y='434' width='92' height='16' rx='8' fill='rgba(255,255,255,0.35)'/&amp;gt;&amp;lt;rect x='456' y='232' width='310' height='290' rx='24' fill='rgba(7,13,30,0.8)' stroke='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;text x='611' y='284' text-anchor='middle' fill='#FADD46' font-family='Arial' font-size='24' font-weight='800'&amp;gt;JSON template&amp;lt;/text&amp;gt;&amp;lt;rect x='502' y='326' width='218' height='18' rx='9' fill='rgba(250,221,70,0.4)'/&amp;gt;&amp;lt;rect x='502' y='366' width='168' height='18' rx='9' fill='rgba(255,255,255,0.25)'/&amp;gt;&amp;lt;rect x='502' y='406' width='204' height='18' rx='9' fill='rgba(255,255,255,0.25)'/&amp;gt;&amp;lt;rect x='868' y='232' width='270' height='290' rx='24' fill='rgba(7,13,30,0.8)' stroke='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;text x='1003' y='284' text-anchor='middle' fill='#FFFFFF' font-family='Arial' font-size='24' font-weight='800'&amp;gt;Render queue&amp;lt;/text&amp;gt;&amp;lt;rect x='912' y='326' width='184' height='42' rx='14' fill='rgba(45,212,191,0.18)' stroke='rgba(45,212,191,0.55)'/&amp;gt;&amp;lt;rect x='912' y='388' width='184' height='42' rx='14' fill='rgba(250,221,70,0.16)' stroke='rgba(250,221,70,0.5)'/&amp;gt;&amp;lt;rect x='912' y='450' width='184' height='42' rx='14' fill='rgba(255,255,255,0.12)' stroke='rgba(255,255,255,0.24)'/&amp;gt;&amp;lt;path d='M370 376 H428' stroke='url(#accent)' stroke-width='8' stroke-linecap='round'/&amp;gt;&amp;lt;path d='M782 376 H840' stroke='url(#accent)' stroke-width='8' stroke-linecap='round'/&amp;gt;&amp;lt;rect x='246' y='574' width='788' height='36' rx='18' fill='rgba(255,255,255,0.1)'/&amp;gt;&amp;lt;rect x='246' y='574' width='560' height='36' rx='18' fill='url(#accent)'/&amp;gt;&amp;lt;text x='640' y='638' text-anchor='middle' fill='#C8D2F1' font-family='Arial' font-size='18'&amp;gt;Submit, poll, store, retry only when needed&amp;lt;/text&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3c2p2q1m0qu2dj5roeh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3c2p2q1m0qu2dj5roeh.webp" alt="Zvid JSON payload visual for bulk video generation API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The payload visual is generated from the real renderable bulk workflow example.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the public render endpoint, wrap the project inside a top-level &lt;code&gt;payload&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bulk-video-generation-api-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the API workflow works
&lt;/h2&gt;

&lt;p&gt;In a single render, your application builds one payload, submits it, and polls one job. In bulk rendering, the same steps happen many times, so the orchestration layer matters as much as the payload.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkii88aa5asko6g42bkxi.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkii88aa5asko6g42bkxi.webp" alt="Systems diagram for bulk video rendering queue and polling" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A bulk renderer should keep source records, payloads, job IDs, and final URLs connected.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A practical implementation looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read a batch of source records from your database, CSV, CMS, or product feed.&lt;/li&gt;
&lt;li&gt;Normalize values so every record has safe text, color, media URL, and timing fields.&lt;/li&gt;
&lt;li&gt;Generate one Zvid payload per record using a versioned template.&lt;/li&gt;
&lt;li&gt;Submit jobs through the render endpoint at a controlled concurrency.&lt;/li&gt;
&lt;li&gt;Store each returned &lt;code&gt;jobId&lt;/code&gt; next to the source record and payload version.&lt;/li&gt;
&lt;li&gt;Poll the jobs endpoint until each job is &lt;code&gt;completed&lt;/code&gt; or &lt;code&gt;failed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Save &lt;code&gt;result.url&lt;/code&gt; for completed jobs and store &lt;code&gt;failedReason&lt;/code&gt; for failed jobs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This structure gives you a clean answer to the most important operational question: "What happened to this specific video?" You can trace each result from original data to payload to render job to final URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design the job queue before the template
&lt;/h2&gt;

&lt;p&gt;For high-volume video rendering, a queue is not an implementation detail. It is the control surface that protects your source systems, API usage, review process, and retry logic.&lt;/p&gt;

&lt;p&gt;The queue should know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which source record is being rendered.&lt;/li&gt;
&lt;li&gt;Which template version created the payload.&lt;/li&gt;
&lt;li&gt;Whether the job is waiting, submitted, active, completed, failed, or blocked.&lt;/li&gt;
&lt;li&gt;How many retry attempts have happened.&lt;/li&gt;
&lt;li&gt;Whether the failure came from input data, media availability, authentication, credits, rate limits, or an unexpected service error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need to submit every planned video at once. In many teams, the safer pattern is to submit a small window of jobs, poll those jobs, then submit more as capacity clears. That keeps the run observable and makes it easier to pause if the source data or template has a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build render payloads from structured data
&lt;/h2&gt;

&lt;p&gt;Bulk rendering works when every variable part of the video is explicit. A product launch video might vary title, price, product image, brand color, disclaimer text, and CTA. A sales outreach video might vary company name, region, benefit copy, chart values, and logo URL. A learning platform might vary lesson title, step number, example screenshot, and outro link.&lt;/p&gt;

&lt;p&gt;Before generating payloads, define a template contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required fields that must exist before submission.&lt;/li&gt;
&lt;li&gt;Optional fields with fallback copy or fallback visuals.&lt;/li&gt;
&lt;li&gt;Text length limits for titles, captions, and CTAs.&lt;/li&gt;
&lt;li&gt;Media URL checks for images, videos, GIFs, and audio.&lt;/li&gt;
&lt;li&gt;Output settings such as aspect ratio, duration, frame rate, and format.&lt;/li&gt;
&lt;li&gt;Naming rules for jobs and output files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That contract is what turns bulk video generation from a fragile loop into a predictable automation workflow. If a record fails the contract, do not submit it. Mark it as blocked, show the missing fields, and let the data owner fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI video generation APIs fit
&lt;/h2&gt;

&lt;p&gt;Many teams search for an AI video generation API when they need to generate videos from prompts, reference images, existing video assets, or text-to-video generation models. Those systems can be useful when the creative content itself needs to be generated. Bulk business video workflows often need a different layer: a repeatable video API that can assemble approved text, images, clips, captions, brand styles, aspect ratios, and CTAs into completed videos.&lt;/p&gt;

&lt;p&gt;That distinction matters. A prompt can help create an idea, a voiceover, an image, a short video, or a storyboard. A JSON template controls how those assets appear in a consistent output. In a high-volume workflow, you may use AI models upstream to draft copy, summarize a product, choose a visual style, or generate reference images, then use Zvid to render the final structured video through API access.&lt;/p&gt;

&lt;p&gt;For bulk rendering, focus less on one generation model and more on the workflow boundary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What data creates each video?&lt;/li&gt;
&lt;li&gt;Which assets are generated, approved, or pulled from an existing library?&lt;/li&gt;
&lt;li&gt;Which template controls layout, duration, timing, and aspect ratio?&lt;/li&gt;
&lt;li&gt;Which endpoint creates the render job?&lt;/li&gt;
&lt;li&gt;Where do completed videos, previews, thumbnails, and failures get stored?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps automation practical. Your team can improve prompts, templates, data cleanup, and review steps independently instead of treating video creation as one opaque request.&lt;/p&gt;

&lt;p&gt;For example, a text prompt might create source copy, a video generation model might create a short clip, and an image-to-video tool might create motion from reference images. Those assets still need a production workflow: choose the right aspect ratio, place captions away from key visuals, add a CTA, create a preview, and store the completed video. Zvid fits after those creative steps when your application needs to turn approved inputs into consistent outputs for TikTok-style vertical clips, square social posts, landing page videos, or internal campaign variants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Polling, retries, and failure handling
&lt;/h2&gt;

&lt;p&gt;Zvid render jobs are asynchronous, so your application should treat the initial &lt;code&gt;202&lt;/code&gt; response as the start of a workflow, not the final result. Save the returned &lt;code&gt;jobId&lt;/code&gt;, then poll the job endpoint until the state is terminal.&lt;/p&gt;

&lt;p&gt;For polling, use a steady interval and store the latest state. A simple implementation can poll every few seconds. A larger system can back off older jobs, prioritize recently submitted jobs, and stop polling after a failure or completion.&lt;/p&gt;

&lt;p&gt;Retry rules should be narrow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retry temporary network errors around your own request.&lt;/li&gt;
&lt;li&gt;Retry a job submission only if you know the first attempt did not create a job, or if you use a caller-side idempotency strategy.&lt;/li&gt;
&lt;li&gt;Do not blindly retry validation failures. Fix the generated payload or source data.&lt;/li&gt;
&lt;li&gt;Do not blindly retry missing media. Check whether the source URL is public, reachable, and intended for the render.&lt;/li&gt;
&lt;li&gt;Store failed payloads so developers can reproduce and repair the issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foukmd6bby1fbd082ucmg.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foukmd6bby1fbd082ucmg.webp" alt="Manual video batching versus bulk video generation API comparison" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bulk rendering is strongest when repeatability, audit trails, and structured variation matter more than manual timeline editing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The goal is not to hide every failure. The goal is to make failures inspectable. A good bulk pipeline lets someone answer whether the issue is bad input data, a broken media URL, an oversized text field, an expired API key, insufficient credits, or an orchestration bug.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;The most common mistake is trying to scale a one-off render script without adding state. Once you generate hundreds or thousands of videos, state is the product: source record state, payload state, job state, and delivery state.&lt;/p&gt;

&lt;p&gt;Other mistakes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Submitting every render at once without a queue window.&lt;/li&gt;
&lt;li&gt;Generating payloads from unvalidated source data.&lt;/li&gt;
&lt;li&gt;Not storing the exact payload used for each render.&lt;/li&gt;
&lt;li&gt;Reusing one layout across landscape, square, and portrait formats without checking text fit.&lt;/li&gt;
&lt;li&gt;Polling forever after a job has reached a terminal state.&lt;/li&gt;
&lt;li&gt;Retrying failures without classifying why they failed.&lt;/li&gt;
&lt;li&gt;Losing the relationship between source record, job ID, and final video URL.&lt;/li&gt;
&lt;li&gt;Treating media URLs as reliable without checking access and file type.&lt;/li&gt;
&lt;li&gt;Updating a template during a run without recording the template version.&lt;/li&gt;
&lt;li&gt;Shipping the first bulk run without reviewing a representative sample.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fix is to make the workflow boring on purpose. Validate first, submit in controlled batches, poll consistently, store outcomes, and review a sample before increasing volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to choose a bulk video generation API
&lt;/h2&gt;

&lt;p&gt;The right bulk video generation API depends on whether your team needs generative video content, template-based video automation, or both. When evaluating AI video generator API options, separate creative generation from production rendering. A generative API may focus on prompts, reference images, image-to-video generation, text-to-video generation, or video extension. A template rendering API focuses on predictable output: the same layout, timing, aspect ratio, and brand rules applied across many source records.&lt;/p&gt;

&lt;p&gt;For a high-volume workflow, evaluate the API around operations rather than demos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input model:&lt;/strong&gt; Can your application send structured data, JSON templates, media URLs, and text variables, or does every request depend on a prompt?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint behavior:&lt;/strong&gt; Does the API return a job ID for asynchronous rendering, and can your app poll or track completed videos?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication:&lt;/strong&gt; Can API key access be kept server-side, away from client UI code?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output controls:&lt;/strong&gt; Can you set duration, frame rate, output format, background color, layout, and aspect ratio for each render?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template control:&lt;/strong&gt; Can developers version the payload and reproduce the same video later?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preview and review:&lt;/strong&gt; Can your workflow store previews, thumbnails, failed payloads, and final URLs for human review?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation fit:&lt;/strong&gt; Can it integrate with your CRM, CMS, product feed, spreadsheet, database, or internal application?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is also where AI and deterministic rendering can work together. AI models can create short video clips, draft scripts, generate images, or suggest variants. Zvid can then assemble approved assets into a consistent final video through a JSON payload and render endpoint. That combination gives teams creative flexibility without giving up operational control.&lt;/p&gt;

&lt;p&gt;Do not choose video generation APIs from a demo clip alone. For bulk production, run a small batch and compare source data quality, prompt reliability, template fit, generation speeds, preview review time, failure messages, and completed video storage. The best API for one-off AI videos may not be the best API to generate videos repeatedly from a database or product feed.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use Zvid
&lt;/h2&gt;

&lt;p&gt;Use Zvid when your application needs repeatable server-side video rendering from structured JSON. It is a strong fit for e-commerce teams, agencies, marketing operations, AI video products, learning platforms, real estate workflows, internal enablement systems, and product-led growth teams that need many related video outputs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj9f9swxywcgjjidaacd.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj9f9swxywcgjjidaacd.webp" alt="Use cases for high volume video generation with Zvid" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One JSON render pipeline can power many repeatable video formats when the source data is structured.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Zvid is especially useful when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One template rendered across many records.&lt;/li&gt;
&lt;li&gt;Programmatic control over text, media, timing, layout, and output settings.&lt;/li&gt;
&lt;li&gt;Hosted render jobs with API submission and polling.&lt;/li&gt;
&lt;li&gt;A workflow that can be integrated into a CMS, CRM, product feed, internal tool, or automation platform.&lt;/li&gt;
&lt;li&gt;Reviewable JSON payloads instead of hidden timeline edits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your team needs one handcrafted flagship video, a manual editor may be the better tool. If you need hundreds of product variants, personalized clips, localized videos, listing videos, onboarding snippets, or campaign creatives, a JSON-to-video API gives your engineering team a clearer system boundary.&lt;/p&gt;

&lt;p&gt;Start with ten records, review the outputs, fix the template, then increase the queue window. Bulk video generation is easiest to scale after the template has already survived a small real batch.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a bulk video generation API?
&lt;/h3&gt;

&lt;p&gt;A bulk video generation API lets software create many videos from structured data by submitting render jobs programmatically instead of editing each video manually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is bulk video generation the same as text-to-video generation?
&lt;/h3&gt;

&lt;p&gt;Not exactly. Text-to-video generation creates video content from a prompt, while bulk video generation usually maps structured records into repeatable templates and render jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I generate 1,000 videos automatically?
&lt;/h3&gt;

&lt;p&gt;Use a reusable video template, map each source record into a JSON payload, submit one render job per output, poll each job, and store the completed video URLs next to the source records.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I submit all 1,000 render jobs at once?
&lt;/h3&gt;

&lt;p&gt;Usually no. A controlled queue window is easier to monitor, pause, and retry than a single burst of every planned job.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I store for each generated video?
&lt;/h3&gt;

&lt;p&gt;Store the source record ID, template version, generated payload, render job ID, current state, failure reason if any, final video URL, and timestamps.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do retries work in bulk video rendering?
&lt;/h3&gt;

&lt;p&gt;Retry temporary request or network failures carefully, but do not blindly retry validation errors, bad media URLs, insufficient credits, or payload bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use product feeds or CSV files for bulk video generation?
&lt;/h3&gt;

&lt;p&gt;Yes. Product feeds and CSV files are common sources because they already contain structured fields that can map into video titles, media, prices, CTAs, and styling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does every video need a different JSON payload?
&lt;/h3&gt;

&lt;p&gt;Each output should have its own payload, but the payloads can come from one reusable template. The template stays stable while the data changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  When is bulk rendering better than manual editing?
&lt;/h3&gt;

&lt;p&gt;Bulk rendering is better when the videos share a repeatable structure and differ mostly by data, media, language, offer, audience, or format.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can AI models be part of a bulk video workflow?
&lt;/h3&gt;

&lt;p&gt;Yes. AI models can help draft copy, generate source visuals, summarize records, or suggest variants, while a JSON render template controls the final video structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  What features matter in a bulk video generation API?
&lt;/h3&gt;

&lt;p&gt;Look for server-side API access, asynchronous job status, structured template inputs, output controls, aspect ratio options, preview or thumbnail storage, and clear failure reporting.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AI B-roll Generator API: Automate with JSON</title>
      <dc:creator>Mina Ramzy</dc:creator>
      <pubDate>Tue, 09 Jun 2026 21:00:00 +0000</pubDate>
      <link>https://dev.to/mena234/ai-b-roll-generator-api-automate-with-json-343i</link>
      <guid>https://dev.to/mena234/ai-b-roll-generator-api-automate-with-json-343i</guid>
      <description>&lt;p&gt;To automate B-roll with JSON, represent each supporting clip, image, or graphic as a timed visual layer with a source URL, start time, end time, position, size, resize mode, and track order. In Zvid, those B-roll assets live in the same &lt;code&gt;visuals&lt;/code&gt; array as titles, captions, overlays, and other scene elements, so your application can generate B-roll placement from scripts, product feeds, transcript cues, or editorial rules instead of editing every video by hand.&lt;/p&gt;

&lt;p&gt;The core API flow is: build the JSON payload, submit it to &lt;code&gt;POST https://api.zvid.io/api/render/api-key&lt;/code&gt;, then poll &lt;code&gt;GET https://api.zvid.io/api/jobs/{id}&lt;/code&gt; until the render completes. Keep the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/image-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Image Elements reference&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/video-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Video Elements reference&lt;/a&gt;, and &lt;a href="https://docs.zvid.io/docs/structure/transitions?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Transitions reference&lt;/a&gt; nearby while you implement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxo12qx7plk1xa513weh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxo12qx7plk1xa513weh.webp" alt="Hero image for automating B-roll with JSON and the Zvid API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;B-roll automation works best when editorial intent becomes structured timing data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are new to Zvid's render model, start with &lt;a href="https://zvid.io/blog/how-to-generate-a-video-from-json?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Generate a Video from JSON&lt;/a&gt;, then compare this B-roll workflow with the broader &lt;a href="https://zvid.io/blog/json-to-video-api-complete-guide-for-developers?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON to Video API guide&lt;/a&gt; and the product-data pattern in &lt;a href="https://zvid.io/blog/how-to-create-product-videos-from-a-csv-or-product-feed?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Create Product Videos from a CSV or Product Feed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is the public API loop most implementations need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.zvid.io/api/render/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @broll-render.json

curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The JSON model for automated B-roll
&lt;/h2&gt;

&lt;p&gt;B-roll automation is a timeline problem. Your app needs to know which media asset should appear, when it should appear, how it should fit the frame, and whether it should sit behind or above the primary story layer.&lt;/p&gt;

&lt;p&gt;In Zvid, each B-roll item can be modeled as a visual element:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IMAGE&lt;/code&gt; for product photos, screenshots, still frames, thumbnails, or generated graphics.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;VIDEO&lt;/code&gt; for short supporting clips, demonstrations, background footage, or reaction shots.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GIF&lt;/code&gt; for lightweight animated accents.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SVG&lt;/code&gt; or &lt;code&gt;TEXT&lt;/code&gt; for generated labels, callouts, diagrams, or timeline overlays.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fields that matter most for B-roll are &lt;code&gt;src&lt;/code&gt;, &lt;code&gt;enterBegin&lt;/code&gt;, &lt;code&gt;enterEnd&lt;/code&gt;, &lt;code&gt;exitBegin&lt;/code&gt;, &lt;code&gt;exitEnd&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;anchor&lt;/code&gt;, &lt;code&gt;resize&lt;/code&gt;, &lt;code&gt;track&lt;/code&gt;, &lt;code&gt;opacity&lt;/code&gt;, and the optional animation or transition fields. The &lt;a href="https://docs.zvid.io/docs/endpoints/submit-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Submit render job reference&lt;/a&gt; documents the hosted render endpoint, and the &lt;a href="https://docs.zvid.io/docs/endpoints/get-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Get render job status reference&lt;/a&gt; documents job polling after submission.&lt;/p&gt;

&lt;p&gt;For example, a production B-roll image layer can look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IMAGE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.pixabay.com/photo/2024/10/02/18/24/leaf-9091894_1280.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cover"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a short supporting clip, use &lt;code&gt;VIDEO&lt;/code&gt; with the same timeline fields and add source trimming when needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VIDEO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.pixabay.com/video/2025/06/03/283533_large.mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cover"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"videoBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"videoEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;volume: 0&lt;/code&gt; when B-roll should not override narration, voiceover, or background music. If the B-roll clip should contribute audio, keep the volume intentional and test it against the rest of the mix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy-paste Zvid B-roll timing payload
&lt;/h2&gt;

&lt;p&gt;The renderable example below uses generated SVG panels to demonstrate B-roll timing without depending on any external media URL. In a production template, replace the SVG stand-ins with &lt;code&gt;IMAGE&lt;/code&gt;, &lt;code&gt;VIDEO&lt;/code&gt;, or &lt;code&gt;GIF&lt;/code&gt; elements from your asset system while keeping the same timing and track ideas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"automate-broll-json-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#0B1020"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='1280' height='720' viewBox='0 0 1280 720' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='bg' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#0B1020'/&amp;gt;&amp;lt;stop offset='1' stop-color='#17233D'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;linearGradient id='accent' x1='0' y1='0' x2='1' y2='0'&amp;gt;&amp;lt;stop offset='0' stop-color='#2DD4BF'/&amp;gt;&amp;lt;stop offset='1' stop-color='#FADD46'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect width='1280' height='720' fill='url(#bg)'/&amp;gt;&amp;lt;rect x='64' y='46' width='1152' height='628' rx='30' fill='rgba(255,255,255,0.045)' stroke='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;rect x='104' y='184' width='420' height='286' rx='28' fill='rgba(7,13,30,0.82)' stroke='rgba(255,255,255,0.12)'/&amp;gt;&amp;lt;text x='136' y='234' fill='#FFFFFF' font-family='Arial' font-size='28' font-weight='800'&amp;gt;Primary story&amp;lt;/text&amp;gt;&amp;lt;rect x='136' y='270' width='318' height='18' rx='9' fill='rgba(255,255,255,0.18)'/&amp;gt;&amp;lt;rect x='136' y='306' width='248' height='18' rx='9' fill='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;rect x='136' y='342' width='286' height='18' rx='9' fill='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;rect x='136' y='394' width='270' height='54' rx='18' fill='rgba(45,212,191,0.13)' stroke='rgba(45,212,191,0.38)'/&amp;gt;&amp;lt;text x='271' y='428' text-anchor='middle' fill='#A7FFF6' font-family='Arial' font-size='18' font-weight='700'&amp;gt;script + narration&amp;lt;/text&amp;gt;&amp;lt;rect x='104' y='530' width='1072' height='74' rx='18' fill='rgba(0,0,0,0.28)' stroke='rgba(255,255,255,0.1)'/&amp;gt;&amp;lt;line x1='152' y1='568' x2='1128' y2='568' stroke='rgba(255,255,255,0.23)' stroke-width='8' stroke-linecap='round'/&amp;gt;&amp;lt;rect x='320' y='556' width='200' height='24' rx='12' fill='#2DD4BF'/&amp;gt;&amp;lt;rect x='572' y='556' width='220' height='24' rx='12' fill='#FADD46'/&amp;gt;&amp;lt;rect x='842' y='556' width='190' height='24' rx='12' fill='#A855F7'/&amp;gt;&amp;lt;text x='640' y='644' text-anchor='middle' fill='#C8D2F1' font-family='Arial' font-size='18'&amp;gt;B-roll cues become timed visual layers&amp;lt;/text&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;112&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:center; color:#ffffff; font-size:36px; font-weight:800; line-height:1.22;'&amp;gt;Automated B-roll from JSON timing&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;662&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;214&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;430&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;235&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='430' height='235' viewBox='0 0 430 235' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;rect width='430' height='235' rx='24' fill='#102A43'/&amp;gt;&amp;lt;rect x='24' y='24' width='382' height='128' rx='20' fill='rgba(45,212,191,0.18)' stroke='rgba(45,212,191,0.55)'/&amp;gt;&amp;lt;circle cx='94' cy='88' r='34' fill='#2DD4BF' opacity='0.9'/&amp;gt;&amp;lt;rect x='154' y='62' width='170' height='18' rx='9' fill='rgba(255,255,255,0.76)'/&amp;gt;&amp;lt;rect x='154' y='96' width='118' height='14' rx='7' fill='rgba(255,255,255,0.42)'/&amp;gt;&amp;lt;text x='215' y='195' text-anchor='middle' fill='#FFFFFF' font-family='Arial' font-size='26' font-weight='800'&amp;gt;Product close-up&amp;lt;/text&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;718&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;214&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;430&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;235&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='430' height='235' viewBox='0 0 430 235' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;rect width='430' height='235' rx='24' fill='#2B1745'/&amp;gt;&amp;lt;rect x='34' y='30' width='362' height='118' rx='20' fill='rgba(168,85,247,0.18)' stroke='rgba(168,85,247,0.58)'/&amp;gt;&amp;lt;path d='M72 122 L148 66 L214 118 L270 82 L360 132' fill='none' stroke='#FADD46' stroke-width='10' stroke-linecap='round' stroke-linejoin='round'/&amp;gt;&amp;lt;text x='215' y='195' text-anchor='middle' fill='#FFFFFF' font-family='Arial' font-size='26' font-weight='800'&amp;gt;Feature proof&amp;lt;/text&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;662&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;214&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;430&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;235&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='430' height='235' viewBox='0 0 430 235' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;rect width='430' height='235' rx='24' fill='#142B21'/&amp;gt;&amp;lt;rect x='38' y='30' width='354' height='118' rx='20' fill='rgba(250,221,70,0.15)' stroke='rgba(250,221,70,0.6)'/&amp;gt;&amp;lt;rect x='78' y='60' width='76' height='54' rx='12' fill='#FADD46' opacity='0.92'/&amp;gt;&amp;lt;rect x='178' y='60' width='76' height='54' rx='12' fill='#2DD4BF' opacity='0.92'/&amp;gt;&amp;lt;rect x='278' y='60' width='76' height='54' rx='12' fill='#FFFFFF' opacity='0.72'/&amp;gt;&amp;lt;text x='215' y='195' text-anchor='middle' fill='#FFFFFF' font-family='Arial' font-size='26' font-weight='800'&amp;gt;Outcome shot&amp;lt;/text&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegvk84g1jxorl6w9cb82.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegvk84g1jxorl6w9cb82.webp" alt="Zvid JSON payload visual for automated B-roll timing" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The payload visual is generated from the real renderable B-roll timing example.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the public API request, wrap the project inside a top-level &lt;code&gt;payload&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"automate-broll-json-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the B-roll workflow works
&lt;/h2&gt;

&lt;p&gt;The most reliable B-roll automation systems separate editorial decisions from rendering. The renderer should receive clean timing data. It should not have to infer what the video is about.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcblokf9dxxv6abvmmzby.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcblokf9dxxv6abvmmzby.webp" alt="Workflow diagram for automated B-roll with JSON and the Zvid API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep cue extraction, asset selection, JSON assembly, render submission, and job polling as separate steps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A practical implementation usually looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with a script, transcript, product feed, tutorial outline, or campaign brief.&lt;/li&gt;
&lt;li&gt;Extract cue windows such as product mention, feature proof, location, testimonial, screenshot, or outcome.&lt;/li&gt;
&lt;li&gt;Match each cue to an approved media asset.&lt;/li&gt;
&lt;li&gt;Convert each matched asset into an &lt;code&gt;IMAGE&lt;/code&gt;, &lt;code&gt;VIDEO&lt;/code&gt;, or &lt;code&gt;GIF&lt;/code&gt; visual element.&lt;/li&gt;
&lt;li&gt;Add timing, track order, resize behavior, and optional transitions.&lt;/li&gt;
&lt;li&gt;Submit the payload to Zvid and poll the render job until the final video is ready.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This structure makes B-roll easier to review. Editors can approve cue timing and media choices before rendering. Developers can test one generated payload without opening a timeline editor. Marketers can reuse the same placement rules across many product videos, explainers, ads, or social clips.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping B-roll plans from scripts or data
&lt;/h2&gt;

&lt;p&gt;The input to your B-roll system can be human-written or machine-generated. The important part is to normalize it into a simple B-roll plan before you build the Zvid payload.&lt;/p&gt;

&lt;p&gt;A readable CSV-style plan might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;label,asset_url,asset_type,start_seconds,end_seconds,editor_note
product close-up,https://example.com/media/product-closeup.jpg,IMAGE,2.2,5.8,Show when the narration names the product
feature proof,https://example.com/media/dashboard-demo.mp4,VIDEO,6.0,11.0,Show dashboard evidence after the feature claim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This CSV is not the Zvid render payload. It is a review-friendly planning layer that editors, AI tools, or automation rules can produce before your application creates renderable JSON. When the plan is approved, your code maps each row into a Zvid visual element: &lt;code&gt;asset_url&lt;/code&gt; becomes &lt;code&gt;src&lt;/code&gt;, &lt;code&gt;asset_type&lt;/code&gt; becomes &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;start_seconds&lt;/code&gt; becomes &lt;code&gt;enterBegin&lt;/code&gt;, and &lt;code&gt;end_seconds&lt;/code&gt; becomes &lt;code&gt;exitEnd&lt;/code&gt;. The template then adds layout fields such as &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;resize&lt;/code&gt;, &lt;code&gt;track&lt;/code&gt;, and optional animations.&lt;/p&gt;

&lt;p&gt;For feed-driven content, the B-roll plan can be generated from the same data source that fills titles, prices, locations, or product attributes. That is why the CSV-to-video pattern maps well to B-roll: the data decides which supporting media appears, while the template controls where and how it appears.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI video and B-roll footage fit
&lt;/h2&gt;

&lt;p&gt;AI can help with B-roll automation, but it should feed the pipeline rather than replace the template. A prompt can ask an AI model to read a script, transcript, subtitle file, or product description and suggest cue windows such as "show dashboard," "show product close-up," "show customer outcome," or "show location context." Your app can then match those suggestions to approved stock footage, product media, image generation outputs, or an internal asset library.&lt;/p&gt;

&lt;p&gt;That distinction matters for short-form videos, YouTube Shorts, Instagram Reels, tutorials, and product explainers. Content creators may want the speed of an AI B-roll generator, while teams still need predictable layout, caption safety, brand rules, and final video review. JSON is the handoff between the creative cue and the rendering API.&lt;/p&gt;

&lt;p&gt;A useful AI-assisted pipeline looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use AI or editorial rules to identify relevant B-roll footage windows.&lt;/li&gt;
&lt;li&gt;Search an approved source such as an internal media library, Pexels-style stock footage, product screenshots, or generated images.&lt;/li&gt;
&lt;li&gt;Convert the selected asset into a timed Zvid visual layer.&lt;/li&gt;
&lt;li&gt;Render the final video through the API with a server-side API key.&lt;/li&gt;
&lt;li&gt;Store the prompt, cue list, payload, and render job ID for review.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This keeps video production repeatable. If a generated cue is weak, you can improve the prompt or asset matcher. If the layout is weak, you can improve the JSON template. If the final video needs a different format, you can adjust the composition without changing the cue extraction step.&lt;/p&gt;

&lt;p&gt;This is also where orchestration tools can sit around the render API. A team might use OpenAI for transcript analysis, a Pexels-style media search for stock footage, n8n or another workflow tool to move data between systems, and GitHub to version prompt and template changes. Zvid's role is the video creation step that turns the approved cue list into the final video through an API.&lt;/p&gt;

&lt;p&gt;Prompt-only B-roll has limits. It may find a relevant topic but still choose the wrong shot, miss the original video pacing, place B-rolls over a caption, or produce a clip that feels generic instead of professional video. A video editor can catch those issues manually, but automation needs the same judgment encoded as reviewable data. Keep the cue list, prompt, selected asset URL, and JSON layer visible so reviewers can fix finding the right B-roll footage without rebuilding the whole video with AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Timing, tracks, resize, and transitions
&lt;/h2&gt;

&lt;p&gt;B-roll quality depends less on how many clips you add and more on whether the timing and layout respect the viewer's attention.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqud375kij3aw2kamhjhi.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqud375kij3aw2kamhjhi.webp" alt="Diagram showing timed B-roll layers in a Zvid JSON payload" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;B-roll layers need timing, layout, and track order, not just asset URLs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Use these rules as a starting point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;enterBegin&lt;/code&gt; and &lt;code&gt;exitEnd&lt;/code&gt; from the cue window.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;enterEnd&lt;/code&gt; and &lt;code&gt;exitBegin&lt;/code&gt; when you want a fade or other entrance and exit effect.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;track&lt;/code&gt; so titles, captions, and callouts sit above B-roll when needed.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;resize: "cover"&lt;/code&gt; for full-frame B-roll and &lt;code&gt;resize: "contain"&lt;/code&gt; when the full asset must remain visible.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, and &lt;code&gt;height&lt;/code&gt; to create picture-in-picture or side-by-side layouts.&lt;/li&gt;
&lt;li&gt;Use video transitions only between coordinated &lt;code&gt;VIDEO&lt;/code&gt; elements when the handoff is intentional.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not turn every cue into a cutaway. B-roll is strongest when it clarifies the spoken point, shows proof, or adds visual context. Too much movement can make a generated video feel noisy even when every JSON field is valid.&lt;/p&gt;

&lt;p&gt;For a talking-head explainer, B-roll often works well as short full-frame cutaways or picture-in-picture inserts. For product videos, it may be a sequence of product photos, feature screenshots, and outcome shots. For tutorials, it can be screen recordings or annotated UI steps. In each case, the JSON model stays the same: timed visual layers on a shared composition timeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  API workflow for rendering B-roll
&lt;/h2&gt;

&lt;p&gt;After your payload is ready, submit it through the Zvid render endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.zvid.io/api/render/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @broll-render.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the returned job ID, then poll the job endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application should treat rendering as asynchronous. Store the source cue list, the generated payload, the render job ID, and the final result URL together. That makes it much easier to debug a wrong asset, a mistimed cue, or a layout issue after the video has been generated.&lt;/p&gt;

&lt;p&gt;If a render fails, inspect the payload your app sent rather than only checking the source data. The bug may be in the cue extractor, asset matcher, JSON mapper, or template. Keeping those stages separate makes automated B-roll easier to operate at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;The biggest mistake is treating B-roll as a list of media URLs instead of a timeline. A URL alone does not define pacing, layout, layering, or audio behavior.&lt;/p&gt;

&lt;p&gt;Other mistakes show up often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding B-roll before the narration introduces the concept.&lt;/li&gt;
&lt;li&gt;Letting cutaways hide important captions, titles, or product details.&lt;/li&gt;
&lt;li&gt;Forgetting &lt;code&gt;volume: 0&lt;/code&gt; on supporting video clips when narration should stay dominant.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;contain&lt;/code&gt; when the B-roll should fill the frame, or &lt;code&gt;cover&lt;/code&gt; when the full screenshot must remain visible.&lt;/li&gt;
&lt;li&gt;Putting every visual on the same &lt;code&gt;track&lt;/code&gt; and getting unexpected layer order.&lt;/li&gt;
&lt;li&gt;Creating transition chains before the basic timing is clear.&lt;/li&gt;
&lt;li&gt;Using assets with inconsistent aspect ratios without testing the layout.&lt;/li&gt;
&lt;li&gt;Generating cues from AI output without editorial review.&lt;/li&gt;
&lt;li&gt;Forgetting that render jobs are asynchronous.&lt;/li&gt;
&lt;li&gt;Reusing one B-roll template across portrait, square, and landscape formats without layout changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w7hb7ohe38mz83cj050.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w7hb7ohe38mz83cj050.webp" alt="Comparison chart for manual B-roll editing versus JSON-driven B-roll automation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;JSON-driven B-roll is strongest when placement rules are repeatable and reviewable.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fix is to make B-roll part of the template contract. Define the allowed asset types, expected cue duration, track order, audio behavior, and layout variants before you generate hundreds of payloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use Zvid
&lt;/h2&gt;

&lt;p&gt;Use Zvid when your application needs to generate videos from structured data and repeat the same B-roll logic across many outputs. It is a strong fit for agencies, AI video tools, ecommerce teams, tutorial platforms, internal enablement systems, and marketing operations teams that already know what supporting media should appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0a4f9w71lp4ylcxs6vr.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0a4f9w71lp4ylcxs6vr.webp" alt="Use-case illustration for teams generating videos with automated B-roll and JSON" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One cue system can power many video formats when B-roll is modeled as data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Zvid is especially useful when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Timed media layers generated from scripts, transcripts, feeds, or campaign rules.&lt;/li&gt;
&lt;li&gt;Repeatable B-roll placement across many videos.&lt;/li&gt;
&lt;li&gt;A JSON payload that controls scene layout, media, text, timing, and output settings.&lt;/li&gt;
&lt;li&gt;A hosted API workflow for render submission and job polling.&lt;/li&gt;
&lt;li&gt;Clear handoff between editorial cue review and automated rendering.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your team only needs one carefully edited hero video, a manual editor may be the right tool. If you need product cutaways, tutorial inserts, social proof clips, or campaign variations generated repeatedly, JSON B-roll gives your app a better system boundary.&lt;/p&gt;

&lt;p&gt;Start with one short cue list, map it into a Zvid payload, render the result, and inspect the timing before you scale the same template across more videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is automated B-roll?
&lt;/h3&gt;

&lt;p&gt;Automated B-roll is supporting video, image, GIF, or graphic content placed on a timeline by software instead of manually edited clip by clip.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I add B-roll with JSON?
&lt;/h3&gt;

&lt;p&gt;Yes. In Zvid, add B-roll as timed visual elements in the &lt;code&gt;visuals&lt;/code&gt; array. Use &lt;code&gt;IMAGE&lt;/code&gt;, &lt;code&gt;VIDEO&lt;/code&gt;, &lt;code&gt;GIF&lt;/code&gt;, &lt;code&gt;SVG&lt;/code&gt;, or &lt;code&gt;TEXT&lt;/code&gt; depending on the asset and layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which fields control B-roll timing?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;enterBegin&lt;/code&gt;, &lt;code&gt;enterEnd&lt;/code&gt;, &lt;code&gt;exitBegin&lt;/code&gt;, and &lt;code&gt;exitEnd&lt;/code&gt; to control when each element appears and disappears on the timeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I keep B-roll from covering titles or captions?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;track&lt;/code&gt; deliberately. Lower tracks render behind higher tracks, so keep background B-roll lower than titles, captions, and callouts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should B-roll video clips include audio?
&lt;/h3&gt;

&lt;p&gt;Only when the source audio is part of the final story. For most narration-led workflows, set supporting video clips to &lt;code&gt;volume: 0&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use images instead of video clips for B-roll?
&lt;/h3&gt;

&lt;p&gt;Yes. Product photos, screenshots, still frames, and generated graphics can work well as B-roll when they are timed and positioned correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I choose between &lt;code&gt;cover&lt;/code&gt; and &lt;code&gt;contain&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;cover&lt;/code&gt; when the asset should fill its frame and cropping is acceptable. Use &lt;code&gt;contain&lt;/code&gt; when the entire asset must remain visible, such as UI screenshots or charts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can AI help choose B-roll cues?
&lt;/h3&gt;

&lt;p&gt;Yes, AI can suggest cue windows from a script or transcript, but teams should still review cue quality, asset relevance, and timing before rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is B-roll automation useful for product videos?
&lt;/h3&gt;

&lt;p&gt;Yes. Product feeds can map images, feature screenshots, benefit cards, and outcome shots into repeatable B-roll scenes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Add Subtitles to Video with JSON: API Tutorial</title>
      <dc:creator>Mina Ramzy</dc:creator>
      <pubDate>Tue, 09 Jun 2026 10:31:04 +0000</pubDate>
      <link>https://dev.to/mena234/add-subtitles-to-video-with-json-api-tutorial-2bal</link>
      <guid>https://dev.to/mena234/add-subtitles-to-video-with-json-api-tutorial-2bal</guid>
      <description>&lt;p&gt;To add subtitles to a video with JSON, define caption segments with &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, and &lt;code&gt;words&lt;/code&gt;, add optional subtitle styles, then send the full video payload to a rendering API. In Zvid, subtitles live in the top-level &lt;code&gt;subtitle&lt;/code&gt; object of the render payload, so captions can be generated, edited, versioned, translated, and rendered alongside the rest of the video scene.&lt;/p&gt;

&lt;p&gt;The practical flow is simple: create the video layout, add timed caption data, submit the render job to &lt;code&gt;POST https://api.zvid.io/api/render/api-key&lt;/code&gt;, and poll &lt;code&gt;GET https://api.zvid.io/api/jobs/{id}&lt;/code&gt; until the captioned output is ready. If you start with an already recorded video or audio file, transcribe it upstream with a speech-to-text service, then convert that subtitle output into Zvid's &lt;code&gt;captions&lt;/code&gt; and &lt;code&gt;words&lt;/code&gt; structure before rendering. Keep the &lt;a href="https://docs.zvid.io/docs/structure/subtitle?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Subtitle reference&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/properties/caption?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Caption reference&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/properties/word?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Word reference&lt;/a&gt;, and &lt;a href="https://docs.zvid.io/docs/structure/properties/subtitle-styles?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;SubtitleStyles reference&lt;/a&gt; nearby while you implement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sa1t418m60tou30mh9q.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sa1t418m60tou30mh9q.webp" alt="Hero image for adding subtitles to video with JSON in the Zvid API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Subtitles become easier to automate when transcript output becomes structured caption data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are new to Zvid's overall render model, start with the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt;, then compare this subtitle-focused workflow with &lt;a href="https://zvid.io/blog/how-to-generate-a-video-from-json?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Generate a Video from JSON&lt;/a&gt; and the broader &lt;a href="https://zvid.io/blog/json-to-video-api-complete-guide-for-developers?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON to Video API guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is the API loop most developers need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.zvid.io/api/render/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @captioned-render.json

curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The JSON subtitle model
&lt;/h2&gt;

&lt;p&gt;Zvid subtitles are not a separate file upload in the common API pattern. They are part of the render payload. That makes them useful for applications that already produce transcripts, voiceover scripts, product narration, or short-form social captions as data.&lt;/p&gt;

&lt;p&gt;The top-level &lt;code&gt;subtitle&lt;/code&gt; object contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;captions&lt;/code&gt;: an array of timed caption segments.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;styles&lt;/code&gt;: optional typography, placement, and display mode settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each caption segment contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;start&lt;/code&gt;: when the caption appears, in seconds.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;end&lt;/code&gt;: when the caption disappears, in seconds.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text&lt;/code&gt;: the full caption text for that segment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;words&lt;/code&gt;: an array of word-level timings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each word item contains &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, and &lt;code&gt;text&lt;/code&gt;. Word timings power interactive-looking subtitle modes such as one-word, karaoke, and progressive captions. They also make your data easier to inspect when a caption feels early, late, or hard to read.&lt;/p&gt;

&lt;p&gt;This is different from uploading an external WebVTT, SRT, or closed captioning file after export. With Zvid, the caption text, timing metadata, font, position, and display mode can travel with the same JSON to video template that controls the visual scene. That gives your app full control over how subtitles appear in the final video, instead of merging captions manually in a separate editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy-paste Zvid caption payload
&lt;/h2&gt;

&lt;p&gt;The example below renders a short captioned explainer card. The visual layout is intentionally simple so the subtitle data is the main thing to study.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"add-subtitles-json-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#101623"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='1280' height='720' viewBox='0 0 1280 720' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='bg' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#101623'/&amp;gt;&amp;lt;stop offset='1' stop-color='#243047'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;linearGradient id='accent' x1='0' y1='0' x2='1' y2='0'&amp;gt;&amp;lt;stop offset='0' stop-color='#2DD4BF'/&amp;gt;&amp;lt;stop offset='1' stop-color='#FADD46'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect width='1280' height='720' fill='url(#bg)'/&amp;gt;&amp;lt;rect x='54' y='54' width='1172' height='612' rx='30' fill='rgba(255,255,255,0.045)' stroke='rgba(255,255,255,0.12)'/&amp;gt;&amp;lt;rect x='96' y='92' width='186' height='38' rx='19' fill='rgba(45,212,191,0.14)' stroke='rgba(45,212,191,0.42)'/&amp;gt;&amp;lt;text x='189' y='117' text-anchor='middle' fill='#A7FFF6' font-family='Arial' font-size='14' font-weight='700'&amp;gt;ZVID SUBTITLES&amp;lt;/text&amp;gt;&amp;lt;rect x='112' y='168' width='420' height='160' rx='24' fill='rgba(8,13,26,0.62)' stroke='rgba(255,255,255,0.12)'/&amp;gt;&amp;lt;text x='152' y='215' fill='#FFFFFF' font-family='Arial' font-size='25' font-weight='800'&amp;gt;Caption data&amp;lt;/text&amp;gt;&amp;lt;text x='152' y='255' fill='#A7FFF6' font-family='Arial' font-size='18' font-weight='700'&amp;gt;{ start, end, text }&amp;lt;/text&amp;gt;&amp;lt;rect x='152' y='282' width='290' height='14' rx='7' fill='rgba(255,255,255,0.18)'/&amp;gt;&amp;lt;rect x='152' y='308' width='224' height='14' rx='7' fill='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;rect x='748' y='168' width='420' height='160' rx='24' fill='rgba(8,13,26,0.62)' stroke='rgba(255,255,255,0.12)'/&amp;gt;&amp;lt;text x='788' y='215' fill='#FFFFFF' font-family='Arial' font-size='25' font-weight='800'&amp;gt;Rendered video&amp;lt;/text&amp;gt;&amp;lt;rect x='788' y='238' width='300' height='66' rx='18' fill='rgba(255,255,255,0.08)' stroke='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;rect x='818' y='261' width='232' height='18' rx='9' fill='url(#accent)' opacity='0.9'/&amp;gt;&amp;lt;rect x='818' y='288' width='190' height='11' rx='6' fill='rgba(255,255,255,0.18)'/&amp;gt;&amp;lt;line x1='582' y1='252' x2='700' y2='252' stroke='#FADD46' stroke-width='7' stroke-linecap='round'/&amp;gt;&amp;lt;polygon points='700,252 680,239 680,265' fill='#FADD46'/&amp;gt;&amp;lt;text x='641' y='229' text-anchor='middle' fill='#FADD46' font-family='Arial' font-size='18' font-weight='700'&amp;gt;render&amp;lt;/text&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;116&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;840&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:center; color:#ffffff; font-size:40px; font-weight:800; line-height:1.12;'&amp;gt;JSON subtitles that render&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;566&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;920&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:center; color:#D7DEF6; font-size:24px; line-height:1.35;'&amp;gt;Keep captions, word timing, styles, and render output in one API payload.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subtitle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"captions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Build captions as JSON data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"words"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Build"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"captions"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"as"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.75&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSON"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.75&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Control every word on the timeline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"words"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Control"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"every"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"word"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"on"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"the"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"timeline"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Render the captioned video with Zvid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"words"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Render"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"the"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"captioned"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"video"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"with Zvid"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"styles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#FFFFFF"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#000000CC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"isBold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fontSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fontFamily"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Montserrat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"marginV"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"marginH"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"karaoke"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"activeWord"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#FADD46"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuimtcdqrlgidl6c4zegr.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuimtcdqrlgidl6c4zegr.webp" alt="Zvid subtitle JSON payload visual generated from the article example" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The payload visual is generated from the real renderable subtitle example in this tutorial.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For a public API request, wrap that project inside a top-level &lt;code&gt;payload&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"add-subtitles-json-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"subtitle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"captions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Build captions as JSON data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"words"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Build"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the subtitle workflow works
&lt;/h2&gt;

&lt;p&gt;The workflow is easiest when you treat subtitle generation as a data pipeline, not as a manual editing step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfjy5i9l2d0tfsifdc2q.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfjy5i9l2d0tfsifdc2q.webp" alt="Workflow diagram for automated video captions with JSON and the Zvid API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep transcript creation, subtitle format conversion, render submission, and job polling as separate steps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A reliable implementation usually looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate or import a transcript from a speech-to-text service.&lt;/li&gt;
&lt;li&gt;Convert the service output into Zvid caption segments with &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, and &lt;code&gt;words&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Preserve word-level timings from the transcription output where available.&lt;/li&gt;
&lt;li&gt;Choose subtitle style settings for placement, color, background, and mode.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;subtitle&lt;/code&gt; object to the same payload that defines the video scene.&lt;/li&gt;
&lt;li&gt;Submit the render job and poll for completion.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This separation matters because captions often need independent review. A designer may care about line length and placement. A localization team may care about translation quality. A developer may care about timestamp accuracy and retry behavior. JSON keeps those concerns explicit.&lt;/p&gt;

&lt;p&gt;If an AI transcription service or speech-to-text tool creates the first draft, treat that output as source data rather than the final subtitle layer. Your app should map the provider's response into Zvid's subtitle format, including caption-level &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, and &lt;code&gt;text&lt;/code&gt; fields plus each caption's &lt;code&gt;words&lt;/code&gt; array. Review proper nouns, numbers, speaker phrasing, punctuation, language, and line breaks before rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subtitle display modes and styles
&lt;/h2&gt;

&lt;p&gt;Subtitle style settings control how the captions look and where they appear. Zvid supports common style fields such as &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;background&lt;/code&gt;, &lt;code&gt;fontSize&lt;/code&gt;, &lt;code&gt;fontFamily&lt;/code&gt;, bold and italic flags, &lt;code&gt;position&lt;/code&gt;, margins, display &lt;code&gt;mode&lt;/code&gt;, and an &lt;code&gt;activeWord&lt;/code&gt; color for word-aware modes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4rmgiz8wyig0034tnlp.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4rmgiz8wyig0034tnlp.webp" alt="Diagram showing how caption text, word timing, style settings, and display mode combine into Zvid subtitles" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A subtitle object combines text, timing, display mode, and style rules.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Use a solid or semi-transparent background when the underlying video is busy. Use center placement when the subtitle is the main teaching element, and move captions to the top or side when lower-third graphics, product details, or call-to-action buttons need that space.&lt;/p&gt;

&lt;p&gt;For most API-driven workflows, start with one brand-safe caption preset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"styles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#FFFFFF"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#000000CC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fontSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fontFamily"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Montserrat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"isBold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"marginV"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"marginH"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"karaoke"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"activeWord"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#FADD46"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that preset works, reuse it across templates. Change it only when the output channel, language, aspect ratio, or visual layout requires a different caption treatment.&lt;/p&gt;

&lt;p&gt;For translated or localized subtitles, expect text length to change. A short English caption may become longer in another language, which can affect font size, line breaks, and position. Test the longest expected language before you generate subtitles automatically across many clips.&lt;/p&gt;

&lt;h2&gt;
  
  
  API workflow for rendering captions
&lt;/h2&gt;

&lt;p&gt;After the payload is ready, submit it through the same render endpoint used for other Zvid videos. The &lt;a href="https://docs.zvid.io/docs/endpoints/submit-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Submit render job reference&lt;/a&gt; documents &lt;code&gt;POST /api/render/api-key&lt;/code&gt;, and the &lt;a href="https://docs.zvid.io/docs/endpoints/get-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Get render job status reference&lt;/a&gt; documents &lt;code&gt;GET /api/jobs/{id}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.zvid.io/api/render/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @captioned-render.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the returned job ID, then poll for status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important application behavior is to treat rendering as asynchronous. Submit the job, store the payload version, poll the job state, and only publish or notify the user after the completed result is available.&lt;/p&gt;

&lt;p&gt;This is also where Zvid fits well with repeatable content systems. The same caption template can support social clips, onboarding videos, course snippets, translated product demos, and programmatic explainers. If the surrounding workflow starts from feeds or spreadsheet data, the pattern is similar to &lt;a href="https://zvid.io/blog/how-to-create-product-videos-from-a-csv-or-product-feed?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Create Product Videos from a CSV or Product Feed&lt;/a&gt;, except the dynamic fields include captions and word timings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding subtitles to an existing video file
&lt;/h2&gt;

&lt;p&gt;If your input is an already recorded video file, the JSON workflow still applies. Use a public media URL for the source video, add it as a &lt;code&gt;VIDEO&lt;/code&gt; visual, then add the subtitle object with synchronized subtitles for the spoken audio. Zvid can create a video output with the captions rendered into the final frame.&lt;/p&gt;

&lt;p&gt;Your app can automatically generate the first transcript with an AI or speech-to-text service, but the render payload should contain the reviewed result in Zvid's subtitle structure: clean text, caption segments, and word arrays that match the audio track. That is the difference between generating raw transcription and generating video subtitles that are readable in the finished clip.&lt;/p&gt;

&lt;p&gt;For teams that need accessible video content, keep the source transcript and caption metadata even after export. The rendered subtitles help viewers watch the video, while a separate platform-specific caption file may still be useful when a publishing destination supports external accessibility tracks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;The most common mistake is modeling subtitles as plain text instead of timed data. Plain transcript text is useful, but it does not tell the renderer when each caption should appear or how word-level modes should behave.&lt;/p&gt;

&lt;p&gt;Other mistakes show up often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Putting word timings outside the parent caption's time range.&lt;/li&gt;
&lt;li&gt;Creating captions that are too long for the available screen time.&lt;/li&gt;
&lt;li&gt;Using small font sizes on mobile-first outputs.&lt;/li&gt;
&lt;li&gt;Leaving captions over important lower-third graphics.&lt;/li&gt;
&lt;li&gt;Forgetting that render jobs are asynchronous.&lt;/li&gt;
&lt;li&gt;Treating translated captions as a drop-in replacement without checking line length.&lt;/li&gt;
&lt;li&gt;Using a busy video background without a readable caption background or outline.&lt;/li&gt;
&lt;li&gt;Assuming automatic transcription is already perfect without editing the generated captions.&lt;/li&gt;
&lt;li&gt;Confusing embedded visual subtitles with a separate accessibility caption file.&lt;/li&gt;
&lt;li&gt;Forgetting to adjust subtitle animation, font size, or default placement for a new output format.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3o786b5grxywv5ayg1o.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3o786b5grxywv5ayg1o.webp" alt="Comparison chart showing manual subtitle editing versus JSON-driven video subtitles through an API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;JSON-driven subtitles are strongest when captions are generated, reviewed, and rendered repeatedly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fix is to make the subtitle object part of your template contract. Store the caption data, the source transcript, the payload version, and the render job ID together. That makes subtitle bugs much easier to reproduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use Zvid
&lt;/h2&gt;

&lt;p&gt;Use Zvid when your application needs to render captioned videos from structured data instead of manually editing every output. It is a strong fit for developer teams, short-form video tools, agencies, course platforms, ecommerce workflows, and automation systems that already know what the caption text should say.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiszj8wvvglfjtijk10hv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiszj8wvvglfjtijk10hv.webp" alt="Use-case illustration for teams generating captioned videos from JSON with the Zvid API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caption data can travel with the same JSON payload that controls the rest of the video.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Zvid is especially useful when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repeatable subtitle styling across many videos.&lt;/li&gt;
&lt;li&gt;Timed captions generated from transcripts, scripts, or localization workflows.&lt;/li&gt;
&lt;li&gt;Word-level subtitle modes for short-form videos.&lt;/li&gt;
&lt;li&gt;A hosted API workflow for render submission and job polling.&lt;/li&gt;
&lt;li&gt;One JSON payload that contains scene layout, media, captions, and output settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your team only needs one hand-edited video, a manual editor may be enough. If you need captioned videos generated from product data, scripts, transcripts, lessons, or campaign templates, JSON subtitles are the better system boundary.&lt;/p&gt;

&lt;p&gt;Start with one short payload, render it through Zvid, and inspect the subtitle output before you scale the same template across more videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What fields are required for Zvid subtitles?
&lt;/h3&gt;

&lt;p&gt;A subtitle object needs a &lt;code&gt;captions&lt;/code&gt; array. Each caption needs &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, and &lt;code&gt;words&lt;/code&gt;. Each word needs &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, and &lt;code&gt;text&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need word-level timings?
&lt;/h3&gt;

&lt;p&gt;Yes, for Zvid subtitle captions that use the documented subtitle shape. Word timings are especially important for one-word, karaoke, and progressive display modes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I style subtitles with JSON?
&lt;/h3&gt;

&lt;p&gt;Yes. The &lt;code&gt;styles&lt;/code&gt; object can define color, background, font size, font family, bold or italic text, placement, margins, display mode, and active word color.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where does the subtitle object go?
&lt;/h3&gt;

&lt;p&gt;Place &lt;code&gt;subtitle&lt;/code&gt; at the top level of the Zvid render payload, alongside fields such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;resolution&lt;/code&gt;, &lt;code&gt;duration&lt;/code&gt;, &lt;code&gt;frameRate&lt;/code&gt;, &lt;code&gt;outputFormat&lt;/code&gt;, &lt;code&gt;visuals&lt;/code&gt;, and &lt;code&gt;audios&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use subtitles with generated or feed-based videos?
&lt;/h3&gt;

&lt;p&gt;Yes. Caption text and timing can be generated from transcripts, scripts, product data, localization workflows, or other structured inputs before you submit the render payload.&lt;/p&gt;

&lt;h3&gt;
  
  
  How should I validate subtitle JSON?
&lt;/h3&gt;

&lt;p&gt;Check that every caption has &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, and &lt;code&gt;words&lt;/code&gt;, every word fits inside its parent caption, and the caption position does not cover important visual content.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I add subtitles to an already recorded video?
&lt;/h3&gt;

&lt;p&gt;Transcribe the recorded audio first, convert the speech-to-text output into Zvid caption segments and word arrays, then add that subtitle object to the same Zvid payload that references the video or recreates the scene.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can AI tools generate subtitles for this workflow?
&lt;/h3&gt;

&lt;p&gt;Yes. AI transcription or speech-to-text tools can generate the first subtitle draft, but your app should still convert the result into Zvid's subtitle structure and review text accuracy, language, punctuation, and line length before sending the JSON payload to Zvid.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are subtitles the same as closed captions?
&lt;/h3&gt;

&lt;p&gt;Not always. In this article, subtitles are visual text rendered into the video. Closed captioning can also mean a separate accessibility track or file, depending on the publishing platform.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Product Video API: How APIs Power CSV Video Generation</title>
      <dc:creator>Mina Ramzy</dc:creator>
      <pubDate>Fri, 05 Jun 2026 21:00:00 +0000</pubDate>
      <link>https://dev.to/mena234/product-video-api-how-apis-power-csv-video-generation-8e8</link>
      <guid>https://dev.to/mena234/product-video-api-how-apis-power-csv-video-generation-8e8</guid>
      <description>&lt;p&gt;A product video API is one of the most practical video APIs for ecommerce teams because it lets you create videos from structured product data instead of editing every SKU by hand. To create product videos from a CSV or product feed, take each row of product data, map it into a reusable video layout, submit one REST API render payload per product, and poll the render jobs until the files are ready. That is the core pattern whether you are generating one launch video, one hundred catalog promos, or channel-specific variations for paid social and marketplaces.&lt;/p&gt;

&lt;p&gt;The important shift is that your feed becomes the source of truth for video generation. Instead of rebuilding timelines manually, you define where the product title, price, CTA, brand colors, and product media should appear in a Zvid render payload. Once that mapping exists, you can render consistent product videos whenever your catalog changes. If you are new to the platform, start with the &lt;a href="https://docs.zvid.io/docs/getting-started?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Getting Started guide&lt;/a&gt;, the &lt;a href="https://docs.zvid.io/docs/authentication?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Authentication guide&lt;/a&gt;, and the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt; so your feed pipeline matches the public API model from the beginning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flcbrvuypfes6qrlzov4x.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flcbrvuypfes6qrlzov4x.webp" alt="Product feed video automation hero for ecommerce teams" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A reusable product-video template turns feed rows into consistent campaign creative.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you already have a feed export, the first working version can be simple. A CSV row with &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;salePrice&lt;/code&gt;, &lt;code&gt;cta&lt;/code&gt;, &lt;code&gt;brandColor&lt;/code&gt;, &lt;code&gt;backgroundColor&lt;/code&gt;, and &lt;code&gt;productImageUrl&lt;/code&gt; is enough to generate a solid promo video when each field maps to a known place in the scene.&lt;/p&gt;

&lt;p&gt;Here is the API shape most teams start with when they want to generate videos programmatically and on-demand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ZVID_API_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://api.zvid.io

curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ZVID_API_BASE_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/render/api-key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$ZVID_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @render-job.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then poll the job until it completes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ZVID_API_BASE_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/jobs/&lt;/span&gt;&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$ZVID_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That flow is the same one described in the &lt;a href="https://docs.zvid.io/docs/getting-started?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Getting Started guide&lt;/a&gt;. The difference for product feeds is how you generate &lt;code&gt;render-job.json&lt;/code&gt;: you build it from structured catalog data instead of hand-authoring every scene.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why feed-driven product video works
&lt;/h2&gt;

&lt;p&gt;Feed-driven video works because product marketing is already structured. Your catalog already knows the product name, price, availability, category, promo language, and image URLs. The video layer should reuse that structure rather than forcing your team to recreate it in an editor for every SKU.&lt;/p&gt;

&lt;p&gt;This approach is especially useful when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One branded template for many products&lt;/li&gt;
&lt;li&gt;Fast refreshes for sales, pricing, and inventory changes&lt;/li&gt;
&lt;li&gt;Different aspect ratios for paid social, marketplace ads, and PDP video slots&lt;/li&gt;
&lt;li&gt;Consistent CTA placement and visual hierarchy across the whole catalog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is also easier to maintain. Your engineering or automation team can version the mapping logic, while marketing keeps control over the copy fields and brand rules that live in the feed itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Product video API workflow
&lt;/h2&gt;

&lt;p&gt;The cleanest video workflow is: ingest feed rows, normalize the fields, map each row to a Zvid payload, submit render jobs through the endpoint, and save the resulting video URL or CDN URL back to your CMS, PIM, Shopify catalog, or ad pipeline. This is the practical difference between a one-off video editing project and video automation that can run every time product details change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxu9epvuob6k6i8gtfvgk.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxu9epvuob6k6i8gtfvgk.webp" alt="CSV to product video workflow using the Zvid API" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A product-feed pipeline separates data cleanup, template mapping, and rendering into repeatable steps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In practice, the product video API pipeline looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse the CSV or pull the product feed from your source system.&lt;/li&gt;
&lt;li&gt;Normalize fields so your template logic gets predictable values.&lt;/li&gt;
&lt;li&gt;Map each normalized row to scene text, colors, media, and timing.&lt;/li&gt;
&lt;li&gt;Submit one render job per video variation through the API.&lt;/li&gt;
&lt;li&gt;Poll job status and store the completed video URL where the business needs it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to use real product photos in production, the &lt;a href="https://docs.zvid.io/docs/structure/image-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Image Elements reference&lt;/a&gt; shows how remote image sources work, while the &lt;a href="https://docs.zvid.io/docs/structure/text-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Text Elements reference&lt;/a&gt; explains the text layer behavior you will use for titles, prices, and CTAs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a product video API for video creation?
&lt;/h2&gt;

&lt;p&gt;A product video API is a creation API for rendering product videos from structured inputs such as product details, image URLs, prices, badges, and calls to action. Unlike a hosting API from a platform such as Vimeo, or live streaming and transcoding APIs for uploaded media, a product video API generates new product video content from a payload.&lt;/p&gt;

&lt;p&gt;For ecommerce teams, the key use case is repeatable video production at scale. Developers send one API call per output, track the job state, and store the finished video URL. That makes it possible to create videos for TikTok ads, marketplace listings, PDP modules, short-form explainers, thumbnails, GIFs, and localized campaign variants without rebuilding the same timeline in a UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  REST API pipeline and API key setup
&lt;/h2&gt;

&lt;p&gt;A reliable REST API implementation keeps auth, payload creation, rendering, and storage separate. First, keep your API key in server-side configuration. Next, build a payload from the product row. Then send it via API to the render endpoint and save the returned job identifier. When the job completes, write the final URL back to your product system.&lt;/p&gt;

&lt;p&gt;That single API loop is small enough to test in a few lines of code, but it can expand into high-volume automated workflows with webhooks, retries, queue monitoring, and per render cost controls. Zvid focuses on rendering videos from templates and structured JSON rather than text prompts, avatar generation, native audio synthesis, or image-to-video generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map feed columns into a reusable Zvid template
&lt;/h2&gt;

&lt;p&gt;The template is the durable asset. The feed row is the changing input.&lt;/p&gt;

&lt;p&gt;For example, a row like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BAG-204"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Transit Weekender Bag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$129"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"salePrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Shop the drop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brandColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#5B3DF5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"accentColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#F5C94A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"productImageUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.example.com/products/transit-weekender-bag.jpg"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be mapped into a render payload with a function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildRenderJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`product-video-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;instagram-story&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;frameRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;outputFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mp4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#0D1020&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;visuals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;IMAGE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productImageUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;960&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;760&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TEXT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;760&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div style='text-align:left; color:#ffffff; font-size:64px; font-weight:700; line-height:1.08;'&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TEXT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;760&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;860&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div style='text-align:left; color:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; font-size:58px; font-weight:700;'&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;salePrice&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is not to hard-code one product. It is to define a stable scene system and let the feed swap in the product-specific values. That becomes much easier when your payload structure follows the public docs for &lt;a href="https://docs.zvid.io/docs/structure/properties/resolution-presets?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;resolution presets&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/text-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;text layers&lt;/a&gt;, and &lt;a href="https://docs.zvid.io/docs/structure/image-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;image layers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rx1svdeq53nh1a92qen.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rx1svdeq53nh1a92qen.webp" alt="Product feed field mapping diagram for reusable video templates" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A feed-driven template works when every incoming field has a fixed role in the scene.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Zvid API payload for one product video
&lt;/h2&gt;

&lt;p&gt;Below is a proof-friendly example payload for a single product promo. It uses &lt;code&gt;SVG&lt;/code&gt; and &lt;code&gt;TEXT&lt;/code&gt; elements only so you can study the scene structure clearly. In a production feed pipeline, you would usually replace the illustrated product card with a real remote product image or video clip.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product-feed-demo-bag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#0d1020"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='1280' height='720' viewBox='0 0 1280 720' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='bg' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#0d1020'/&amp;gt;&amp;lt;stop offset='1' stop-color='#1f153d'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;radialGradient id='glowA' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(1060 120) rotate(90) scale(260)'&amp;gt;&amp;lt;stop stop-color='#5b3df5' stop-opacity='0.30'/&amp;gt;&amp;lt;stop offset='1' stop-color='#5b3df5' stop-opacity='0'/&amp;gt;&amp;lt;/radialGradient&amp;gt;&amp;lt;radialGradient id='glowB' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(220 620) rotate(90) scale(280)'&amp;gt;&amp;lt;stop stop-color='#f5c94a' stop-opacity='0.20'/&amp;gt;&amp;lt;stop offset='1' stop-color='#f5c94a' stop-opacity='0'/&amp;gt;&amp;lt;/radialGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect width='1280' height='720' fill='url(#bg)'/&amp;gt;&amp;lt;circle cx='1060' cy='120' r='260' fill='url(#glowA)'/&amp;gt;&amp;lt;circle cx='220' cy='620' r='280' fill='url(#glowB)'/&amp;gt;&amp;lt;rect x='32' y='32' width='1216' height='656' rx='34' fill='rgba(255,255,255,0.035)' stroke='rgba(255,255,255,0.08)'/&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;330&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;370&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"smoothleft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='420' height='520' viewBox='0 0 420 520' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='card' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='rgba(255,255,255,0.12)'/&amp;gt;&amp;lt;stop offset='1' stop-color='rgba(255,255,255,0.05)'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;linearGradient id='bag' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#6f58ff'/&amp;gt;&amp;lt;stop offset='1' stop-color='#f5c94a'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect x='0.5' y='0.5' width='419' height='519' rx='32' fill='url(#card)' stroke='rgba(255,255,255,0.14)'/&amp;gt;&amp;lt;rect x='36' y='34' width='126' height='34' rx='17' fill='rgba(245,201,74,0.14)' stroke='rgba(245,201,74,0.34)'/&amp;gt;&amp;lt;text x='99' y='56' text-anchor='middle' fill='#f5c94a' font-size='15' font-family='Inter' font-weight='700'&amp;gt;NEW ARRIVAL&amp;lt;/text&amp;gt;&amp;lt;rect x='78' y='108' width='264' height='272' rx='28' fill='rgba(10,16,31,0.40)' stroke='rgba(255,255,255,0.10)'/&amp;gt;&amp;lt;path d='M150 198 C150 160 178 138 210 138 C242 138 270 160 270 198' fill='none' stroke='url(#bag)' stroke-width='18' stroke-linecap='round'/&amp;gt;&amp;lt;rect x='126' y='188' width='168' height='150' rx='34' fill='url(#bag)'/&amp;gt;&amp;lt;rect x='156' y='224' width='108' height='18' rx='9' fill='rgba(255,255,255,0.22)'/&amp;gt;&amp;lt;rect x='106' y='408' width='208' height='20' rx='10' fill='rgba(255,255,255,0.11)'/&amp;gt;&amp;lt;rect x='132' y='442' width='156' height='16' rx='8' fill='rgba(245,201,74,0.18)'/&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;852&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;148&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#f5c94a; font-size:18px; font-weight:700; letter-spacing:1px;'&amp;gt;WEEKEND TRAVEL ESSENTIAL&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;852&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;268&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#ffffff; font-family:Poppins; font-size:54px; font-weight:700; line-height:1.08;'&amp;gt;Transit Weekender Bag&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;852&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; line-height:1.3;'&amp;gt;&amp;lt;div style='color:#9ea7d8; font-size:22px; margin-bottom:10px;'&amp;gt;Carry-on sized. Structured silhouette. Limited seasonal colorway.&amp;lt;/div&amp;gt;&amp;lt;div style='color:#f5c94a; font-size:52px; font-weight:700;'&amp;gt;$99 &amp;lt;span style='color:#8a92bf; font-size:24px; text-decoration:line-through;'&amp;gt;$129&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;852&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;534&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='display:inline-block; background:rgba(91,61,245,0.20); border:1px solid rgba(91,61,245,0.42); border-radius:26px; padding:16px 24px; color:#ffffff; font-size:22px; font-weight:700;'&amp;gt;Shop the drop&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;654&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:center; color:#c4c9ea; font-size:16px;'&amp;gt;Mapped from feed fields: title, list price, sale price, badge, CTA, and brand colors.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbitfrha2j61ra9bgkr8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbitfrha2j61ra9bgkr8.webp" alt="Zvid API payload example for a product feed video" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The same payload structure can be reused for every row in your catalog.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is also a good place for a mid-funnel CTA: if your team already has product data in a spreadsheet, feed, or database table, test one product row first. Build a single reusable template, send one render job, confirm the layout, and then scale from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video editing vs feed-driven rendering
&lt;/h2&gt;

&lt;p&gt;The decision is mostly about volume and repeatability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual editing is fine when you need a handful of one-off launch videos.&lt;/li&gt;
&lt;li&gt;Feed-driven rendering is better when the creative structure stays mostly the same while the product data changes often.&lt;/li&gt;
&lt;li&gt;A template plus API flow gives engineering teams a way to control consistency, retries, and output destinations.&lt;/li&gt;
&lt;li&gt;A feed-driven system also makes localization and promotion-specific variants much easier because the text and pricing already live in structured fields.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaerw2osvzspacgn26oq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaerw2osvzspacgn26oq.webp" alt="Manual editing versus feed-driven product video rendering comparison" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Product feeds outperform manual editing when the scene stays stable and the data changes often.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Video generation API use case checklist
&lt;/h2&gt;

&lt;p&gt;When you compare video APIs, look for the part of the workflow each platform actually owns. Some APIs are built for upload, playback, live streams, and cloud infrastructure. Others are AI video generator tools for text to video, image generation, or prompt-based creative output. For feed-driven ecommerce, you usually need a video generation API that is fully customizable, accepts product data programmatically, supports videos using real product URLs, and returns a finished asset your app can store.&lt;/p&gt;

&lt;p&gt;A practical checklist is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the API generate videos from product details without manual video editing?&lt;/li&gt;
&lt;li&gt;Can one API call create a predictable render from a saved layout?&lt;/li&gt;
&lt;li&gt;Does the endpoint support image URLs, text layers, brand colors, and output presets?&lt;/li&gt;
&lt;li&gt;Can the pipeline support high-volume catalog refreshes and automated workflows?&lt;/li&gt;
&lt;li&gt;Can the result be routed to a CDN, ad platform, CMS, or Shopify workflow?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  AI video generator, no-code, and ecommerce integrations
&lt;/h2&gt;

&lt;p&gt;Developers often start with direct API calls, then connect the same workflow to no-code tools when marketing or operations teams need control. A product feed pipeline can be triggered from n8n, Zapier, a Shopify export, a PIM change, or a scheduled catalog job. Tools such as Creatomate, HeyGen, and ElevenLabs solve adjacent creation problems, but the right product video API depends on whether you need configurable product layouts, AI features, text prompts, avatar clips, or structured rendering from CSV data.&lt;/p&gt;

&lt;p&gt;Zvid fits the structured rendering side: define the layout, inject feed values, render the asset, and send the completed video directly to the destination that needs it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;The most common failure is trying to automate before the template rules are clear. If the title box, price placement, offer badge, and CTA style are still changing every day, the feed mapping will stay unstable.&lt;/p&gt;

&lt;p&gt;Other mistakes show up repeatedly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Treating the CSV as clean input when fields actually need normalization first&lt;/li&gt;
&lt;li&gt;Letting title length vary wildly without defining truncation or line-break rules&lt;/li&gt;
&lt;li&gt;Mixing channel formats without deciding when to use &lt;code&gt;instagram-story&lt;/code&gt;, &lt;code&gt;instagram-post&lt;/code&gt;, &lt;code&gt;youtube-video&lt;/code&gt;, or another supported preset&lt;/li&gt;
&lt;li&gt;Hard-coding promotional copy in the template instead of sourcing it from the feed&lt;/li&gt;
&lt;li&gt;Using a template that depends on manual visual tweaks for every product&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before scaling, decide which fields are required, which are optional, and what the fallback behavior should be when an image, sale price, or CTA is missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use Zvid for video automation
&lt;/h2&gt;

&lt;p&gt;Zvid makes sense when you want the video itself to be a programmatic output of your product data.&lt;/p&gt;

&lt;p&gt;Use Zvid when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reusable scene templates for many products or offers&lt;/li&gt;
&lt;li&gt;API-based render submission and job polling in your own pipeline&lt;/li&gt;
&lt;li&gt;Flexible control over text, layout, timing, and media placement&lt;/li&gt;
&lt;li&gt;Different outputs for paid social, lifecycle campaigns, marketplaces, or storefronts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not over-engineer it for a tiny catalog with rare changes. The advantage appears when you want a repeatable system rather than a one-time edit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqekc5pssbixdff41ny7c.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqekc5pssbixdff41ny7c.webp" alt="Ecommerce team creating many product promo videos from one shared feed" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One shared feed can power storefront, paid social, and marketplace video variants.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For implementation detail, the most useful internal docs to keep open are the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/text-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Text Elements reference&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/image-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Image Elements reference&lt;/a&gt;, and &lt;a href="https://docs.zvid.io/docs/structure/properties/resolution-presets?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Resolution Presets reference&lt;/a&gt;. Those pages define the scene building blocks you will reuse as your catalog grows.&lt;/p&gt;

&lt;p&gt;If you want to prove the workflow quickly, start with one row, one template, and one destination format. After that, add batch submission, channel variants, and post-render routing back into your commerce stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Which type of video API do I need?
&lt;/h3&gt;

&lt;p&gt;If you need to host or stream uploaded files, choose a hosting or live streaming API. If you need text-to-video or image-to-video generation from prompts, choose an AI video generator API. If you need to generate product videos from catalog data, choose a product video API that accepts structured fields, images, and layout rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I automate video creation with a video API?
&lt;/h3&gt;

&lt;p&gt;Yes. A video API can automate video creation when your application can build the payload, call the endpoint, poll for completion, and store the result URL. The strongest use case is a repeatable layout with changing inputs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I create many videos from one CSV file?
&lt;/h3&gt;

&lt;p&gt;Yes. The usual pattern is to parse the CSV into rows, map each row into a render payload, and submit one API job per output. The template stays stable while the product fields change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a different template for every product category?
&lt;/h3&gt;

&lt;p&gt;Not always. Many teams start with one universal promo template and then split into category-specific templates only when aspect ratios, copy density, or media framing diverge too much.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does this work with Meta, Google, TikTok, and other ad platforms?
&lt;/h3&gt;

&lt;p&gt;Yes, if your pipeline renders the right aspect ratio and stores the finished video URL where your ad or product workflow can access it. For example, one feed can produce vertical TikTok variants, square marketplace assets, and landscape product explainers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use real product images instead of illustrated placeholders?
&lt;/h3&gt;

&lt;p&gt;Yes. In production, you would normally use remote image URLs with Zvid's &lt;a href="https://docs.zvid.io/docs/structure/image-elements" rel="noopener noreferrer"&gt;Image Elements&lt;/a&gt;. The example payload here keeps the scene self-contained so the structure is easier to study and adapt.&lt;/p&gt;

&lt;p&gt;Structured product data is already most of the work. The leverage comes from turning that structure into a reusable video template and a reliable render workflow. If that matches your use case, test one product row with Zvid, confirm the layout, and then scale the same template across the rest of your feed.&lt;/p&gt;

</description>
      <category>api</category>
      <category>automation</category>
      <category>data</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Generate Video from JSON: AI Context and API Workflow</title>
      <dc:creator>Mina Ramzy</dc:creator>
      <pubDate>Thu, 04 Jun 2026 21:00:00 +0000</pubDate>
      <link>https://dev.to/mena234/generate-video-from-json-ai-context-and-api-workflow-145l</link>
      <guid>https://dev.to/mena234/generate-video-from-json-ai-context-and-api-workflow-145l</guid>
      <description>&lt;p&gt;To generate video from JSON, define the video as structured data, send that payload to a rendering API, save the returned job ID, and poll the job until the final video URL is ready. That is the practical JSON to video workflow behind most JSON video generators: your application creates the scene definition, and the renderer turns it into a finished file.&lt;/p&gt;

&lt;p&gt;With Zvid, that flow is public and straightforward. You verify your API key, submit a &lt;code&gt;payload&lt;/code&gt; to &lt;code&gt;POST https://api.zvid.io/api/render/api-key&lt;/code&gt;, then poll &lt;code&gt;GET https://api.zvid.io/api/jobs/{id}&lt;/code&gt; until the render completes. The best reference pages to keep open while you implement it are the &lt;a href="https://docs.zvid.io/docs/getting-started?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Getting Started guide&lt;/a&gt;, the &lt;a href="https://docs.zvid.io/docs/authentication?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Authentication guide&lt;/a&gt;, the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt;, and the published deep dive &lt;a href="https://zvid.io/blog/json-to-video-api-complete-guide-for-developers?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON to Video API: Convert JSON to Video with Zvid&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh65o3ne075uza6izvitj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh65o3ne075uza6izvitj.webp" alt="Hero illustration showing how to generate a video from JSON with the Zvid API" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Structured JSON becomes a repeatable render workflow when the payload shape stays stable.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to see the broader feed-driven pattern after this tutorial, the same ideas also show up in &lt;a href="https://zvid.io/blog/how-to-create-product-videos-from-a-csv-or-product-feed" rel="noopener noreferrer"&gt;How to Create Product Videos from a CSV or Product Feed&lt;/a&gt;. The difference here is that we are starting with one payload and one render job instead of a larger automation pipeline.&lt;/p&gt;

&lt;p&gt;Here is the minimal public API sequence most developers start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/user/profile &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;

curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.zvid.io/api/render/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @render-job.json

curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What it means to generate a video from JSON
&lt;/h2&gt;

&lt;p&gt;Generating a video from JSON means your timeline is described as data instead of being trapped inside a manual editor file.&lt;/p&gt;

&lt;p&gt;That JSON can define the canvas size, video duration, frame rate, background color, text layers, images, videos, audio tracks, subtitle timing, and output format. Zvid then validates the payload, queues the job, renders the composition, and returns the result when the job is done.&lt;/p&gt;

&lt;p&gt;This is useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The same video layout needs many content variations.&lt;/li&gt;
&lt;li&gt;Your app already stores the inputs as structured data.&lt;/li&gt;
&lt;li&gt;You want repeatable renders instead of one-off exports.&lt;/li&gt;
&lt;li&gt;You need a server-side workflow that can submit, retry, and track jobs predictably.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only need one handcrafted launch video, a manual editor may still be faster. If your product already thinks in structured inputs, JSON rendering is usually a much better fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the JSON to video workflow works
&lt;/h2&gt;

&lt;p&gt;The working loop is: build the JSON payload, submit the job, poll the result, then store or publish the finished video URL. In other words, the JSON file or JSON object acts like a video template plus the values that should fill it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh2k004xwa7dzhz8hbmgr.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh2k004xwa7dzhz8hbmgr.webp" alt="Workflow for generating a video from JSON with the Zvid API" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep payload generation, submission, and job polling as separate steps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In practice, the flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build one valid Zvid &lt;code&gt;payload&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;Submit that payload to &lt;code&gt;POST https://api.zvid.io/api/render/api-key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Save the returned &lt;code&gt;jobId&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and queue details.&lt;/li&gt;
&lt;li&gt;Poll &lt;code&gt;GET https://api.zvid.io/api/jobs/{id}&lt;/code&gt; until the state is &lt;code&gt;completed&lt;/code&gt; or &lt;code&gt;failed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;result.url&lt;/code&gt; when the render finishes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://docs.zvid.io/docs/endpoints/submit-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Submit render job reference&lt;/a&gt; is the canonical source for the request body, and the &lt;a href="https://docs.zvid.io/docs/endpoints/get-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Get render job status reference&lt;/a&gt; is the canonical source for the polling response shape.&lt;/p&gt;

&lt;p&gt;If you are evaluating the workflow for the first time, the right CTA is simple: copy one payload, submit one render, and verify one finished result before you design anything more ambitious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy-paste Zvid JSON example
&lt;/h2&gt;

&lt;p&gt;The render request body must contain a top-level &lt;code&gt;payload&lt;/code&gt;. Inside that payload, the main fields are &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;resolution&lt;/code&gt;, &lt;code&gt;duration&lt;/code&gt;, &lt;code&gt;frameRate&lt;/code&gt;, &lt;code&gt;outputFormat&lt;/code&gt;, &lt;code&gt;backgroundColor&lt;/code&gt;, &lt;code&gt;visuals&lt;/code&gt;, &lt;code&gt;audios&lt;/code&gt;, and &lt;code&gt;subtitle&lt;/code&gt;, as described in the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt;, the &lt;a href="https://docs.zvid.io/docs/structure/properties/resolution-presets" rel="noopener noreferrer"&gt;Resolution Presets reference&lt;/a&gt;, and the &lt;a href="https://docs.zvid.io/docs/structure/text-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Text Elements reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below is a proof-friendly Zvid API payload for a short tutorial-style explainer card. It uses &lt;code&gt;SVG&lt;/code&gt; and &lt;code&gt;TEXT&lt;/code&gt; elements only so the layout is easy to study and adapt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"generate-video-from-json-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#0b1020"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='1280' height='720' viewBox='0 0 1280 720' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='bg' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#0b1020'/&amp;gt;&amp;lt;stop offset='1' stop-color='#1b2147'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;radialGradient id='glowA' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(1080 110) rotate(90) scale(250)'&amp;gt;&amp;lt;stop stop-color='#2dd4bf' stop-opacity='0.18'/&amp;gt;&amp;lt;stop offset='1' stop-color='#2dd4bf' stop-opacity='0'/&amp;gt;&amp;lt;/radialGradient&amp;gt;&amp;lt;radialGradient id='glowB' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(210 640) rotate(90) scale(260)'&amp;gt;&amp;lt;stop stop-color='#f6b84d' stop-opacity='0.16'/&amp;gt;&amp;lt;stop offset='1' stop-color='#f6b84d' stop-opacity='0'/&amp;gt;&amp;lt;/radialGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect width='1280' height='720' fill='url(#bg)'/&amp;gt;&amp;lt;circle cx='1080' cy='110' r='250' fill='url(#glowA)'/&amp;gt;&amp;lt;circle cx='210' cy='640' r='260' fill='url(#glowB)'/&amp;gt;&amp;lt;rect x='30' y='30' width='1220' height='660' rx='34' fill='rgba(255,255,255,0.035)' stroke='rgba(255,255,255,0.08)'/&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;304&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;368&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;416&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;470&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"smoothleft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='416' height='470' viewBox='0 0 416 470' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='card' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='rgba(255,255,255,0.13)'/&amp;gt;&amp;lt;stop offset='1' stop-color='rgba(255,255,255,0.05)'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;linearGradient id='panel' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#2dd4bf'/&amp;gt;&amp;lt;stop offset='1' stop-color='#4f73ff'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect x='0.5' y='0.5' width='415' height='469' rx='30' fill='url(#card)' stroke='rgba(255,255,255,0.14)'/&amp;gt;&amp;lt;rect x='30' y='30' width='138' height='32' rx='16' fill='rgba(45,212,191,0.14)' stroke='rgba(45,212,191,0.34)'/&amp;gt;&amp;lt;text x='99' y='51' text-anchor='middle' fill='#9ef3ea' font-size='14' font-family='Arial' font-weight='700'&amp;gt;JSON PAYLOAD&amp;lt;/text&amp;gt;&amp;lt;rect x='30' y='90' width='356' height='134' rx='22' fill='rgba(9,16,31,0.58)' stroke='rgba(255,255,255,0.08)'/&amp;gt;&amp;lt;rect x='30' y='244' width='356' height='82' rx='22' fill='rgba(9,16,31,0.58)' stroke='rgba(255,255,255,0.08)'/&amp;gt;&amp;lt;rect x='30' y='346' width='356' height='92' rx='22' fill='url(#panel)' opacity='0.92'/&amp;gt;&amp;lt;rect x='58' y='118' width='136' height='16' rx='8' fill='rgba(255,255,255,0.24)'/&amp;gt;&amp;lt;rect x='58' y='148' width='236' height='13' rx='6.5' fill='rgba(255,255,255,0.10)'/&amp;gt;&amp;lt;rect x='58' y='174' width='194' height='13' rx='6.5' fill='rgba(255,255,255,0.10)'/&amp;gt;&amp;lt;rect x='58' y='270' width='122' height='14' rx='7' fill='rgba(255,255,255,0.22)'/&amp;gt;&amp;lt;rect x='58' y='296' width='232' height='12' rx='6' fill='rgba(255,255,255,0.10)'/&amp;gt;&amp;lt;rect x='58' y='374' width='194' height='18' rx='9' fill='rgba(255,255,255,0.28)'/&amp;gt;&amp;lt;rect x='58' y='404' width='132' height='12' rx='6' fill='rgba(255,255,255,0.18)'/&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;874&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;146&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#9ef3ea; font-size:18px; font-weight:700; letter-spacing:1px;'&amp;gt;FROM JSON TO RENDERED VIDEO&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;874&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#ffffff; font-size:50px; font-weight:700; line-height:1.1;'&amp;gt;Define one scene in JSON, then let the API render it.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;874&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#d7def6; font-size:22px; line-height:1.45;'&amp;gt;Use the same payload pattern for demos, explainers, feed-driven videos, and automated campaign variations.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;820&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;556&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;340&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='display:inline-block; background:rgba(246,184,77,0.20); border:1px solid rgba(246,184,77,0.42); border-radius:24px; padding:16px 24px; color:#ffffff; font-size:22px; font-weight:700;'&amp;gt;Submit your first job&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;654&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:center; color:#c4cceb; font-size:16px;'&amp;gt;Start small: one payload, one job, one finished output.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnmqmbbqu61qqqju8ji9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnmqmbbqu61qqqju8ji9.webp" alt="Diagram showing how JSON fields map to a rendered video output in Zvid" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The payload stays reusable when each field has one clear job in the render.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The point of this example is not the design. It is the shape of the request. Once your app can build one valid payload consistently, generating videos from JSON becomes a normal systems problem instead of a manual export task.&lt;/p&gt;

&lt;p&gt;If you want remote media instead of an all-SVG tutorial card, the &lt;a href="https://docs.zvid.io/docs/structure/text-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Text Elements reference&lt;/a&gt; explains safe text and HTML rendering, while the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt; shows where images, videos, audio, and subtitles fit into the same payload model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Send the render job and poll status
&lt;/h2&gt;

&lt;p&gt;Once the payload shape makes sense, the rest is standard API work.&lt;/p&gt;

&lt;p&gt;Start by verifying authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/user/profile &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then submit a render request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"generate-video-from-json-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#0b1020"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello from Zvid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"fontSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"textAlign"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then poll the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.zvid.io/docs/getting-started?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Getting Started guide&lt;/a&gt; shows the same sequence with response examples, and the &lt;a href="https://docs.zvid.io/docs/endpoints/get-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Get render job status reference&lt;/a&gt; shows the fields you should expect in the poll response. Save the returned &lt;code&gt;jobId&lt;/code&gt;, track the job state, and only treat the render as done when the API returns a completed result.&lt;/p&gt;

&lt;p&gt;This is the second CTA most readers need: do not build a full queueing system first. Submit one valid payload, inspect one finished output, and then scale the workflow once the basic loop is solid.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSON prompt vs structured render payload
&lt;/h2&gt;

&lt;p&gt;Search results for JSON video generation often mix two related ideas: a JSON prompt for an AI video generator and a structured JSON payload for a video rendering API. They both use JSON, but they are not the same workflow.&lt;/p&gt;

&lt;p&gt;A JSON prompt for AI video generation usually describes creative intent for a model such as Sora, Veo, Google Veo 3, Veo 3.1, or Seedance. It may include camera motion, subject, lighting, style, dialogue, negative prompts, video length, and other prompt structure details. That can be useful when you want an AI-generated scene from text prompts or image generation inputs.&lt;/p&gt;

&lt;p&gt;A Zvid render payload is more deterministic. It describes the output video as a set of explicit fields: resolution, duration, frame rate, visuals, text, media URLs, timing, subtitles, and output format. That makes it better when you need consistent video production, on-brand layouts, product data, placeholders for text, and repeatable video rendering without manual editing.&lt;/p&gt;

&lt;p&gt;Use the AI prompt approach when the model should invent the shot. Use a structured render payload when your application already knows the content and needs to programmatically generate a video from structured JSON data.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSON templates for video automation
&lt;/h2&gt;

&lt;p&gt;A good JSON template separates stable design rules from dynamic content. The template might define the layout, animation timing, colors, subtitle placement, and output format. Your application can then inject the values that change, such as headline, CTA, product image, voiceover file, locale, or campaign name.&lt;/p&gt;

&lt;p&gt;That structure is what lets teams automate video creation instead of editing every output by hand. You can create a template once, validate it with a small payload, and then use the same JSON format to generate videos automatically for many variants.&lt;/p&gt;

&lt;p&gt;A practical template checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep required fields predictable, including &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;resolution&lt;/code&gt;, &lt;code&gt;duration&lt;/code&gt;, &lt;code&gt;frameRate&lt;/code&gt;, and &lt;code&gt;outputFormat&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Define placeholders for text, media URLs, subtitles, and optional campaign fields.&lt;/li&gt;
&lt;li&gt;Decide fallback behavior for missing images, long titles, unsupported formats, and empty CTA text.&lt;/li&gt;
&lt;li&gt;Keep scene layout logic separate from product, marketing, CRM, or spreadsheet data.&lt;/li&gt;
&lt;li&gt;Save the payload version so you can debug and regenerate the same video later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  JSON rendering vs manual editing
&lt;/h2&gt;

&lt;p&gt;The practical tradeoff is repeatability versus handcrafted flexibility.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual editing is better when every video needs one-off creative work.&lt;/li&gt;
&lt;li&gt;JSON rendering is better when the structure repeats and the inputs change.&lt;/li&gt;
&lt;li&gt;Manual editors optimize for human timeline work.&lt;/li&gt;
&lt;li&gt;JSON payloads optimize for systems that can generate many variations reliably.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v8po0a7xfe6a70izan6.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v8po0a7xfe6a70izan6.webp" alt="Comparison chart of manual video editing versus generating videos from JSON" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;JSON rendering wins when the scene repeats and the data changes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That is why JSON-driven rendering is common in catalog automation, localized campaign variants, onboarding sequences, personalized clips, and app-generated explainers. The same template logic can keep paying off long after the first demo works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use cases and integrations
&lt;/h2&gt;

&lt;p&gt;The strongest use case for a JSON to video workflow is repeatable output from structured data. That can include product videos, personalized videos, onboarding explainers, video marketing assets, social media content for TikTok or other channels, internal training clips, and automated status updates.&lt;/p&gt;

&lt;p&gt;Integration usually happens in one of three places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend jobs that build a payload and call the video API directly.&lt;/li&gt;
&lt;li&gt;Automation tools that trigger renders from forms, CRM changes, ecommerce events, or spreadsheet rows.&lt;/li&gt;
&lt;li&gt;Content pipelines where AI agents, copy tools, or image and video systems prepare assets before the final render request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is to keep the renderer's job clear. Zvid receives structured JSON, renders the video, and returns a finished output. Your surrounding workflow can decide where the content comes from, whether AI helps draft it, and where the completed video file should be stored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;The most common mistake is treating the payload like a one-off export instead of a reusable contract between your application and the renderer.&lt;/p&gt;

&lt;p&gt;Other problems show up repeatedly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mixing data cleanup with scene layout logic in the same step.&lt;/li&gt;
&lt;li&gt;Hard-coding text lengths and dimensions that only work for one example.&lt;/li&gt;
&lt;li&gt;Assuming a successful submit means the video is already finished.&lt;/li&gt;
&lt;li&gt;Skipping auth checks while debugging and then chasing the wrong problem.&lt;/li&gt;
&lt;li&gt;Designing a scene that looks good once but breaks with longer real inputs.&lt;/li&gt;
&lt;li&gt;Confusing prompt-based AI video generation with deterministic JSON video rendering.&lt;/li&gt;
&lt;li&gt;Forgetting to plan brand consistency across output sizes, languages, and channels.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another easy failure is making the first payload too ambitious. Start with one stable scene, short copy, and predictable layout. After that works, add remote media, subtitles, channel variants, and more dynamic inputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use Zvid
&lt;/h2&gt;

&lt;p&gt;Use Zvid when you want a hosted API that can turn structured video definitions into repeatable render jobs without building the rendering pipeline yourself.&lt;/p&gt;

&lt;p&gt;Zvid is a strong fit when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One payload model reused across many outputs.&lt;/li&gt;
&lt;li&gt;Public API endpoints for auth checks, render submission, and job polling.&lt;/li&gt;
&lt;li&gt;Control over timing, layout, text, and media through JSON.&lt;/li&gt;
&lt;li&gt;A workflow that fits backend jobs, automation systems, and data-driven products.&lt;/li&gt;
&lt;li&gt;A way to programmatically generate videos from JSON templates, not just a one-off visual editor export.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52n53myzgpmm6htknefi.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52n53myzgpmm6htknefi.webp" alt="Use cases for generating videos from JSON with the Zvid API" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One JSON-driven render system can support many outputs once the payload model is stable.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you only need occasional handcrafted edits, the API model may be unnecessary. If your inputs already exist as structured data, generating videos from JSON usually becomes much easier than maintaining the same work manually.&lt;/p&gt;

&lt;p&gt;If that matches your use case, try one Zvid payload today, confirm the finished output, and then expand the same pattern into your real templates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbby4v15wenvpewfrrf0i.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbby4v15wenvpewfrrf0i.webp" alt="Zvid JSON payload visual for generating a video from JSON" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The payload visual is generated from the real renderable example in this tutorial.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do I need a huge payload to get started?
&lt;/h3&gt;

&lt;p&gt;No. A small payload with one or two text elements is enough to prove the request flow first. Add more scene complexity only after you can submit jobs and track finished results reliably.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I convert JSON to video?
&lt;/h3&gt;

&lt;p&gt;Create a JSON payload that describes the video, send it to a render endpoint, save the returned job ID, and poll until the API returns a completed video URL. In Zvid, the public render endpoint accepts a &lt;code&gt;payload&lt;/code&gt; object and the jobs endpoint reports render status.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this the same as JSON prompting for AI video?
&lt;/h3&gt;

&lt;p&gt;Not exactly. JSON prompting for AI video describes a scene for a generative model. Zvid uses structured JSON as a render payload, which is better for explicit layouts, templates, brand consistency, subtitles, media placement, and repeatable output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use preset resolutions or custom width and height?
&lt;/h3&gt;

&lt;p&gt;Preset resolutions are usually the fastest starting point because they give you known output sizes. Use custom dimensions when your workflow needs a format that does not fit a preset cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I generate many videos from the same JSON structure?
&lt;/h3&gt;

&lt;p&gt;Yes. That is one of the main advantages of this approach. Keep the scene logic stable and swap the changing inputs such as title, CTA, media URL, language, or destination format.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I integrate JSON video rendering with my existing workflow?
&lt;/h3&gt;

&lt;p&gt;Yes. A backend service, automation tool, ecommerce job, CRM trigger, or spreadsheet workflow can prepare the structured data, create the JSON payload, call the API, and store the finished output URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long does it take to generate a video from JSON?
&lt;/h3&gt;

&lt;p&gt;The exact render time depends on video length, complexity, media assets, and queue state. The reliable pattern is to submit the job, poll status, and treat the video as ready only when the API returns a completed result.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I save from each render request?
&lt;/h3&gt;

&lt;p&gt;Save the payload version, returned &lt;code&gt;jobId&lt;/code&gt;, current state, and final output URL. That gives you enough context to debug, retry, and regenerate later.&lt;/p&gt;

&lt;p&gt;Generating a video from JSON is mostly about getting one reliable loop working: create the payload, submit the job, poll the result, and reuse the same structure as your content changes. Zvid gives you a public API for that exact workflow, so the next practical step is to send one small render job and inspect the finished output.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JSON to Video API: Convert JSON to Video with Zvid</title>
      <dc:creator>Mina Ramzy</dc:creator>
      <pubDate>Thu, 04 Jun 2026 10:16:28 +0000</pubDate>
      <link>https://dev.to/mena234/json-to-video-api-convert-json-to-video-with-zvid-3f40</link>
      <guid>https://dev.to/mena234/json-to-video-api-convert-json-to-video-with-zvid-3f40</guid>
      <description>&lt;p&gt;A JSON to video API lets you describe a video as structured JSON data, submit that payload to a rendering endpoint, and receive a finished video file when the job completes. If you need to convert JSON to video for templates, localization, product feeds, campaign variants, or app-generated clips, that is usually a better fit than rebuilding timelines manually in a GUI.&lt;/p&gt;

&lt;p&gt;The core workflow is simple: verify your API key, submit a &lt;code&gt;payload&lt;/code&gt; with a POST request to &lt;code&gt;/api/render/api-key&lt;/code&gt;, save the returned &lt;code&gt;jobId&lt;/code&gt;, and poll &lt;code&gt;GET /api/jobs/{id}&lt;/code&gt; until the render completes. Zvid documents that exact flow in the &lt;a href="https://docs.zvid.io/docs/getting-started?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Getting Started guide&lt;/a&gt;, the &lt;a href="https://docs.zvid.io/docs/authentication?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Authentication guide&lt;/a&gt;, and the &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt;. If you are evaluating the broader automation pattern, the same principles also appear in &lt;a href="https://zvid.io/blog/how-to-generate-1000-videos-automatically-with-an-api?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Generate 1,000 Videos Automatically with an API&lt;/a&gt; and &lt;a href="https://zvid.io/blog/how-to-create-product-videos-from-a-csv-or-product-feed?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;How to Create Product Videos from a CSV or Product Feed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfsuaqj4pe0btslpj24c.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfsuaqj4pe0btslpj24c.webp" alt="JSON to video API workflow hero illustration" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A JSON-to-video workflow turns structured inputs into repeatable renders.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is the public API shape most teams start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/user/profile &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;

curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.zvid.io/api/render/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @render-job.json

curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That request pattern matters more than any single example video. Once your application can generate valid payloads, submit jobs, and track results, the same system can power demos, onboarding videos, product videos, internal ops videos, ecommerce clips, or high-volume personalized output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a JSON to video API actually does
&lt;/h2&gt;

&lt;p&gt;A JSON to video API separates video intent from video rendering.&lt;/p&gt;

&lt;p&gt;Instead of storing a timeline only inside an editor, you send a structured description of the scene: canvas size, duration, background, visual layers, audio tracks, subtitle or caption timing, animation timing, and output format. The API validates that structure, queues the job, resolves any remote assets, renders the final composition, and returns a status object until the video is ready.&lt;/p&gt;

&lt;p&gt;That is why JSON-driven video is attractive for engineering teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is versionable and diffable like the rest of your application logic.&lt;/li&gt;
&lt;li&gt;It makes video templates reusable across many content variations.&lt;/li&gt;
&lt;li&gt;It fits cleanly into backend jobs, queues, and webhook or polling workflows.&lt;/li&gt;
&lt;li&gt;It removes manual export steps when the creative structure is mostly stable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only need one bespoke launch video, a traditional editing tool may still be faster. If you need the same video system to react to changing data, JSON starts to win.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to convert JSON to video
&lt;/h2&gt;

&lt;p&gt;At a high level, the lifecycle is: build the JSON payload, submit the render job, poll status, then store or publish the result URL. That is the practical answer to "how do I convert JSON to video?": the JSON file or JSON object becomes the source for layout, timing, media, text, and output settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpyx3d0lb92ujlsx1gqq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpyx3d0lb92ujlsx1gqq.webp" alt="JSON to video API workflow from payload to completed render" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A reliable render flow keeps payload generation, submission, and polling separate.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In practice, the flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate or retrieve the structured content your video needs.&lt;/li&gt;
&lt;li&gt;Map that content into one Zvid &lt;code&gt;payload&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;Send the payload to &lt;code&gt;POST https://api.zvid.io/api/render/api-key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Save the returned &lt;code&gt;jobId&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and any queue metadata.&lt;/li&gt;
&lt;li&gt;Poll &lt;code&gt;GET https://api.zvid.io/api/jobs/{id}&lt;/code&gt; until &lt;code&gt;state&lt;/code&gt; is &lt;code&gt;completed&lt;/code&gt; or &lt;code&gt;failed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;result.url&lt;/code&gt; when the render completes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can start with a static payload checked into your repo, then move to dynamically generated JSON once the first render works. For example, an ecommerce app might inject product names, prices, image URLs, and destination format into the same template. A localization workflow might keep the layout fixed while changing headline copy, subtitle language, and voiceover files.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.zvid.io/docs/endpoints/submit-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Submit render job&lt;/a&gt; and &lt;a href="https://docs.zvid.io/docs/endpoints/get-render-job?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Get render job status&lt;/a&gt; references are the key docs to keep open while you wire this up. If you want to make the workflow safer in production, the &lt;a href="https://docs.zvid.io/docs/endpoints/get-credit-balance?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Get credit balance&lt;/a&gt; and &lt;a href="https://docs.zvid.io/docs/endpoints/get-user-profile?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Get user profile&lt;/a&gt; references are also useful checks before you submit large batches.&lt;/p&gt;

&lt;p&gt;This is the first useful CTA for most readers: do not start with a huge pipeline. Start with one payload, one render job, and one completed output. Once that loop is stable, scaling is mostly an orchestration problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The anatomy of a Zvid payload
&lt;/h2&gt;

&lt;p&gt;Zvid's public docs define the render body as an object with a required &lt;code&gt;payload&lt;/code&gt;. Inside that payload, the main fields are &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;resolution&lt;/code&gt;, &lt;code&gt;duration&lt;/code&gt;, &lt;code&gt;frameRate&lt;/code&gt;, &lt;code&gt;outputFormat&lt;/code&gt;, &lt;code&gt;backgroundColor&lt;/code&gt;, &lt;code&gt;visuals&lt;/code&gt;, &lt;code&gt;audios&lt;/code&gt;, and &lt;code&gt;subtitle&lt;/code&gt;. Those JSON objects give you control over every aspect that matters in a template-driven render: element types, coordinates, media URLs, timing, and platform-ready output. The &lt;a href="https://docs.zvid.io/docs/structure?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;JSON Structure overview&lt;/a&gt;, &lt;a href="https://docs.zvid.io/docs/structure/properties/resolution-presets?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;ResolutionPreset reference&lt;/a&gt;, and &lt;a href="https://docs.zvid.io/docs/structure/text-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Text Elements reference&lt;/a&gt; are the most important references for understanding that shape.&lt;/p&gt;

&lt;p&gt;Below is a proof-friendly Zvid API payload that renders a short landscape explainer card. It uses &lt;code&gt;SVG&lt;/code&gt; and &lt;code&gt;TEXT&lt;/code&gt; elements only so the structure is easy to inspect and adapt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json-to-video-api-guide-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#08111f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='1280' height='720' viewBox='0 0 1280 720' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='bg' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#08111f'/&amp;gt;&amp;lt;stop offset='1' stop-color='#1c2448'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;radialGradient id='glowA' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(1040 120) rotate(90) scale(260)'&amp;gt;&amp;lt;stop stop-color='#2fd4c5' stop-opacity='0.22'/&amp;gt;&amp;lt;stop offset='1' stop-color='#2fd4c5' stop-opacity='0'/&amp;gt;&amp;lt;/radialGradient&amp;gt;&amp;lt;radialGradient id='glowB' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(220 640) rotate(90) scale(280)'&amp;gt;&amp;lt;stop stop-color='#f4b647' stop-opacity='0.18'/&amp;gt;&amp;lt;stop offset='1' stop-color='#f4b647' stop-opacity='0'/&amp;gt;&amp;lt;/radialGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect width='1280' height='720' fill='url(#bg)'/&amp;gt;&amp;lt;circle cx='1040' cy='120' r='260' fill='url(#glowA)'/&amp;gt;&amp;lt;circle cx='220' cy='640' r='280' fill='url(#glowB)'/&amp;gt;&amp;lt;rect x='36' y='36' width='1208' height='648' rx='32' fill='rgba(255,255,255,0.035)' stroke='rgba(255,255,255,0.08)'/&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SVG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;258&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;372&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;454&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"smoothleft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;svg width='372' height='454' viewBox='0 0 372 454' xmlns='http://www.w3.org/2000/svg'&amp;gt;&amp;lt;defs&amp;gt;&amp;lt;linearGradient id='card' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='rgba(255,255,255,0.14)'/&amp;gt;&amp;lt;stop offset='1' stop-color='rgba(255,255,255,0.05)'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;linearGradient id='panel' x1='0' y1='0' x2='1' y2='1'&amp;gt;&amp;lt;stop offset='0' stop-color='#2fd4c5'/&amp;gt;&amp;lt;stop offset='1' stop-color='#4f78ff'/&amp;gt;&amp;lt;/linearGradient&amp;gt;&amp;lt;/defs&amp;gt;&amp;lt;rect x='0.5' y='0.5' width='371' height='453' rx='30' fill='url(#card)' stroke='rgba(255,255,255,0.14)'/&amp;gt;&amp;lt;rect x='28' y='30' width='124' height='30' rx='15' fill='rgba(47,212,197,0.14)' stroke='rgba(47,212,197,0.30)'/&amp;gt;&amp;lt;text x='90' y='49' text-anchor='middle' fill='#9cf5eb' font-size='14' font-family='Inter' font-weight='700'&amp;gt;API READY&amp;lt;/text&amp;gt;&amp;lt;rect x='28' y='90' width='316' height='124' rx='20' fill='rgba(8,17,31,0.56)' stroke='rgba(255,255,255,0.08)'/&amp;gt;&amp;lt;rect x='28' y='234' width='316' height='78' rx='20' fill='rgba(8,17,31,0.56)' stroke='rgba(255,255,255,0.08)'/&amp;gt;&amp;lt;rect x='28' y='330' width='316' height='92' rx='20' fill='url(#panel)' opacity='0.92'/&amp;gt;&amp;lt;rect x='54' y='116' width='132' height='16' rx='8' fill='rgba(255,255,255,0.22)'/&amp;gt;&amp;lt;rect x='54' y='148' width='222' height='14' rx='7' fill='rgba(255,255,255,0.10)'/&amp;gt;&amp;lt;rect x='54' y='176' width='176' height='14' rx='7' fill='rgba(255,255,255,0.10)'/&amp;gt;&amp;lt;rect x='54' y='260' width='116' height='14' rx='7' fill='rgba(255,255,255,0.22)'/&amp;gt;&amp;lt;rect x='54' y='284' width='218' height='12' rx='6' fill='rgba(255,255,255,0.10)'/&amp;gt;&amp;lt;rect x='54' y='358' width='180' height='18' rx='9' fill='rgba(255,255,255,0.26)'/&amp;gt;&amp;lt;rect x='54' y='388' width='122' height='12' rx='6' fill='rgba(255,255,255,0.18)'/&amp;gt;&amp;lt;/svg&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;850&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#9cf5eb; font-size:18px; font-weight:700; letter-spacing:1px;'&amp;gt;STRUCTURED VIDEO WORKFLOW&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;850&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;258&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#ffffff; font-family:Poppins; font-size:46px; font-weight:700; line-height:1.12;'&amp;gt;Send JSON. Track jobs. Render videos at scale.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;850&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;426&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:left; color:#d7def6; font-size:22px; line-height:1.45;'&amp;gt;Define layout, timing, media, and output in JSON, then let the API queue and render the final video.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;850&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;556&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='display:inline-block; background:rgba(244,182,71,0.20); border:1px solid rgba(244,182,71,0.42); border-radius:24px; padding:16px 24px; color:#ffffff; font-size:22px; font-weight:700;'&amp;gt;Start with one render job&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;654&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enterAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitBegin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitEnd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exitAnimation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style='text-align:center; color:#c3cceb; font-size:16px;'&amp;gt;A small payload example is enough to prove the render loop before you scale it.&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq436j6omwgv02d2pa3m.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq436j6omwgv02d2pa3m.webp" alt="Diagram of a JSON to video API payload mapped to rendered output" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A payload stays useful when each field has a stable responsibility in the render.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The point of this example is not the design itself. The point is the shape: one object describes the video in a way your backend can generate repeatedly.&lt;/p&gt;

&lt;p&gt;For image-heavy workflows, the &lt;a href="https://docs.zvid.io/docs/structure/image-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Image Elements reference&lt;/a&gt; explains remote image handling, while the &lt;a href="https://docs.zvid.io/docs/structure/text-elements?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Text Elements reference&lt;/a&gt; covers the safe text and HTML options most teams use for headlines, labels, and CTAs.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical API request flow
&lt;/h2&gt;

&lt;p&gt;Once you understand the payload, the rest of the system is normal API engineering.&lt;/p&gt;

&lt;p&gt;Start by verifying auth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/user/profile &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check credits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/credits/balance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then submit a render request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json-to-video-api-guide-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frameRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outputFormat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#08111f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello from Zvid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"anchor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"fontSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"textAlign"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Poll until the job finishes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.zvid.io/api/jobs/&lt;span class="nv"&gt;$JOB_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.zvid.io/docs/getting-started?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=zvid_blog" rel="noopener noreferrer"&gt;Getting Started guide&lt;/a&gt; shows the same sequence with example responses. In production, the important discipline is to store the returned &lt;code&gt;jobId&lt;/code&gt;, track status transitions, and only treat the video as complete when the jobs endpoint returns a finished result.&lt;/p&gt;

&lt;p&gt;This is where the middle CTA makes sense: if you are still evaluating vendors or architecture, do not optimize for every edge case up front. Send one render, inspect the output, and confirm the API model fits how your product already stores data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video templates, animation, and dynamic output
&lt;/h2&gt;

&lt;p&gt;A JSON to video workflow works best when the template is treated as a system contract. The JSON can hold fixed design rules, dynamic fields, or both. Fixed rules might include frame rate, resolution, brand colors, text styles, and animation timing. Dynamic fields might include headline text, image URLs, subtitle files, product details, prices, CTAs, and output format.&lt;/p&gt;

&lt;p&gt;This is different from asking an AI video generator to interpret a loose text prompt. With structured JSON, the application can programmatically generate hundreds of videos while keeping the same layout and brand rules. You can still use AI-generated copy, images, or voiceovers upstream, but the render payload should stay explicit enough that the final video is predictable.&lt;/p&gt;

&lt;p&gt;For a scalable pipeline, keep three layers separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content data: the product, campaign, customer, or locale fields.&lt;/li&gt;
&lt;li&gt;Template rules: the scene layout, text animation, element types, and fallback behavior.&lt;/li&gt;
&lt;li&gt;Render orchestration: the API call, queue handling, retries, and final video URL storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Manual video tools vs JSON-driven rendering
&lt;/h2&gt;

&lt;p&gt;Most teams should not think of JSON rendering as a replacement for all creative tools. It is a replacement for repeated manual export work when the video structure is stable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual editors are better when every video needs hands-on creative changes.&lt;/li&gt;
&lt;li&gt;A JSON to video API is better when the same structure repeats across many variants.&lt;/li&gt;
&lt;li&gt;Manual editors optimize for one timeline at a time.&lt;/li&gt;
&lt;li&gt;JSON-driven rendering optimizes for systems that can generate many timelines safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbf6roy99760ff10l61tm.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbf6roy99760ff10l61tm.webp" alt="Comparison chart for manual editing versus JSON to video API workflows" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;JSON rendering is strongest when the structure repeats and the inputs change.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If your use case is catalog automation, localization, campaign fan-out, onboarding videos, or personalized clips, the same template logic can keep paying off. That is why high-volume and feed-driven use cases often move toward structured rendering instead of more manual editing.&lt;/p&gt;

&lt;h2&gt;
  
  
  No-code integrations and JSON2Video alternatives
&lt;/h2&gt;

&lt;p&gt;Some teams call a JSON to video API directly from a backend service. Others connect the same video automation workflow through no-code or low-code tools such as n8n, Zapier, Make, Shopify exports, CRM triggers, or scheduled spreadsheet jobs. The integration pattern is the same: collect structured data, generate the JSON payload, send the render request, and route the completed video file to the next system.&lt;/p&gt;

&lt;p&gt;You will also see tools and category terms such as JSON2Video, video editing API, dynamic video, and programmatic video creation API in this market. The useful comparison is not only feature count. Ask whether the platform gives you enough control over templates, output formats, media handling, watermarks, API key authentication, job status, and repeatable rendering without manual editing.&lt;/p&gt;

&lt;p&gt;For Zvid, the fit is structured video rendering through a hosted API. It is not positioned here as a prompt-only text-to-video model such as Sora, Veo, or Seedance, and it is not a hosting-only video API. It is for teams that want application data to become on-brand videos through explicit JSON payloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;The most common mistake is treating the JSON payload as a one-off export artifact instead of a reusable system contract.&lt;/p&gt;

&lt;p&gt;Other mistakes show up repeatedly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mixing business data cleanup with scene layout logic in the same step&lt;/li&gt;
&lt;li&gt;Hard-coding visual values that should come from reusable template rules&lt;/li&gt;
&lt;li&gt;Skipping credit or auth checks before large submissions&lt;/li&gt;
&lt;li&gt;Ignoring job-state tracking and assuming a successful submit means a finished render&lt;/li&gt;
&lt;li&gt;Designing templates that only work for one headline length, one locale, or one media shape&lt;/li&gt;
&lt;li&gt;Treating every provider as interchangeable without checking template control, integration needs, or output requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another common failure is overfitting the first demo. A payload can look fine with one short headline and then break once real inputs are longer, translated, or missing optional media. That is why repeatability matters more than getting one perfect screenshot.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use Zvid
&lt;/h2&gt;

&lt;p&gt;Use Zvid when you want a hosted API that turns structured video definitions into repeatable render jobs without building your own rendering pipeline.&lt;/p&gt;

&lt;p&gt;Zvid is a strong fit when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Programmatic video generation from structured app data&lt;/li&gt;
&lt;li&gt;One template system reused across many outputs&lt;/li&gt;
&lt;li&gt;Public API endpoints for auth checks, render submission, and job polling&lt;/li&gt;
&lt;li&gt;Support for timed text, SVG, images, videos, audio, and subtitle-driven workflows&lt;/li&gt;
&lt;li&gt;A scalable way to generate videos from JSON without manual editing for each variation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faj6gj8zovwwavz8rrn4k.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faj6gj8zovwwavz8rrn4k.webp" alt="Use cases for a JSON to video API across product and automation teams" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One structured video system can support many teams once the render loop is stable.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you only need occasional handcrafted exports, the API model may be unnecessary. If you already have structured content and want the output video to be just another system-generated asset, it becomes much more useful.&lt;/p&gt;

&lt;p&gt;The right next step is simple: build one small payload, render one finished video, and then decide whether your workflow needs more templates, more variations, or more orchestration around the same API core.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is a JSON to video API only for high-volume rendering?
&lt;/h3&gt;

&lt;p&gt;No. High volume is one use case, but the same model is useful even for smaller systems when you want predictable, repeatable output from structured content.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I convert JSON to video?
&lt;/h3&gt;

&lt;p&gt;Create a JSON payload that describes the video, send it to a render endpoint, save the returned job ID, and poll the job until the API returns a completed video URL. In Zvid, that means sending a &lt;code&gt;payload&lt;/code&gt; to the render endpoint and tracking the job status.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need to generate every field dynamically?
&lt;/h3&gt;

&lt;p&gt;Not at all. Most teams keep a mostly fixed template and only inject the fields that change, such as title, subtitle, CTA, product image, locale, or destination format.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I render multiple videos from different JSON inputs?
&lt;/h3&gt;

&lt;p&gt;Yes. Use the same template rules, generate one JSON object per variation, and submit one render job for each output. That is how teams generate videos automatically for product catalogs, localized campaigns, onboarding flows, and personalized clips.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I start with text and simple graphics before I add remote media?
&lt;/h3&gt;

&lt;p&gt;Yes. That is often the safest way to prove the payload model first. Then you can expand into remote images, video clips, audio, or subtitles as the use case gets more complex.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I connect a JSON to video workflow to n8n, Zapier, or Shopify?
&lt;/h3&gt;

&lt;p&gt;Yes, as long as the integration can prepare structured data and make authenticated API requests. Many teams use no-code tools for triggers and routing, while keeping template logic and render validation in application code.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I save from each render request?
&lt;/h3&gt;

&lt;p&gt;Save the payload version, the returned &lt;code&gt;jobId&lt;/code&gt;, the current job state, and the final output URL once the job completes. That gives you enough information to debug, retry, or regenerate later.&lt;/p&gt;

&lt;p&gt;If your product already thinks in structured inputs, a JSON to video API is usually the cleanest path to repeatable rendering. Start with one Zvid payload, one render job, and one completed output, then expand only after that loop feels reliable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi492nrfxy2dntalrrpm.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi492nrfxy2dntalrrpm.webp" alt="Zvid payload visual for a JSON to video API example" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The payload visual is generated from the article's real render example.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ffmpeg</category>
      <category>automation</category>
      <category>node</category>
    </item>
    <item>
      <title>JSON to Video</title>
      <dc:creator>Mina Ramzy</dc:creator>
      <pubDate>Wed, 25 Feb 2026 16:03:59 +0000</pubDate>
      <link>https://dev.to/mena234/json-video-33pd</link>
      <guid>https://dev.to/mena234/json-video-33pd</guid>
      <description>&lt;p&gt;I spent the last 1.5 years creating an open-source &lt;a href="https://www.npmjs.com/package/zvid" rel="noopener noreferrer"&gt;npm package&lt;/a&gt; that leverages FFMPEG to render videos at a large scale via JSON&lt;/p&gt;

&lt;p&gt;It supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Images, videos, GIFs, SVGs&lt;/li&gt;
&lt;li&gt;Text &amp;amp; HTML&lt;/li&gt;
&lt;li&gt;Audio&lt;/li&gt;
&lt;li&gt;Timing, Tracking, animations, transitions, filters, chroma key, zoom, styling, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why did I build it?
&lt;/h2&gt;

&lt;p&gt;Mainly for &lt;strong&gt;Video automation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nowadays, in the age of AI, automated videos are everywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;marketing videos&lt;/li&gt;
&lt;li&gt;social content at scale&lt;/li&gt;
&lt;li&gt;personalized videos&lt;/li&gt;
&lt;li&gt;programmatic content pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most existing tools are either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GUI-only (hard to automate)&lt;/li&gt;
&lt;li&gt;too low-level (FFmpeg scripts everywhere)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://zvid.io" rel="noopener noreferrer"&gt;Zvid&lt;/a&gt; &lt;strong&gt;sits in the middle.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it?
&lt;/h2&gt;

&lt;p&gt;You can use it with just one terminal prompt.&lt;/p&gt;

&lt;p&gt;First, make sure you have &lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;Node&lt;/a&gt;.js installed on your system.&lt;/p&gt;

&lt;p&gt;Create a JSON file to define your Video JSON structure (ex: &lt;code&gt;example.json&lt;/code&gt; )&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#753C73"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"visuals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Welcome, Zvid!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center-center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in the terminal run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx zvid render example.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I would love feedback on
&lt;/h2&gt;

&lt;p&gt;Feel free to check the source code from &lt;a href="https://github.com/Zvid-io/zvid" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. If you liked the idea and felt you would use it one day, don't forget to put a ⭐ on GitHub&lt;/p&gt;

&lt;p&gt;I’d also love your thoughts on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did you like the idea?&lt;/li&gt;
&lt;li&gt;What do you think are the best use cases?&lt;/li&gt;
&lt;li&gt;Would you share it with someone who needs it?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>ffmpeg</category>
      <category>npm</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
