Render from Studio Template
Learn how you can make a POST request to render from a custom template on Orshot
What are Studio Templates?#
Templates that you've designed in Orshot Studio are Studio Templates. These templates are custom designs that you can customize and paramterize
You can render content from a custom template that you've designed using Orshot Studio by making POST request to Orshot API
https://api.orshot.com/v1/studio/renderPOST Request#
await fetch("https://api.orshot.com/v1/studio/render", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <ORSHOT_API_KEY>",
},
body: JSON.stringify({
templateId: <TEMPLATE_ID>,
modifications: {
canvasBackgroundColor: "#eff2fa", // Supports CSS Color Values(HEX, RGBA, linear-gradient)
canvasBackgroundImage: "https://acme.com/public/web-background.png",
title: "Custom Title",
imageUrl: "Custom Image URL",
},
response : {
type: "base64",
format: "png",
scale: 1, // control scale of the image/pdf, scale = 1(set size), 2 = double the size
includePages: [1, 3], // only for multi-page templates
fileName: "" // specify custom file name(without extension) for output file
},
pdfOptions : { // applicable only if response.format is "pdf"
margin: "20px",
rangeFrom: 1, // show only from page 1(set to "null" to show all pages)
rangeTo: 2, // to page 2(set to "null" to show all pages)
colorMode: "rgb", // set color mode for PDFs (supports "rgb" and "cmyk")
dpi: 300, // set DPI for the PDF
},
videoOptions: { // applicable only if response.format is "mp4", "webm", or "gif"
fps: 30,
quality: 80,
trimStart: 0,
trimEnd: 20,
muted: true,
audioSource: "https://acme.com/public/background-music.mp3", // override or add audio
subtitleSource: "https://acme.com/public/subtitles.srt",
subtitleFontSize: "30px",
subtitleFontWeight: "700",
subtitleColor: "#ffffff",
subtitleBackground: "rgba(0,0,0,0.5)",
subtitleFontFamily: "Inter, sans-serif",
subtitlePosition: "bottom", // "bottom" or "top"
subtitleOffset: "50px",
combinePages: true, // optional, only for multi-page mp4/webm
pageTransition: "fade", // optional
pageTransitionDuration: 0.5, // optional, 0.1 to 2 seconds
},
publish: { // optional — publish render to connected social accounts
accounts: [1, 2], // social account IDs from your workspace
content: "Check out our latest design!", // caption for the post
},
}),
});Response Structure#
{
"data": {
"content": "data:image/png;base64,iVBORw0.....",
"format": "png",
"type": "base64",
"responseTime": 325.22
},
// only if publish object was included in the request
"publish": [
{ "platform": "twitter", "username": "acmehq", "status": "published" },
{ "platform": "instagram", "username": "acmeinsta", "status": "published" }
]
}Single Page Templates#
- Templates with only one page
- Response can be accessed at the value at
data.content, it's instringformat - (base64 format + binary type) response combination isn't supported
Multi Page Templates#
- Templates with more than one pages
- Response can be accessed at
data.content, it's inarrayformat with content - Each array entry includes
page(1-based page number) andpageId(stable UUID of the page). PreferpageIdwhen your workflow needs to reference a specific page — page numbers shift when pages are reordered, whilepageIdis stable for the lifetime of the page - For multi-page video renders (
mp4/webm), setvideoOptions.combinePages: trueto return one combined video instead of per-page video files
Parameters#
templateId: Each Studio template has a unique templateId(integer) which you can see on Template's page or paygroundmodifications: Object structure of the dynamic modidifcations that you've set in the template. Additionally, you can also use style parameters to dynamically set styles for your layers, learn moreresponse.format- Supportspng,webp,jpg,avif,pdf,mp4,webm,gifresponse.typeresponse.fileName: works only when the response type is eitherurlorbinary, can be used to specify custom file name for the output files. In carousel templates, the file name will be suffixed by-page-1,-page-2etc. Also ifresponse/formatis set tourl, the custom file name will be suffixed with-[UNIQUE_HASH]to make sure it's a unique filepdfOptions: Optional object for PDF renders (response.format: "pdf")pdfOptions.margin: Global margin around PDF content (example:"20px")pdfOptions.rangeFrom: Start page for PDF range selectionpdfOptions.rangeTo: End page for PDF range selectionpdfOptions.colorMode: Color mode ("rgb"or"cmyk")pdfOptions.dpi: Output DPI (commonly72,150,300)pdfOptions.marginTop: Optional top margin overridepdfOptions.marginBottom: Optional bottom margin overridepdfOptions.marginLeft: Optional left margin overridepdfOptions.marginRight: Optional right margin override- See PDF Options for behavior details and print recommendations
videoOptions: Optional object for video renders (mp4,webm,gif)videoOptions.fps: Output FPS (1-30)videoOptions.quality: Video quality (1-100)videoOptions.trimStart: Global trim start in seconds (works withtrimEnd)videoOptions.trimEnd: Global trim end in seconds (works withtrimStart)videoOptions.duration: Fallback output duration in seconds when trim range is not providedvideoOptions.muted: Global audio control (true= mute all output audio including page audio,false= include audio from video elements and page-level audio)videoOptions.audioSource: Override or add audio at render time (per-track, not a wholesale replacement)string: overrides the first audio track's URL on each rendered page (applies to both single-page and multi-page templates)array: per-page and per-track overrides for targeted control, e.g.[{ page: 1, url: "..." }]or[{ pageId: "uuid", url: "..." }]. Usetrack(0-based index) to target a specific audio track. Non-targeted tracks are preserved
videoOptions.subtitleSource: Subtitle input source (overrides page-level subtitles if set)string: single subtitle/audio/video/SRT URL for single-page templatesarray: page-mapped sources for multi-page templates, e.g.[{ page: 1, url: "..." }]or[{ pageId: "uuid", url: "..." }]
videoOptions.subtitleFontSize: Subtitle font size (CSS size string, e.g."30px")videoOptions.subtitleFontWeight: Subtitle font weight (e.g."700")videoOptions.subtitleColor: Subtitle text colorvideoOptions.subtitleBackground: Subtitle background colorvideoOptions.subtitleFontFamily: Subtitle font familyvideoOptions.subtitlePosition: Subtitle position ("bottom"or"top")videoOptions.subtitleOffset: Distance from positioned edge (e.g."50px", replacessubtitleBottom)videoOptions.subtitlePaddingX: Horizontal padding (e.g."16px")videoOptions.subtitlePaddingY: Vertical padding (e.g."8px")videoOptions.subtitleBorderRadius: Corner radius (e.g."6px")videoOptions.subtitleShadowX: Text shadow X offset in pxvideoOptions.subtitleShadowY: Text shadow Y offset in pxvideoOptions.subtitleShadowBlur: Text shadow blur radius in pxvideoOptions.subtitleShadowColor: Text shadow colorvideoOptions.combinePages: Combine multi-page videos into one output video (supported only for multi-pagemp4andwebm)videoOptions.pageTransition: Optional transition whencombinePagesis enabled- Supported values:
fade,fadeblack,fadewhite,dissolve,wipeleft,wiperight,wipeup,wipedown,slideleft,slideright,slideup,slidedown,circleopen,circleclose,pixelize - Use
"none"or omit for hard cuts
- Supported values:
videoOptions.pageTransitionDuration: Transition duration in seconds (0.1to2)- See Video Options for behavior details and examples
publish: Optional object to publish the render directly to connected social accountspublish.accounts: Array of social account IDs from your workspacepublish.content: Caption/text for the social postpublish.isDraft: Set totrueto save as draft instead of publishingpublish.schedule.scheduledFor: ISO date string to schedule the post for laterpublish.timezone: Timezone string (e.g."America/New_York") for schedulingpublish.platformOptions: Per-account options keyed by account ID (e.g. LinkedInfirstComment, Pinteresttitle/link). See Publish from API
Video Generation#
For templates with video elements, you can render them as video files by setting response.format to mp4, webm, or gif.
await fetch("https://api.orshot.com/v1/studio/render", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <ORSHOT_API_KEY>",
},
body: JSON.stringify({
templateId: <TEMPLATE_ID>,
modifications: {
"videoElement": "https://example.com/custom-video.mp4", // Dynamic video URL
"videoElement.trimStart": 0, // Start time in seconds
"videoElement.trimEnd": 10, // End time in seconds
"videoElement.muted": false, // Include audio
"videoElement.loop": true, // Loop the video
},
videoOptions: { // global video option
trimStart: 0, // in seconds
trimEnd: 20, // in seconds
muted: true,
combinePages: true, // optional, only for multi-page mp4/webm
pageTransition: "fade", // optional transition between pages
pageTransitionDuration: 0.5, // optional, seconds (0.1 to 2)
},
response: {
type: "url",
format: "mp4", // or "webm", "gif"
},
}),
});Video Parameters#
For video elements with a parameter ID set, you can pass dynamic video properties:
{parameterId}- Custom video URL{parameterId}.trimStart- Start time in seconds{parameterId}.trimEnd- End time in seconds{parameterId}.muted-trueorfalsefor audio{parameterId}.loop-trueorfalsefor looping
Global videoOptions#
All supported videoOptions fields are listed above in the Parameters section.
Page-Level Audio & Subtitles#
Pages can have multiple audio tracks (e.g., background music + voiceover) and subtitles configured directly in the Studio editor. These are automatically included when rendering videos:
- Page audio tracks are mixed into the output alongside any video element audio. Use
videoOptions.muted: trueto mute everything. UsevideoOptions.audioSourceto override or add audio URLs at render time. - Page subtitles (uploaded SRT or auto-generated from audio) are used as a fallback when no
videoOptions.subtitleSourceis provided. Subtitle styles set in the editor are applied automatically, but can be overridden withvideoOptions.subtitle*properties.
Audio and subtitles configured in Studio work automatically. To override audio at render time, use videoOptions.audioSource:
{
"videoOptions": {
"audioSource": "https://example.com/background-music.mp3"
}
}For multi-page templates with per-page audio (you can use page number or pageId UUID — pageId is stable when pages are reordered):
{
"videoOptions": {
"audioSource": [
{ "page": 1, "url": "https://example.com/intro.mp3" },
{ "pageId": "a1b2c3d4-5e6f-7890-abcd-ef1234567890", "url": "https://example.com/main.mp3" }
]
}
}Combining Multi-Page Videos#
By default, multi-page video renders return one output per page.
To get one final combined video, pass videoOptions.combinePages: true.
await fetch("https://api.orshot.com/v1/studio/render", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <ORSHOT_API_KEY>",
},
body: JSON.stringify({
templateId: <TEMPLATE_ID>,
response: {
type: "url",
format: "webm",
includePages: [1, 2, 3],
},
videoOptions: {
combinePages: true,
pageTransition: "fade", // optional
pageTransitionDuration: 0.5, // optional
},
}),
});combinePages is supported only for multi-page mp4 and webm renders. GIF
renders always return per-page outputs.
Ready to automate?
Start rendering images, PDFs and videos from your templates in under 2 minutes. Free plan, no credit card.
Get your API key- Image, PDF and video generation via API
- Visual editor with AI and smart layouts
- Zapier, Make, MCP and 50+ integrations
- White-label embed for your own app
- 60 free renders — no credit card required