Faceless video API: voiceover, B-roll, music, and captions

Build a faceless video with the Sume API: TTS narration as the spine, generated B-roll, a Sume-hosted music bed, and captions timed from TTS words.

6 min readSume
All posts

To make a faceless video with the Sume API, synthesize the narration with POST /v1/tts-1.0/generate, generate B-roll clips with POST /v1/videos, and lay the clips over the narration in a Timeline 1.0 render with a Sume-hosted music bed. Then, if the video runs 60 seconds or less, burn captions with POST /v1/video-captions, passing the TTS word timings as words so no speech-to-text runs.

The facts below come from the TTS, BGM, and captions schemas in the Sume API reference and Sume's Video generation, Timeline 1.0, and Video captions docs, read on 2026-09-27. Anything described as current behavior is read from Sume's code. Add B-roll to a talking-head avatar video cuts B-roll into an avatar's A-roll; here nobody is on screen.

Why does narration over B-roll need no lip sync?

Sume's model docs say video models do not lip-sync to generated TTS or to a later voice-over, so a talking face is never a video-model clip with narration laid underneath. B-roll has no lips to match, so generated clips can run under any narration. For a speaker on camera, use an Avatar 1.0 talking video or VEED Fabric 1.0, a talking still plus audio, instead.

How do I make the narration?

Send the script to TTS 1.0 as transcript, up to 20,000 characters, with a voice: the avatar_id or avatar_handle of an avatar whose voice is ready, or a voice.id. TTS returns audio, so the avatar lends its voice and never appears. Text to speech API covers every field; three matter here:

  • timestamps: { "words": true } adds words[] with start and end seconds to the completed result. In the current code each entry is { word, start, end }, and the result also carries duration_seconds, the value for the render's audio.duration_seconds.
  • language: set it for every non-English script.
  • output_format: the default is mp3 at 44,100 Hz. A Timeline master inherits its spine's sample rate and channel count, the API reference names a TTS master as a spine-grade file, and a spine under 32 kHz is reported as audio_spine_low_fidelity.

How do I make the B-roll?

Generate each shot with POST /v1/videos: a prompt, aspect_ratio: "9:16" for vertical, and a duration the model lists. sume/auto create controls default to 720p and 8 s, with 3–10 s clips at 16:9 or 9:16; a pinned model's limits are on GET /v1/videos/models. Read each clip's media.sume.com URL from GET /v1/jobs/{id}/result, because Timeline takes only Sume-hosted URLs. A Sume-hosted still in a slot is held as a static frame.

How do I assemble the narration, clips, and music?

One Timeline 1.0 render does the edit. audio.url is the narration and audio.duration_seconds its length (1–1800). video[] holds the clips: 1–200 slots, the first starting at 0. soundtrack adds the bed, and duck_db (0–20) dips it while the narration speaks; the output audio is the narration spine with the bed mixed under it. Check the document first with the unbilled POST /v1/timeline-1.0/plan.

For the bed, the keyless BGM routes (GET /v1/bgm/catalog, or POST /v1/bgm/pick to score tracks against a mood) list ready tracks. Sume's own tracks are served from the Sume media host, so in the current code their audio_url passes as soundtrack.url. The featured CC BY 4.0 tracks sit at their official URLs off Sume: Timeline refuses them with unsupported_media_source, and the API asks you to keep track.attribution with any public use. The background music catalog has its own post.

curl -X POST https://api.sume.com/v1/timeline-1.0/render \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: faceless-render-001" \
  -d '{
    "audio": { "url": "https://media.sume.com/artifacts/artf_demo/narration.mp3", "duration_seconds": 24 },
    "video": [
      { "source_url": "https://media.sume.com/artifacts/artf_demo/broll-1.mp4", "start": 0, "duration": 8 },
      { "source_url": "https://media.sume.com/artifacts/artf_demo/broll-2.mp4", "start": 8, "duration": 8,
        "transition": { "type": "fade", "duration": 0.25 } },
      { "source_url": "https://media.sume.com/artifacts/artf_demo/broll-3.mp4", "start": 16, "duration": 8 }
    ],
    "soundtrack": {
      "url": "https://media.sume.com/assets/bgm/minimal-clean-focus.mp3",
      "loop": true,
      "duck_db": 8,
      "fade_out_seconds": 2
    }
  }'

How do I caption it from the TTS timings?

Send the render's video_url to POST /v1/video-captions with words: the TTS words[], each word renamed to text. Sume then skips speech-to-text and burns exactly those words at exactly those times. With the narration as the spine from its first second (audio.source_in defaults to 0), the TTS times line up with the render.

  • Keep a video you caption to 60 seconds. Each words time runs from 0 to 60 seconds, the docs quote the caption price for videos up to 60 seconds, and in the current code a longer source fails the caption job.
  • words takes 1–1,200 entries, each text up to 200 characters.
  • words is mutually exclusive with script_text, cues, and segments.
  • Omit style and Latin wording burns in slam, Korean wording in black-outline.
curl -X POST https://api.sume.com/v1/video-captions \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: faceless-captions-001" \
  -d '{
    "video_url": "https://media.sume.com/artifacts/artf_demo/faceless.mp4",
    "words": [
      { "text": "Three", "start": 0.12, "end": 0.41 },
      { "text": "ways", "start": 0.41, "end": 0.7 }
    ]
  }'

What does a faceless video cost?

Each paid step is a separate job, billed separately. The TTS and render rates are read from API pricing; synthesized audio over 1,200 seconds fails with tts_duration_exceeded and captures no credit.

From the Sume API reference, Video generation, Timeline 1.0, and Video captions, read 2026-09-27.
StepCallBilling
NarrationPOST /v1/tts-1.0/generate$0.0475 per 1,000 characters; spaces and punctuation count
B-rollPOST /v1/videosReserved at provider list × 1.25 on submit
MusicGET /v1/bgm/catalog, POST /v1/bgm/pickKeyless routes; the bed is mixed in the render
PreflightPOST /v1/timeline-1.0/planUnbilled
AssemblyPOST /v1/timeline-1.0/render$0.10 per output minute; reserve is ceil(audio.duration_seconds / 60) minutes
CaptionsPOST /v1/video-captionsA fixed amount per job for videos up to 60 s; confirm it in GET /v1/catalog

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume