Bulk Create Studio Templates

Create up to 50 studio templates in one JSON request

Updated

POST
/v1/studio/templates/bulk-create
curl -X POST "https://api.orshot.com/v1/studio/templates/bulk-create" \
  -H "Authorization: Bearer <ORSHOT_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "templates": []
  }'

Create multiple studio templates in a single API call. This endpoint is ideal for importing templates in bulk from external systems or migrating existing template libraries.

For detailed information about the template data structure, see Anatomy of a Template.

Endpoint#

Endpoint
https://api.orshot.com/v1/studio/templates/bulk-create

Query Parameters#

ParameterTypeRequiredDefaultDescription
includeThumbnailsBooleanNofalseWhen true, thumbnails for every page of every template are rendered before the response is sent. Templates are processed sequentially to bound concurrency; expect ~1–2 seconds per page. When false or absent, thumbnails are generated in the background.

Request#

JavaScript
await fetch("https://api.orshot.com/v1/studio/templates/bulk-create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    templates: [
      {
        name: "Instagram Post - Square",
        description: "1:1 aspect ratio for Instagram feed",
        canvas_width: 1080,
        canvas_height: 1080
      },
      {
        name: "Instagram Story",
        description: "9:16 aspect ratio for Instagram stories",
        canvas_width: 1080,
        canvas_height: 1920
      },
      {
        name: "Facebook Cover",
        description: "Facebook page cover photo",
        canvas_width: 820,
        canvas_height: 312
      },
      {
        name: "Twitter Header",
        description: "Twitter profile header image",
        canvas_width: 1500,
        canvas_height: 500
      },
      {
        name: "LinkedIn Banner",
        description: "LinkedIn company page banner",
        canvas_width: 1128,
        canvas_height: 191
      }
    ]
  }),
});
JSON
{
  "success": true,
  "created": 5,
  "failed": 0,
  "templates": [
    {
      "id": 12345,
      "name": "Instagram Post - Square",
      "canvas_width": 1080,
      "canvas_height": 1080
    },
    {
      "id": 12346,
      "name": "Instagram Story",
      "canvas_width": 1080,
      "canvas_height": 1920
    },
    {
      "id": 12347,
      "name": "Facebook Cover",
      "canvas_width": 820,
      "canvas_height": 312
    },
    {
      "id": 12348,
      "name": "Twitter Header",
      "canvas_width": 1500,
      "canvas_height": 500
    },
    {
      "id": 12349,
      "name": "LinkedIn Banner",
      "canvas_width": 1128,
      "canvas_height": 191
    }
  ]
}
JSON
{
  "success": true,
  "created": 2,
  "failed": 0,
  "templates": [
    {
      "id": 12345,
      "name": "Instagram Post - Square",
      "canvas_width": 1080,
      "canvas_height": 1080,
      "thumbnails": {
        "success": true,
        "pages": [
          {
            "page": 1,
            "page_id": "page-1",
            "thumbnail_url": "https://storage.orshot.com/cloud/w-50/renders/thumbnails/a1b2c3.png",
            "error": null
          }
        ]
      }
    },
    {
      "id": 12346,
      "name": "Instagram Story",
      "canvas_width": 1080,
      "canvas_height": 1920,
      "thumbnails": {
        "success": true,
        "pages": [
          {
            "page": 1,
            "page_id": "page-2-uuid",
            "thumbnail_url": "https://storage.orshot.com/cloud/w-50/renders/thumbnails/d4e5f6.png",
            "error": null
          }
        ]
      }
    }
  ]
}
JSON
{
  "success": true,
  "created": 3,
  "failed": 2,
  "templates": [
    {
      "id": 12345,
      "name": "Valid Template 1",
      "canvas_width": 1080,
      "canvas_height": 1080
    },
    {
      "id": 12346,
      "name": "Valid Template 2",
      "canvas_width": 1200,
      "canvas_height": 628
    },
    {
      "id": 12347,
      "name": "Valid Template 3",
      "canvas_width": 800,
      "canvas_height": 600
    }
  ],
  "errors": [
    {
      "index": 3,
      "name": "Invalid Template",
      "errors": ["'canvas_width' must be between 1 and 5000"]
    },
    {
      "index": 4,
      "name": "Template 5",
      "errors": ["'name' is required and must be a string"]
    }
  ]
}

Rate Limits#

LimitValue
Requests per minute30
Max templates per request50

