Update Template
Update template metadata, dimensions or complete page structure
Updated
/v1/studio/templates/{templateId}/updatecurl -X PATCH "https://api.orshot.com/v1/studio/templates/<TEMPLATE_ID>/update" \
-H "Authorization: Bearer <ORSHOT_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"name": "<NAME>",
"description": "<DESCRIPTION>",
"tags": [],
"canvas_width": 1
}'const res = await fetch("https://api.orshot.com/v1/studio/templates/<TEMPLATE_ID>/update", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <ORSHOT_API_KEY>",
},
body: JSON.stringify({
"name": "<NAME>",
"description": "<DESCRIPTION>",
"tags": [],
"canvas_width": 1
}),
});
const data = await res.json();import requests
response = requests.patch(
"https://api.orshot.com/v1/studio/templates/<TEMPLATE_ID>/update",
headers={"Authorization": "Bearer <ORSHOT_API_KEY>"},
json={
"name": "<NAME>",
"description": "<DESCRIPTION>",
"tags": [],
"canvas_width": 1
},
)
data = response.json()$ch = curl_init("https://api.orshot.com/v1/studio/templates/<TEMPLATE_ID>/update");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer <ORSHOT_API_KEY>",
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"name" => "<NAME>",
"description" => "<DESCRIPTION>",
"tags" => [],
"canvas_width" => 1
]));
$data = json_decode(curl_exec($ch), true);
curl_close($ch);require "net/http"
require "json"
uri = URI("https://api.orshot.com/v1/studio/templates/<TEMPLATE_ID>/update")
req = Net::HTTP::Patch.new(uri)
req["Authorization"] = "Bearer <ORSHOT_API_KEY>"
req["Content-Type"] = "application/json"
req.body = {
"name": "<NAME>",
"description": "<DESCRIPTION>",
"tags": [],
"canvas_width": 1
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)Enterprise Only
This endpoint is available only to first party clients like the Orshot MCP server and workspaces on the Enterprise plan. Check out Enterprise pricing to get access.
Update an existing studio template. You can update metadata (name, description, tags), canvas dimensions, or the full page structure including elements.
Which update endpoint?#
| You want to change | Use |
|---|---|
| Name, tags, the default canvas size, or the entire design at once | Update Template (this page) |
| Pages: add, duplicate, replace, edit settings (including page size), delete, reorder | Update Pages |
| Layers on a page: add, replace, edit (incl. saved animation timing), delete, restack | Update Layers |
| Values of existing dynamic layers: text, images, colors, style, position | Update Template Modifications |
Endpoint#
https://api.orshot.com/v1/studio/templates/:templateId/updateQuery Parameters#
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
includeThumbnails | Boolean | No | false | When true, the endpoint renders thumbnails synchronously and waits for all uploads before responding. When false or absent, thumbnails are generated asynchronously if visual content changed. |
includeVideoThumbnails | Boolean | No | false | When true, pages_data was sent and at most 2 of its pages are animated, the response waits for their animated previews and returns them in template.pages_meta[].video_thumbnail_url. Otherwise they are generated in the background. |
Request Examples#
// Update name, description, and tags
await fetch("https://api.orshot.com/v1/studio/templates/12345/update", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <ORSHOT_API_KEY>",
},
body: JSON.stringify({
name: "Summer Sale Banner - Updated",
description: "Updated promotional banner for the summer 2026 campaign",
tags: ["sale", "summer", "promotional"]
}),
});// Update canvas dimensions and pages
await fetch("https://api.orshot.com/v1/studio/templates/12345/update?includeThumbnails=true", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <ORSHOT_API_KEY>",
},
body: JSON.stringify({
canvas_width: 1200,
canvas_height: 628,
pages_data: [
{
id: "page-1",
name: "Page 1",
canvas: { width: 1200, height: 628, backgroundColor: "#ffffff" },
elements: [
{
id: "headline-element",
type: "text",
position: { x: 100, y: 200 },
dimensions: { width: 880, height: 100 },
content: "Your Headline Here",
parameterId: "headline",
parameterizable: true
}
]
}
]
}),
});{
"success": true,
"template": {
"id": 12345,
"name": "Summer Sale Banner - Updated",
"description": "Updated promotional banner for the summer 2026 campaign",
"tags": ["sale", "summer", "promotional"],
"updated_at": "2026-01-29T12:00:00.000Z"
}
}{
"success": true,
"template": {
"id": 12345,
"name": "Summer Sale Banner - Updated",
"description": "Updated promotional banner for the summer 2026 campaign",
"tags": ["sale", "summer", "promotional"],
"updated_at": "2026-01-29T12:00:00.000Z",
"thumbnails": {
"success": true,
"pages": [
{
"page": 1,
"page_id": "page-1",
"thumbnail_url": "https://storage.orshot.com/cloud/w-50/renders/thumbnails/abc123.png",
"error": null
}
]
}
}
}Rate Limits#
| Limit | Value |
|---|---|
| Requests per minute | 30 |
The limit is 30 requests per minute per API key, shared by every /v1/studio template endpoint, including template reads. Renders are not counted.
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | Integer | Yes | The ID of the template to update |
Request Body Parameters#
At least one of the following parameters must be provided:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | String | No | New name for the template (max 255 characters) |
description | String | No | New description for the template |
tags | Array | No | Array of tag strings to categorize the template (e.g. ["social", "marketing"]) |
canvas_width | Integer | No | The template's default width in pixels, 1 to 5000. Pages that have their own canvas size keep it (every page created through the API has one). To resize a page, use Update Pages with { "op": "update", "set": { "canvas": { "width": 1200, "height": 628 } } }, or send pages_data |
canvas_height | Integer | No | The template's default height in pixels, 1 to 5000. Same rule as canvas_width |
pages_data | Array | No | Full array of page objects with elements (replaces existing pages). Must contain at least one page; to change or delete individual pages use Update Pages |
film | Object | No | The template's film block, on its own or with pages_data. An object makes or changes the film; null turns it back into separate pages (each page keeps its transitionIn). Validated against the pages the template will have |
base_updated_at | String | No | The template's updated_at from your last read. If the template changed since, nothing is written and you get 409 |
Element motion and page motion fields (Motion) are validated on write: structural problems (a missing or cyclic after reference, values over the engine caps) fail with a 400 listing each issue, while unknown or misspelled motion params are accepted and reported back in the response warnings array with a suggestion. Problems already present in the stored template never block an unrelated update.
When pages_data is provided, template-level modifications are automatically recalculated from the elements. Pure metadata updates (name, description, tags) do not trigger thumbnail regeneration.
Pages may include audio tracks, generated narration, ambient audio, subtitles, waveform elements, and a saved video duration. Generated narration and ambient audio are resolved when the template is saved. See Template Anatomy for the complete schema.
Response Fields#
| Field | Type | Description |
|---|---|---|
success | Boolean | Whether the update was successful |
template | Object | Updated template information |
template.id | Integer | Template ID |
template.name | String | Updated template name |
template.description | String | Updated template description |
template.tags | Array | Updated tags array |
template.updated_at | String | The design version (ISO 8601). It does not change on name, description or tags updates. Send it as base_updated_at on your next write |
warnings | Array | Non-blocking authoring warnings (e.g. an unknown motion param with a suggested fix). Present only when there is something to fix |
template.thumbnails | Object | Only present when ?includeThumbnails=true. See the Thumbnails Object Structure section |
template.pages_meta | Array | Only present when ?includeVideoThumbnails=true rendered the animated previews in the request. Each page's preview is in video_thumbnail_url |
Thumbnails Object Structure#
When you pass ?includeThumbnails=true and the update includes visual changes (pages_data, canvas_width, or canvas_height), the response includes a thumbnails object:
| 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 id 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 |
Error Responses#
| Status Code | Error | Description |
|---|---|---|
| 400 | At least one field required | None of the updatable fields was sent |
| 400 | name must be non-empty string | Empty or invalid name provided |
| 400 | name must be 255 characters or less | Name exceeds maximum length |
| 400 | description must be a string | Invalid description type |
| 400 | tags must be an array of strings | Invalid tags |
| 400 | pages_data must be an array | pages_data is not an array |
| 400 | Invalid base_updated_at | base_updated_at is not the updated_at timestamp from Get Studio Template |
| 400 | empty_pages_data | pages_data is an empty array |
| 400 | invalid_canvas_size | canvas_width/canvas_height is not a number from 1 to 5000 |
| 400 | invalid_film | film is not an object or null |
| 400 | Validation failed | The film or a page transitionIn fails film validation against the pages the template will have; details names each problem by path |
| 409 | Template changed since you fetched it | base_updated_at is stale: fetch the template again and retry |
| 423 | stage_locked | An approval flow locks the template |
| 401 | Unauthorized | The OAuth token is invalid or expired. Refresh it |
| 403 | Access Forbidden | Invalid API key, your plan does not include this endpoint, or a payment is overdue (see code) |
| 404 | Template not found | The template isn't in your workspace |
| 429 | Rate limit exceeded | Too many requests (max 30/min) |
| 500 | Internal server error | Server-side error |
Cache Invalidation#
When the template is updated:
- Template render cache is automatically invalidated
- Dynamic URL cache for the template is cleared
Use Cases#
- Rename templates after generation or import
- Update descriptions for better organization
- Tag templates for filtering and categorization
- Change the default canvas size. To resize existing pages, use Update Pages or send
pages_data - Replace page structure with updated elements and layouts
- Batch rename templates via programmatic naming conventions
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 40+ integrations
- White-label embed for your own app
- 100 free credits a month, no credit card required