Laura van Sinderen·2 October 2026 (updated)·14 min readIn this tutorial, you'll learn how to automate video generation from structured JSON using n8n and Creatomate, then download the video as an MP4.
When every video follows the same layout, a reusable template is usually the easiest way to automate production. But sometimes the structure itself needs to change - for example, the number of scenes, their duration, the elements they contain, or how they are animated.
In those cases, RenderScript gives you direct control over the complete video structure. It is Creatomate's JSON-based format for describing scenes, text, images, audio, animations, and timing. Creatomate turns those instructions into an MP4, GIF, JPEG, or PNG.
In this tutorial, we'll pass RenderScript from n8n directly to the Creatomate node. We'll begin with a basic animated text video to explain the essential properties. Then we'll replace it with a multi-scene RenderScript containing colors, transitions, and text animations. By the end, you'll have a workflow that renders videos from JSON and downloads the finished MP4 automatically.
{
"output_format": "mp4",
"width": 720,
"height": 1280,
"elements": [
{
"type": "composition",
"track": 1,
"time": 0,
"duration": 4.5,
"fill_color": "rgba(243,207,86,1)",
"elements": [
{
"type": "text",
"text": "This example video is entirely generated through code.",
"track": 1,
"time": 0,
"width": "95.2506%",
"height": "32.6602%",
"x_alignment": "50%",
"y_alignment": "50%",
"font_family": "Inter",
"font_weight": "700",
"line_height": "100%",
"fill_color": "rgba(0,0,0,1)",
"color_filter": "hue",
"animations": [
{
"easing": "linear",
"type": "scale",
"fade": false,
"scope": "element",
"start_scale": "70%"
},
{
"time": 0,
"duration": 1,
"easing": "back-in-out",
"type": "text-scale",
"split": "letter",
"track": 0
}
]
}
]
},
{
"type": "composition",
"track": 1,
"time": 3.5,
"duration": 4.5,
"fill_color": "rgba(73,128,241,1)",
"animations": [
{
"time": 0,
"duration": 1,
"transition": true,
"type": "circular-wipe"
}
],
"elements": [
{
"type": "text",
"text": "Define your entire video in code: scenes, layers, animations, audio, and timing.",
"track": 1,
"time": 0.5,
"width": "79.7626%",
"height": "37.8471%",
"x_alignment": "50%",
"y_alignment": "50%",
"font_family": "Inter",
"font_weight": "700",
"line_height": "100%",
"fill_color": "#ffffff",
"animations": [
{
"easing": "linear",
"type": "scale",
"fade": false,
"scope": "element",
"start_scale": "70%"
},
{
"time": 0,
"duration": 1,
"easing": "back-in-out",
"type": "text-scale",
"split": "letter",
"track": 0
}
]
}
]
},
{
"type": "composition",
"track": 1,
"duration": 4.5,
"fill_color": "rgba(60,174,163,1)",
"animations": [
{
"time": 0,
"duration": 0.87,
"transition": true,
"type": "circular-wipe"
}
],
"elements": [
{
"type": "text",
"text": "Build fully automated video pipelines driven by JSON.",
"track": 1,
"time": 0.5,
"width": "79.7626%",
"height": "37.8471%",
"x_alignment": "50%",
"y_alignment": "50%",
"font_family": "Inter",
"font_weight": "700",
"line_height": "100%",
"fill_color": "#ffffff",
"animations": [
{
"easing": "linear",
"type": "scale",
"fade": false,
"scope": "element",
"start_scale": "70%"
},
{
"time": 0,
"duration": 1,
"easing": "back-in-out",
"type": "text-scale",
"split": "letter",
"track": 0
}
]
}
]
}
]
}To create a video from JSON with n8n, pass a RenderScript object to the Creatomate node. The JSON defines the video format, dimensions, scenes, elements, animations, and timing. Creatomate interprets those instructions, renders the video, and returns a URL for the finished file.
In this tutorial, a Manual Trigger starts the workflow and an Edit Fields node supplies the RenderScript. The Creatomate node generates the video and waits until it is finished. An HTTP Request node then downloads the MP4 into n8n, where it can be passed to whatever file-handling node your workflow requires.
The workflow we'll build looks like this:

Let's get started!
In a real automation, the RenderScript could come from a database, webhook, Code node, another application, or an earlier part of the workflow. To keep this example easy to follow, we'll enter a ready-made JSON object using an Edit Fields node.
In your n8n dashboard, click Create workflow.
Click Add first step... and choose Trigger manually. The node appears on the canvas as When clicking 'Execute workflow':
Click the + after the trigger and add an Edit Fields (Set) node. Rename it RenderScript so it is easy to identify later.
Set Mode to JSON. Remove the example content and replace it with:
{
"output_format": "mp4",
"width": 720,
"height": 1280,
"elements": [
{
"type": "text",
"track": 1,
"width": "75%",
"height": "25%",
"x_alignment": "50%",
"y_alignment": "50%",
"text": "This video is generated from JSON data! 👋",
"font_family": "Noto Sans",
"fill_color": "#ffffff",
"animations": [
{
"time": 0,
"duration": 1,
"easing": "quadratic-out",
"type": "text-slide",
"scope": "element",
"split": "line",
"distance": "200%",
"direction": "right",
"background_effect": "disabled"
}
]
}
]
}The node should look like this:

The RenderScript contains everything Creatomate needs to generate the video:
output_format, width, and height define a 720-by-1280 MP4.elements contains everything that appears in the video. This example has one text element.type specifies that this is a text element.track places the element on track 1 of the timeline. When multiple elements use the same track, Creatomate arranges them one after another.width and height define the size of the text box, while x_alignment and y_alignment center the text inside it.text, font_family, and fill_color define the message and its appearance.animations array defines how the text enters the screen.Because no duration is specified, Creatomate determines the video length automatically.
This example uses only a small selection of the available RenderScript properties. For a complete reference, see the RenderScript documentation.
Click Execute step. The output should contain the complete RenderScript object:

The JSON is ready to be rendered.
Click the + after the RenderScript node and search for Creatomate.
If you haven't used the node before, open its details and click Install node. n8n installs the verified Creatomate node into your workspace:

After installation, select Create a render under Render actions:

Connect your Creatomate account
Under Credential, click Connect to Creatomate:

In a separate browser tab, return to Creatomate. Click your project in the top-left corner and choose Project Settings. Open the API section and copy the API key for this project:
Back in n8n, paste the key into the Creatomate credential and click Save:

An API key belongs to one Creatomate project. If you use multiple projects, create a separate n8n credential for each one.
Pass the RenderScript to Creatomate
Return to the Creatomate node and configure it as follows:
The RenderScript field appears with a small example JSON object. Replace the complete example with:
{{ $json }}
When you enter the expression, n8n switches the field to expression mode automatically. Because the Creatomate node follows the RenderScript node directly, {{ $json }} represents the complete JSON object created in step 1. A preview beginning with [Object: should appear underneath, confirming that the entire RenderScript object will be passed to Creatomate:

Tip: {{ $json }} works here because the incoming item contains only the RenderScript. If your item also contains other data, store the video definition in a separate object, such as renderScript, and map only that object using {{ $json.renderScript }}.
Render the video
Before running the node, leave Wait for Completion enabled. This ensures that the Creatomate node waits for the completed render and returns the finished file URL, so the next node can use it immediately.
Click Execute step. Creatomate validates the RenderScript, generates the video, and returns the completed render. The output should show status as succeeded and include a public url for the MP4:

Open the URL to watch the generated video:
You can also review the render on the API Log page in Creatomate. It shows the render status, processing time, resolution, Creatomate credit usage, and video output. If a render fails, the API Log also displays the complete error details:

The Creatomate node returns a public URL for the finished video. We'll use that URL to download the actual MP4 into n8n so it can be passed to nodes that require a file.
Click the + after the Creatomate node and add an HTTP Request node. Rename it Download Video.
Configure it as follows:
{{ $json.url }}Under Options, add Response and configure:
dataNo authentication is required because the finished video is available through a public URL:

Click Execute step. Open the Binary tab to verify that the output contains a file named data:

The video is now available in n8n as binary data in the data field. From here, you can pass the file to whatever node your workflow requires - for example, to upload it to social media or cloud storage, attach it to an email, or send it to another workflow.
For this tutorial, we'll keep the same workflow and replace only the RenderScript to generate a more advanced multi-scene video.
Return to the RenderScript node. Replace the existing JSON with:
{
"output_format": "mp4",
"width": 720,
"height": 1280,
"elements": [
{
"type": "composition",
"track": 1,
"time": 0,
"duration": 4.5,
"fill_color": "rgba(243,207,86,1)",
"elements": [
{
"type": "text",
"text": "This example video is entirely generated through code.",
"track": 1,
"time": 0,
"width": "95.2506%",
"height": "32.6602%",
"x_alignment": "50%",
"y_alignment": "50%",
"font_family": "Inter",
"font_weight": "700",
"line_height": "100%",
"fill_color": "rgba(0,0,0,1)",
"color_filter": "hue",
"animations": [
{
"easing": "linear",
"type": "scale",
"fade": false,
"scope": "element",
"start_scale": "70%"
},
{
"time": 0,
"duration": 1,
"easing": "back-in-out",
"type": "text-scale",
"split": "letter",
"track": 0
}
]
}
]
},
{
"type": "composition",
"track": 1,
"time": 3.5,
"duration": 4.5,
"fill_color": "rgba(73,128,241,1)",
"animations": [
{
"time": 0,
"duration": 1,
"transition": true,
"type": "circular-wipe"
}
],
"elements": [
{
"type": "text",
"text": "Define your entire video in code: scenes, layers, animations, audio, and timing.",
"track": 1,
"time": 0.5,
"width": "79.7626%",
"height": "37.8471%",
"x_alignment": "50%",
"y_alignment": "50%",
"font_family": "Inter",
"font_weight": "700",
"line_height": "100%",
"fill_color": "#ffffff",
"animations": [
{
"easing": "linear",
"type": "scale",
"fade": false,
"scope": "element",
"start_scale": "70%"
},
{
"time": 0,
"duration": 1,
"easing": "back-in-out",
"type": "text-scale",
"split": "letter",
"track": 0
}
]
}
]
},
{
"type": "composition",
"track": 1,
"duration": 4.5,
"fill_color": "rgba(60,174,163,1)",
"animations": [
{
"time": 0,
"duration": 0.87,
"transition": true,
"type": "circular-wipe"
}
],
"elements": [
{
"type": "text",
"text": "Build fully automated video pipelines driven by JSON.",
"track": 1,
"time": 0.5,
"width": "79.7626%",
"height": "37.8471%",
"x_alignment": "50%",
"y_alignment": "50%",
"font_family": "Inter",
"font_weight": "700",
"line_height": "100%",
"fill_color": "#ffffff",
"animations": [
{
"easing": "linear",
"type": "scale",
"fade": false,
"scope": "element",
"start_scale": "70%"
},
{
"time": 0,
"duration": 1,
"easing": "back-in-out",
"type": "text-scale",
"split": "letter",
"track": 0
}
]
}
]
}
]
}The top-level properties are unchanged, so the output is still a 720-by-1280 MP4. Here's how this RenderScript builds on the first example:
elements array contains three composition elements. Each composition contains a text element and acts as one scene in the video.track: 1 and have a duration of 4.5 seconds. The first starts at time: 0, while the second starts at time: 3.5, overlapping the first by one second. Because the third composition has no time value, Creatomate positions it automatically on the same track.fill_color on each composition sets its background color. The nested text elements have their own fill_color and animations.transition: true with type: circular-wipe to transition from the previous scene.This pattern can be extended with additional scenes and other element types, including images, videos, audio, and shapes.
Close the RenderScript node and return to the workflow canvas. Click Execute workflow to run all four nodes from the beginning. n8n passes the updated RenderScript to Creatomate, waits for the multi-scene video to finish, and downloads the new MP4 automatically.

When the workflow finishes, all four nodes should have completed successfully.
Open the Download Video node and select the Binary tab. The data field should now contain the newly generated multi-scene MP4. Click View to watch it:

Here's the finished video:
That's it! The workflow can now turn a RenderScript JSON object into a finished video and download the MP4 automatically.
The Manual Trigger and fixed JSON make the workflow easy to test. In a production automation, the trigger and RenderScript can come from any source that fits your process.
For example, you could:
If the next node accepts a public URL, you can use the url returned by Creatomate directly. Use the downloaded data file when the destination requires binary input.
RenderScript offers complete flexibility, but that also means your workflow is responsible for the design and structure. If the layout stays mostly the same between renders, consider using a reusable Creatomate template and only map the content that changes.
When the RenderScript is created dynamically, validate its structure before producing videos at scale. The Creatomate node must receive a valid JSON object, and the API Log provides complete details for RenderScript validation errors and other render failures.
For more examples and reference material, see:
👉 How to Create Videos from JSON
👉 JSON-to-Video: Practical Examples
👉 RenderScript documentation
Whether you prefer code or no-code, we have a wide range of guides on video automation.