The limit is 30 requests per minute per API key, shared by every /v1/studio template endpoint, including template reads. Renders are not counted.

Request Body Parameters#

ParameterTypeRequiredDescription
templatesArrayYesArray of template objects to create

Template Object Structure#

Each template in the templates array should include:

FieldTypeRequiredDescription
nameStringYesName of the template (max 255 characters)
descriptionStringNoDescription of the template
canvas_widthIntegerYesWidth of the canvas in pixels (1-5000)
canvas_heightIntegerYesHeight of the canvas in pixels (1-5000)
pages_dataArrayNoArray of page objects with elements
tagsArrayNoArray of tag strings, e.g. ["social", "marketing"]
filmObjectNoMakes the template a film, same as in Create Studio Template
thumbnail_urlStringNoIgnored. Orshot renders a thumbnail for each page from your design

Pages may include audio tracks, generated narration, ambient audio, subtitles, waveform elements, and a saved video duration. Generated narration and ambient audio are resolved for each template as it is created. See Template Anatomy for the complete schema.

Response Fields#

FieldTypeDescription
successBooleanWhether the operation completed (may be partial success)
createdIntegerNumber of templates successfully created
failedIntegerNumber of templates that failed validation
templatesArrayCreated templates. Each item has id, name, canvas_width, canvas_height and tags
errorsArrayArray of error objects for failed templates (only if any failed)

Error Object Structure#

FieldTypeDescription
indexIntegerIndex of the failed template in the original array
nameStringName of the template that failed, or Template <n> (1-based) when it had no name
errorsArrayList of error messages (validation, stock media or narration)

Thumbnails Object Structure#

When you pass ?includeThumbnails=true, each entry in templates[] gets a nested thumbnails object with per-page render results:

FieldTypeDescription
successBooleantrue if at least one page of this template rendered successfully
pages[].pageInteger1-based page number
pages[].page_idStringStable id of the page
pages[].thumbnail_urlString|nullPublic URL of the uploaded thumbnail PNG. null if this page failed
pages[].errorString|nullError message if this page failed. null on success

When ?includeThumbnails is not passed, thumbnails are generated asynchronously after the response is sent and appear on each page's thumbnail_url in Get Studio Template shortly after creation.

Bulk Import with Pages Data#

You can also include full page structures with elements for each template:

JavaScript
await fetch("https://api.orshot.com/v1/studio/templates/bulk-create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    templates: [
      {
        name: "Product Card A",
        canvas_width: 800,
        canvas_height: 600,
        pages_data: [
          {
            id: "page-uuid-1",
            name: "Page 1",
            canvas: { width: 800, height: 600, backgroundColor: "#f5f5f5" },
            elements: [
              {
                id: "title-1",
                type: "text",
                position: { x: 50, y: 50 },
                dimensions: { width: 700, height: 60 },
                content: "Product Title",
                parameterId: "title",
                parameterizable: true,
              },
            ],
          },
        ],
      },
      {
        name: "Product Card B",
        canvas_width: 800,
        canvas_height: 600,
        pages_data: [
          {
            id: "page-uuid-2",
            name: "Page 1",
            canvas: { width: 800, height: 600, backgroundColor: "#ffffff" },
            elements: [
              {
                id: "title-2",
                type: "text",
                position: { x: 50, y: 50 },
                dimensions: { width: 700, height: 60 },
                content: "Product Title",
                parameterId: "title",
                parameterizable: true,
              },
            ],
          },
        ],
      },
    ],
  }),
});

Error Responses#

Status CodeErrorDescription
400Validation failedtemplates array is missing, empty, or exceeds 50 items
400All templates failed validationEvery template in the array had validation errors
401UnauthorizedThe OAuth token is invalid or expired. Refresh it
403Access ForbiddenInvalid or missing API key, your plan does not include this endpoint, or a payment is overdue (see code)
429Rate limit exceededToo many requests (max 30/min)
500Internal server errorServer-side error

Best Practices#

  1. Batch Size: While the limit is 50 templates per request, we recommend batches of 20-30 for optimal performance
  2. Validation: Validate your data client-side before sending to avoid partial failures
  3. Error Handling: Always check both created and failed counts in the response
  4. Idempotency: This endpoint creates new templates each time - there's no upsert functionality
  5. Pages Data: If importing templates with complex structures, ensure pages_data follows the Orshot Studio format
Was this page helpful?

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