Automotion docs
Guides

Faceless short with voiceover and subtitles

A vertical short: AI background, Polly voiceover, word-timed subtitles — all from one JSON document.

The classic automated-content format: a 9:16 short where a synthetic voice reads your script over a background, with word-by-word highlighted captions. No camera, no editor — one JSON document.

The recipe

Three ingredients per scene:

  1. a voice element — the script text plus a voiceId from the voice catalog;
  2. duration: "voice" on the scene, so it lasts exactly as long as the speech;
  3. a subtitles element with source: "auto" — cues and word timings are derived from the generated speech automatically (word-timed, with a highlight color).

Full document

movie.json
{
  "schema": "v1",
  "preset": "9:16",
  "quality": "high",
  "scenes": [
    {
      "id": "hook",
      "duration": "voice",
      "elements": [
        {
          "id": "hook-bg",
          "type": "image",
          "generate": {
            "prompt": "dramatic mountain landscape at golden hour, cinematic",
            "style": "photographic",
            "seed": 42
          },
          "fit": "cover"
        },
        {
          "id": "hook-voice",
          "type": "voice",
          "text": "Most people never automate their content. Here is how you can.",
          "voiceId": "Matthew",
          "language": "en-US",
          "speed": 1
        },
        {
          "id": "hook-subs",
          "type": "subtitles",
          "source": "auto",
          "fontSize": 56,
          "color": "#ffffff",
          "highlightColor": "#facc15",
          "position": "bottom-center",
          "mode": "word"
        }
      ]
    },
    {
      "id": "payoff",
      "duration": "voice",
      "transition": { "type": "fade", "duration": 0.4 },
      "elements": [
        {
          "id": "payoff-bg",
          "type": "image",
          "generate": {
            "prompt": "sunrise over calm ocean, warm cinematic tones",
            "style": "photographic",
            "seed": 43
          },
          "fit": "cover"
        },
        {
          "id": "payoff-voice",
          "type": "voice",
          "text": "Describe the video as JSON, send it to the API, and publish the result.",
          "voiceId": "Matthew",
          "language": "en-US"
        },
        {
          "id": "payoff-subs",
          "type": "subtitles",
          "source": "auto",
          "fontSize": 56,
          "highlightColor": "#facc15",
          "position": "bottom-center"
        }
      ]
    }
  ],
  "elements": [
    {
      "id": "music",
      "type": "audio",
      "src": "https://assets.example.com/audio/lofi-loop.mp3",
      "volume": 0.2,
      "fadeIn": 0.5,
      "fadeOut": 1.5
    }
  ]
}

▶ Try it in the playground

Why this works

  • duration: "voice" removes all timing math — each scene ends when its narration does.
  • AI backgrounds (generate) are cached by prompt + seed: re-rendering the same document doesn't consume credits. Change the seed to get a different image for the same prompt.
  • Movie-level audio (the elements array at the top level) spans every scene — background music in one place, faded in and out.
  • Auto subtitles are timed from the actual speech marks, not estimates, so the word highlight lands exactly on the spoken word.

Render it

Send it like any other render (see the quickstart):

curl -X POST https://api.automotion.dev/v1/renders \
  -H "Authorization: Bearer $AUTOMOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json

where request.json is { "movie": <the document above> }.

Variations

  • Different voice per scene — any voiceId from the catalog, including non-English voices (set language to match).
  • Line-by-line captions instead of word highlighting: "mode": "line".
  • Your own footage instead of AI images: swap the image elements for a video element with mute: true.
  • Make it data-driven: replace the script strings with {{variables}} and a template — see the data-driven guide.

On this page