2026-10-28 · 6 min read

Captions for Faceless Channels: The Layer Between AI Voiceover and a Watchable Video

A faceless channel is a narration business. Whether the voice is a person, an AI voiceover, or a mix, the audio carries the entire video: the visuals are stock clips, generated b-roll, gameplay, or reddit screenshots. Strip the audio and there is little left to follow, which is exactly what happens when the video autoplays muted in a feed.

The fix is captions: bold, word-by-word, timed to the voiceover, so the narration survives muted viewing. Done by hand, that pass means transcribing, timing and styling every single video in an editor.

Captioning is an API call, not an editing session

caption.sh replaces the caption pass entirely. When your render finishes, POST the MP4 (or a public URL), pick a style, and poll the job. You get back a new MP4 with word-timed, styled captions burned in. The transcription, word timing and rendering are the API's problem, not yours.

# caption a finished faceless video in one submit, then poll
KEY=$CAPTION_API_KEY
resp=$(curl -s -X POST https://api.caption.sh/v1/videos \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"source_url":"https://cdn.example.com/episode-41.mp4","options":{"font":"luckiest-guy","max_words":3,"position":"center"}}')
job=$(echo "$resp" | jq -r .job_id)
if [ -z "$job" ] || [ "$job" = "null" ]; then echo "submit failed: $resp"; exit 1; fi
deadline=$((SECONDS + 900))
status=""
while [ $SECONDS -lt $deadline ]; do
  resp=$(curl -s https://api.caption.sh/v1/jobs/$job -H "Authorization: Bearer $KEY")
  status=$(echo "$resp" | jq -r .status)
  [ "$status" = "done" ] && break
  [ "$status" = "error" ] && { echo "job failed: $resp"; exit 1; }
  sleep 5
done
[ "$status" = "done" ] || { echo "gave up waiting for job $job"; exit 1; }
curl -sL -H "Authorization: Bearer $KEY" \
  https://api.caption.sh/v1/jobs/$job/result -o captioned-episode-41.mp4

The flow is the same whether you publish once a week or run an automated channel that ships daily: the caption step is one submit plus a poll, inserted wherever your pipeline produces the final video. The API documents no webhook surface, and because the captions are part of the pixels, no player or platform can drop or restyle them.

What matters for faceless formats

  • Word-level highlight timing: each word lights up as it is spoken, so fast narration stays followable.
  • max_words controls pacing: 3 words per group reads like a classic shorts channel, 1 word at a time gives the karaoke feel.
  • Style is set per job, so a network of channels can each keep its own font, colors and position while sharing one API key and one balance.
  • Pricing is $0.10 per minute, prepaid. A ten-minute video costs a dollar to caption, and you know that before the job starts.

If you run or automate a faceless channel, the fastest way to judge the output is to get an API key at caption.sh and run one of your own episodes through. The captions come back already timed, styled and burned in, ready to publish.

Back to all articles