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/render

POST 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 in string format
  • (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 in array format with content
  • Each array entry includes page (1-based page number) and pageId (stable UUID of the page). Prefer pageId when your workflow needs to reference a specific page — page numbers shift when pages are reordered, while pageId is stable for the lifetime of the page
  • For multi-page video renders (mp4/webm), set videoOptions.combinePages: true to 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 payground
  • modifications: 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 more
  • response.format - Supports png, webp, jpg, avif, pdf, mp4, webm, gif
  • response.type
  • response.fileName: works only when the response type is either url or binary, 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-2 etc. Also if response/format is set to url, the custom file name will be suffixed with -[UNIQUE_HASH] to make sure it's a unique file
  • pdfOptions: Optional object for PDF renders (response.format: "pdf")
    • pdfOptions.margin: Global margin around PDF content (example: "20px")
    • pdfOptions.rangeFrom: Start page for PDF range selection
    • pdfOptions.rangeTo: End page for PDF range selection
    • pdfOptions.colorMode: Color mode ("rgb" or "cmyk")
    • pdfOptions.dpi: Output DPI (commonly 72, 150, 300)
    • pdfOptions.marginTop: Optional top margin override
    • pdfOptions.marginBottom: Optional bottom margin override
    • pdfOptions.marginLeft: Optional left margin override
    • pdfOptions.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 with trimEnd)
    • videoOptions.trimEnd: Global trim end in seconds (works with trimStart)
    • videoOptions.duration: Fallback output duration in seconds when trim range is not provided
    • videoOptions.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: "..." }]. Use track (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 templates
      • array: 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 color
    • videoOptions.subtitleBackground: Subtitle background color
    • videoOptions.subtitleFontFamily: Subtitle font family
    • videoOptions.subtitlePosition: Subtitle position ("bottom" or "top")
    • videoOptions.subtitleOffset: Distance from positioned edge (e.g. "50px", replaces subtitleBottom)
    • 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 px
    • videoOptions.subtitleShadowY: Text shadow Y offset in px
    • videoOptions.subtitleShadowBlur: Text shadow blur radius in px
    • videoOptions.subtitleShadowColor: Text shadow color
    • videoOptions.combinePages: Combine multi-page videos into one output video (supported only for multi-page mp4 and webm)
    • videoOptions.pageTransition: Optional transition when combinePages is 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
    • videoOptions.pageTransitionDuration: Transition duration in seconds (0.1 to 2)
    • See Video Options for behavior details and examples
  • publish: Optional object to publish the render directly to connected social accounts
    • publish.accounts: Array of social account IDs from your workspace
    • publish.content: Caption/text for the social post
    • publish.isDraft: Set to true to save as draft instead of publishing
    • publish.schedule.scheduledFor: ISO date string to schedule the post for later
    • publish.timezone: Timezone string (e.g. "America/New_York") for scheduling
    • publish.platformOptions: Per-account options keyed by account ID (e.g. LinkedIn firstComment, Pinterest title/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 - true or false for audio
  • {parameterId}.loop - true or false for 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: true to mute everything. Use videoOptions.audioSource to 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.subtitleSource is provided. Subtitle styles set in the editor are applied automatically, but can be overridden with videoOptions.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
    },
  }),
});

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