Working with Text

Text now lives in composition.text_overlays instead of composition.timeline. This keeps media timing (video/audio/image) separate from text instructions for easier no-code payload generation.

Basic Text Overlay Object

A text overlay does not require an asset_id (there is no external media file to download). It requires content and time (start_seconds, duration_seconds). id is optional.

{
  "id": "intro-text",
  "content": "Welcome to Reel Forge",
  "time": {
    "start_seconds": 2,
    "duration_seconds": 3
  }
}

Layout & Bounding Boxes

Use layout to control where text renders. If omitted, text defaults to full frame (x: "0%", y: "0%", width: "100%", height: "100%").

{
  "content": "Lower Third Caption",
  "layout": {
    "x": "10%",
    "y": "70%",
    "width": "80%",
    "height": "20%"
  },
  "time": {
    "start_seconds": 0,
    "duration_seconds": 4
  }
}

Typography and Styling (style)

Text overlays use strict snake_case for style keys (consistent with image/video layer styles). Accepted keys:

  • font_size (number)
  • font_family (string)
  • font_weight (number)
  • color (string)
  • text_align (left | center | right | justify)
  • letter_spacing (number, rendered as em)
  • line_height (number)
  • stroke_color (string)
  • stroke_width (number)
  • shadow_color (string)
  • shadow_blur (number)
  • shadow_offset_x (number)
  • shadow_offset_y (number)

text_align only controls horizontal alignment inside the overlay's bounding box. Use layout (or global_layouts.text) to control vertical placement and overlay region.

{
  "content": "LOUD AND CLEAR",
  "time": { "start_seconds": 1, "duration_seconds": 3 },
  "style": {
    "font_family": "Montserrat",
    "font_size": 120,
    "font_weight": 900,
    "color": "#FFD700",
    "text_align": "center",
    "stroke_color": "black",
    "stroke_width": 4,
    "shadow_color": "rgba(0,0,0,0.8)",
    "shadow_offset_x": 0,
    "shadow_offset_y": 8,
    "shadow_blur": 16
  }
}

Global Text Defaults

You can define shared text defaults once and override per overlay:

  1. composition.global_styles.text then text_overlay.style
  2. composition.global_layouts.text then text_overlay.layout

Local keys always win.

{
  "composition": {
    "global_styles": {
      "text": {
        "color": "white",
        "font_family": "Inter",
        "font_weight": 700,
        "shadow_color": "rgba(0,0,0,0.6)",
        "shadow_offset_x": 0,
        "shadow_offset_y": 4,
        "shadow_blur": 12
      }
    },
    "global_layouts": {
      "text": {
        "x": "0%",
        "y": "30%",
        "width": "100%",
        "height": "20%"
      }
    },
    "text_overlays": [
      {
        "id": "text-default",
        "content": "Uses global defaults",
        "time": { "start_seconds": 0, "duration_seconds": 2 }
      },
      {
        "id": "text-override",
        "content": "Overrides color locally",
        "time": { "start_seconds": 2, "duration_seconds": 2 },
        "style": { "color": "#FFD700" }
      }
    ]
  }
}

Full Text Request Example

curl -X POST https://api.reelforger.com/v1/videos/render \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "v1",
    "output": { "width": 1080, "height": 1920, "fps": 30 },
    "assets": [
        {
          "id": "asset-bg-video",
          "type": "video",
          "url": "https://example.com/background.mp4"
        }
    ],
    "composition": {
        "timeline": [
          {
            "id": "base-video",
            "type": "video",
            "asset_id": "asset-bg-video",
            "time": { "start_seconds": 0, "duration_seconds": 10 }
          }
        ],
        "text_overlays": [
          {
            "id": "title-text",
            "content": "THE TRUTH REVEALED",
            "time": { "start_seconds": 1, "duration_seconds": 4 },
            "layout": {
              "x": "0%",
              "y": "30%",
              "width": "100%",
              "height": "20%",
              "z_index": 10
            },
            "style": {
              "color": "white",
              "font_size": 80,
              "font_weight": 700,
              "font_family": "Inter",
              "text_align": "center",
              "stroke_color": "black",
              "stroke_width": 4
            }
          }
        ]
    }
  }'