Recipe: voiceover_explainer

Status: Live

Narration-led explainer recipe with rotating backgrounds, hook, CTA, and transcript-driven captions.

Bridge Note

Recipes are the recommended path. Use https://api.reelforger.com/v1/recipes/render as the canonical endpoint.

When to use it

  • You have a voiceover and transcript words
  • You want recipe-first generation with minimal timeline math
  • You need social-ready motion defaults and caption styling

Input assets

This example uses the following assets:

Required inputs

  • voiceover_audio_url
  • transcript_words
  • background_assets
  • style_preset

Optional overrides

  • correct_text (punctuated reference for caption alignment)
  • hook_text / cta_text
  • hook_style / cta_style / captions_style
  • hook_layout / cta_layout / captions_layout
  • per-asset motion via object form

Request structure

  • Send requests to https://api.reelforger.com/v1/recipes/render.
  • Use canonical field recipe_id.
  • Keep style_preset at the root and recipe-specific values inside variables.

Variable behavior guide

  • voiceover_audio_url: narration track that drives final duration.
  • background_assets: image/video array sequenced across narration.
  • transcript_words: timestamped words for caption timing.
  • correct_text: cleaned transcript for punctuation/casing alignment.
  • hook_text / cta_text: optional intro and closing overlays.

Payload and output preview

Payload example

{
  "recipe_id": "voiceover_explainer",
  "style_preset": "bold_outline",
  "idempotency_key": "recipe-voiceover-001",
  "variables": {
    "voiceover_audio_url": "https://pub-2ad5592bc4ca44abb609acfc0b7c5ceb.r2.dev/reel-forge-website-assets/football%20commentary%20speech.mp3",
    "background_assets": [
      "https://pub-2ad5592bc4ca44abb609acfc0b7c5ceb.r2.dev/reel-forge-website-assets/kai%20ren%201.jpeg",
      { "url": "https://pub-2ad5592bc4ca44abb609acfc0b7c5ceb.r2.dev/reel-forge-website-assets/kai%20ren%202.jpeg", "motion": "pan_right" },
      { "url": "https://pub-2ad5592bc4ca44abb609acfc0b7c5ceb.r2.dev/reel-forge-website-assets/kai%20ren%203.jpeg", "motion": "zoom_out" },
      { "url": "https://pub-2ad5592bc4ca44abb609acfc0b7c5ceb.r2.dev/reel-forge-website-assets/kai%20ren%204.jpeg", "motion": "pan_left" },
      { "url": "https://pub-2ad5592bc4ca44abb609acfc0b7c5ceb.r2.dev/reel-forge-website-assets/kai%20ren%205.jpeg", "motion": "zoom_in" }
    ],
    "transcript_words": [
      { "text": "This", "start": 160, "end": 320, "confidence": 0.92733216, "speaker": "A" },
      { "text": "goal", "start": 320, "end": 760, "confidence": 0.9995247, "speaker": "A" },
      { "text": "changed", "start": 760, "end": 1240, "confidence": 0.9977877, "speaker": "A" },
      { "text": "the", "start": 1240, "end": 1400, "confidence": 0.99970955, "speaker": "A" },
      { "text": "whole", "start": 1400, "end": 1720, "confidence": 0.999252, "speaker": "A" },
      { "text": "match.", "start": 1720, "end": 2080, "confidence": 0.57080585, "speaker": "A" },
      { "text": "90", "start": 2720, "end": 3080, "confidence": 0.9999782, "speaker": "A" },
      { "text": "seconds", "start": 3080, "end": 3680, "confidence": 0.99942905, "speaker": "A" },
      { "text": "left,", "start": 3680, "end": 4000, "confidence": 0.6299604, "speaker": "A" },
      { "text": "one", "start": 4240, "end": 4600, "confidence": 0.85895026, "speaker": "A" },
      { "text": "chance,", "start": 4600, "end": 5040, "confidence": 0.9754993, "speaker": "A" },
      { "text": "one", "start": 5360, "end": 5680, "confidence": 0.99934345, "speaker": "A" },
      { "text": "touch", "start": 5680, "end": 6040, "confidence": 0.9998425, "speaker": "A" },
      { "text": "to", "start": 6040, "end": 6240, "confidence": 0.99973553, "speaker": "A" },
      { "text": "control", "start": 6240, "end": 6520, "confidence": 0.9999193, "speaker": "A" },
      { "text": "it,", "start": 6520, "end": 6880, "confidence": 0.98364824, "speaker": "A" },
      { "text": "one", "start": 7040, "end": 7360, "confidence": 0.99861884, "speaker": "A" },
      { "text": "defender", "start": 7360, "end": 8040, "confidence": 0.99974185, "speaker": "A" },
      { "text": "beaten,", "start": 8040, "end": 8640, "confidence": 0.9053415, "speaker": "A" },
      { "text": "and", "start": 8720, "end": 9040, "confidence": 0.9994054, "speaker": "A" },
      { "text": "then—", "start": 9040, "end": 9360, "confidence": 0.6485888, "speaker": "A" },
      { "text": "top", "start": 9920, "end": 10320, "confidence": 0.7475579, "speaker": "A" },
      { "text": "corner!", "start": 10400, "end": 10880, "confidence": 0.92240775, "speaker": "A" },
      { "text": "From", "start": 11440, "end": 11800, "confidence": 0.9978428, "speaker": "A" },
      { "text": "doubt", "start": 11800, "end": 12280, "confidence": 0.99835914, "speaker": "A" },
      { "text": "to", "start": 12280, "end": 12560, "confidence": 0.9951866, "speaker": "A" },
      { "text": "eruption", "start": 12560, "end": 13240, "confidence": 0.9988387, "speaker": "A" },
      { "text": "in", "start": 13240, "end": 13520, "confidence": 0.9958352, "speaker": "A" },
      { "text": "a", "start": 13520, "end": 13760, "confidence": 0.99887687, "speaker": "A" },
      { "text": "single", "start": 13760, "end": 14240, "confidence": 0.99969864, "speaker": "A" },
      { "text": "strike.", "start": 14240, "end": 14640, "confidence": 0.77905774, "speaker": "A" }
    ],
    "correct_text": "This goal changed the whole match. 90 seconds left, one chance, one touch to control it, one defender beaten, and then - top corner! From doubt to eruption in a single strike.",
    "hook_text": "How this goal changed everything",
    "cta_text": "Built in ReelForge",
    "captions_layout": { "y": "72%" }
  }
}

Output preview

Kai Ren sports-anime explainer: 5 stills, Ken Burns motion, voiceover, and aligned captions.

Constraints

  • hook_text max length is 60
  • transcript_words must contain at least one token
  • Output duration follows transcript timing

Common mistakes and errors

  • Sending an empty transcript_words array
  • Using webpage URLs instead of direct media URLs
  • Overloading hook_text with long paragraphs