Create Studio Template
Create a single studio template programmatically via API
Enterprise Only
This is an Enterprise only private endpoint. Checkout the Enterprise Pricing to get access.
Create a new studio template in your workspace programmatically. This endpoint allows you to define the template structure, dimensions, and optionally include pre-built pages with elements.
For detailed information about the template data structure, see Anatomy of a Template.
Endpoint#
https://api.orshot.com/v1/studio/templates/createQuery Parameters#
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
includeThumbnails | Boolean | No | false | When true, the endpoint renders a thumbnail for every page and waits for all uploads before responding. When false or absent, thumbnails are generated asynchronously after the response is sent. |
Request#
// Create a blank template with specified dimensions
await fetch("https://api.orshot.com/v1/studio/templates/create", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <ORSHOT_API_KEY>",
},
body: JSON.stringify({
name: "Product Banner",
description: "E-commerce product showcase banner",
canvas_width: 1200,
canvas_height: 628,
embed_user_id: "your-external-user-id" // Optional
}),
});Rate Limits#
| Limit | Value |
|---|---|
| Requests per minute | 30 |
Request Body Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Name of the template (max 255 characters) |
description | String | No | Description of the template |
canvas_width | Integer | Yes | Width of the canvas in pixels (1-5000) |
canvas_height | Integer | Yes | Height of the canvas in pixels (1-5000) |
pages_data | Array | No | Array of page objects with elements. If not provided, a blank page is created |
tags | Array | No | Array of tag strings to categorize the template (e.g. ["social", "marketing"]) |
thumbnail_url | String | No | URL to a thumbnail image for the template |
embed_user_id | String | No | Assign the template to an embed user. Accepts either an external user ID (which will be resolved using your workspace's embed configuration) or an Orshot internal ID (prefixed with eui_). |
Pages Data Structure#
Each page in the pages_data array should follow this structure:
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier for the page (UUID recommended) |
name | String | Name of the page (e.g., "Page 1") |
canvas | Object | Canvas settings { width, height, backgroundColor } |
elements | Array | Array of element objects (text, image, shapes, etc.) |
modifications | Array | Array of parameterizable modifications |
thumbnail_url | String | URL to page thumbnail |
Response Fields#
| Field | Type | Description |
|---|---|---|
success | Boolean | Whether the operation was successful |
template.id | Integer | Unique identifier for the created template |
template.name | String | Name of the template |
template.canvas_width | Integer | Canvas width in pixels |
template.canvas_height | Integer | Canvas height in pixels |
template.tags | Array | Tags assigned to the template |
template.pages_count | Integer | Number of pages in the template |
template.modifications | Array | List of parameterizable modifications extracted from elements |
template.created_at | String | ISO timestamp of creation |
template.thumbnails | Object | Only present when ?includeThumbnails=true. See Thumbnails Object Structure below |
Modification Object Structure#
Each modification in template.modifications contains:
| Field | Type | Description |
|---|---|---|
key | String | Unique key for the modification. For multi-page templates this is prefixed, e.g. page1@headline |
id | String | Same as key |
type | String | Type of modification (text, imageUrl, videoUrl, backgroundColor, fill, color, stroke) |
description | String | Human-readable description, e.g. "Headline — Text content" or "Image URL" when no element name is set |
help_text | String | Same as description |
element_name | String | Layer name of the element in the editor (only present when the element has a name) |
example | String | Default/example value for the field |
page_number | Integer | 1-based page number this modification belongs to |
page_id | String | Stable UUID of the page this modification belongs to — use this to reliably map modifications to pages after reorder |
Error Responses#
| Status Code | Error | Description |
|---|---|---|
| 400 | Validation failed | Invalid request body parameters |
| 403 | Access Forbidden | Invalid or missing API key |
| 429 | Rate limit exceeded | Too many requests (max 30/min) |
| 500 | Internal server error | Server-side error |
Thumbnails Object Structure#
When you pass ?includeThumbnails=true, the endpoint renders a PNG thumbnail for each page using the same scale convention as the Studio editor (capped at 1200×1200, never upscaled). The returned template.thumbnails object has this shape:
{
"success": true,
"pages": [
{ "page": 1, "page_id": "...", "thumbnail_url": "https://...", "error": null },
{ "page": 2, "page_id": "...", "thumbnail_url": "https://...", "error": null }
]
}| Field | Type | Description |
|---|---|---|
success | Boolean | true if at least one page rendered successfully |
pages[].page | Integer | 1-based page number |
pages[].page_id | String | Stable UUID of the page |
pages[].thumbnail_url | String|null | Public URL of the uploaded thumbnail PNG. null if this specific page failed |
pages[].error | String|null | Error message if this page failed. null on success |
Asynchronous thumbnails#
When ?includeThumbnails=true is not set (the default), the endpoint responds immediately and generates thumbnails in the background. The thumbnails will appear on the template (via pages_data[].thumbnail_url and pages_meta[].thumbnail_url) shortly after creation — typically within a few seconds per page. Use GET /v1/studio/templates/:templateId to fetch the current state.
Pass ?includeThumbnails=true only when your workflow needs the thumbnail URLs in the same response (e.g., you're about to render or display the template immediately). Sync mode adds ~1–2 seconds per page to the response time.
Notes#
- If
pages_datais not provided, a blank page with the specified dimensions is automatically created - Elements with
parameterizable: trueand aparameterIdwill be automatically extracted as modifications - The
modificationsarray in the response shows which dynamic parameters are available for rendering - When
embed_user_idis provided, the template will be associated with the specified embed user. If you pass your own external user ID, it will be resolved to an internal Orshot ID using the embed configuration linked to your workspace. You can also pass an Orshot internal ID directly (format:eui_followed by 16 alphanumeric characters).
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