Browse the docs

DocsREST API

Studio API

List the Studio templates with the JSON schema of their inputs, render a vertical video from your media library and check the render.

On this page

Studio turns videos from your media library into vertical 1080×1920 videos. The API renders the same templates as the app, with the same fair use limits. A render only saves a new video to your media library. It never creates, schedules or publishes a post: to post the video, pass its id and path to POST /posts like any other upload.

All paths are relative to https://app.postdelegate.com/api/public/v1. Authentication is the same as for every other endpoint: see REST API overview.

GET /studio/templates

Lists the templates. Each one has a plain description and a schema: the JSON schema of the spec a render takes. New templates appear here by themselves, so read the schema instead of hard-coding it.

curl https://app.postdelegate.com/api/public/v1/studio/templates \
  -H "Authorization: YOUR_API_KEY"
[
  {
    "identifier": "hook-over-clip",
    "title": "Hook over clip",
    "description": "A clip filling the vertical frame with a hook line popping in over it.",
    "captions": false,
    "schema": {
      "type": "object",
      "required": ["input", "trim", "hook"],
      "properties": {
        "input": { "type": "object", "required": ["mediaId"], "properties": { "mediaId": { "type": "string", "format": "uuid" } } },
        "trim": { "type": "object", "required": ["start", "end"], "properties": { "start": { "type": "number" }, "end": { "type": "number" } } },
        "hook": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string", "maxLength": 120 } } }
      }
    }
  }
]

The schema above is shortened. Times are seconds on the source video. Today there are seven templates:

identifierWhat it makesMedia it reads
hook-over-clipA trimmed clip with a hook line popping in1 video
talking-head-captionsA trimmed clip with word-by-word captions from a typed script or your own word timings1 video
image-slideshow2 to 10 pictures with a line of text each and transitionspictures
before-afterTwo pictures or videos stacked or wiping, with labels2 pictures or videos
top-n-listA title over 3 to 7 numbered pictures or clipspictures or videos
quote-cardA quote appearing word by word over a colour, picture or videooptional background
ai-ugcA spoken script over your footage with word-by-word captions1 or more videos

POST /studio/renders

Makes a Studio project from a template and a spec and starts rendering it.

FieldNotes
templateRequired. An identifier from GET /studio/templates.
specRequired. An object that follows the template’s schema.
nameOptional name of the project in Studio, up to 100 characters. Defaults to the template’s title.
  • Media are ids only. Every mediaId must be a media in your own media library, from GET /media or an upload. URLs are not accepted, and a path you send is replaced with the stored one. An upload with adjust must be ready first.
  • Captions. For a template with "captions": true, send what is said in captions.script and leave captions.words out. Studio spreads the words over the clip, giving longer words more time. You can also send captions.words with your own timings.
  • AI UGC without a key. ai-ugc takes your own script (script.hook, script.lines, script.cta) and, unless you send "voiceover": true, renders it as captions over your footage for seconds, with no AI key. An AI voice (voiceover: true) runs on your workspace’s own OpenAI key and answers 400 without one. AI stills (stills) only come with the voice: stills without voiceover: true answers 400. A null counts as left out.
  • Music. music.assetId must be a music uploaded in Studio in the app that no other project uses. A music already used by another project answers 400 (“That music belongs to another Studio project; upload it again in Studio”). The API cannot upload or list music yet.
  • Paths. Any path in the spec is replaced with the stored path of its media or music, or dropped.
  • A video is at most 90 seconds long after speed changes, and each template’s own rules (like a clip’s end after its start) are checked before anything is made.
curl -X POST https://app.postdelegate.com/api/public/v1/studio/renders \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "hook-over-clip",
    "name": "Launch teaser",
    "spec": {
      "input": { "mediaId": "MEDIA_ID" },
      "trim": { "start": 4, "end": 19 },
      "hook": { "text": "We shipped exports", "position": "top" }
    }
  }'
{ "id": "RENDER_ID", "projectId": "PROJECT_ID" }

The project also appears in Studio in the app, where it can be edited and rendered again. Projects made through the API are hidden from the Studio list until you turn on Show projects made by assistants and the API, so they never crowd out your own.

POST /studio/renders is limited to 30 requests per workspace per hour, counting requests that are refused.

GET /studio/renders/:id

Returns a render. Poll it every few seconds until status is completed, failed or cancelled.

{
  "id": "RENDER_ID",
  "projectId": "PROJECT_ID",
  "status": "completed",
  "progress": 100,
  "seconds": 15,
  "error": null,
  "mediaId": "MEDIA_ID_OF_THE_VIDEO",
  "path": "https://media.postdelegate.com/....mp4",
  "thumbnail": "https://media.postdelegate.com/....jpg",
  "createdAt": "2026-11-01T10:00:00.000Z",
  "updatedAt": "2026-11-01T10:00:41.000Z"
}

status goes from queued to rendering and uploading, then ends as completed, failed or cancelled. On completed, mediaId and path are the new video in your media library. On failed, error says why, and the render is not counted.

POST /studio/renders/:id/cancel

Stops a render that is still waiting or rendering and returns it. A cancelled render still counts toward the daily and trial limits. A render that already ended is returned as it is.

Limits and errors

Studio is included in every paid plan with fair use: one render at a time per workspace with up to 3 more waiting, 30 videos a day, 90 seconds per video, and 10 videos in total during the free trial.

StatusWhen
400Unknown template, a spec that does not follow the schema (the message array says what to fix), a media that is not in your media library, still processing or of the wrong kind (a picture where a video is needed), a music that is not yours or belongs to another project, an AI voice without an AI key, AI stills without the AI voice, or a video longer than 90 seconds
404Render not found, including renders of another workspace
406Studio needs an active plan, or the trial’s 10 videos are used
429More than 30 POST /studio/renders requests this hour, 3 videos are already waiting, the 30 videos a day are reached, another render is being started, or Studio is busy right now
503Studio is not available

Every id is scoped to the workspace of the API key: another workspace’s media, projects and renders are never found.

Something unclear, wrong or missing? Email support@postdelegate.com and tell us which page you were on.