Working with Images
Image layers allow you to render static .jpg, .png, or .webp files over time. They are incredibly powerful when combined with the layout object for Picture-in-Picture, logos, or watermarks.
Basic Image Object
An image layer needs an asset_id and a time definition. time.start_seconds is required. time.duration_seconds is optional when ReelForge can infer overall composition duration from timed media layers (or explicit composition.duration_seconds).
Duration Inference Precedence
When image time.duration_seconds is omitted, ReelForge resolves timing in this order:
- If image
time.duration_secondsis provided, that explicit value is used. - Otherwise, if
composition.duration_secondsis provided, image duration is inferred as:composition.duration_seconds - image.time.start_seconds
- Otherwise, composition duration is inferred from the maximum timed end across
composition.timelineandcomposition.text_overlays, then image duration is inferred from that result.
If none of the above can establish a valid duration, validation fails with a clear error.
If composition.auto_stitch is enabled and media layers are untimed, ReelForge can still infer composition duration at render time by probing media duration, then apply the same image-duration inference.
{
"id": "watermark-logo",
"type": "image",
"asset_id": "asset-logo-1",
"time": {
"start_seconds": 0,
"duration_seconds": 60
}
}
Spatial Coordinates (layout)
To position an image, supply a layout object. The layout allows you to define standard CSS-like spatial bounds.
x: Horizontal position (e.g.,"10%","20px"). Maps to the CSSleftproperty.y: Vertical position (e.g.,"10%","20px"). Maps to the CSStopproperty.width: The width of the bounding box.height: The height of the bounding box.fit: How the image fits inside its bounding box ("cover"or"contain").
{
"id": "logo-top-right",
"type": "image",
"asset_id": "asset-logo-1",
"layout": {
"x": "80%",
"y": "5%",
"width": "15%",
"height": "10%",
"fit": "contain"
}
}
Background Mode (background_mode)
Similar to Videos, images support background_mode. If your image does not perfectly match its layout bounding box, you can control the empty space.
For things like transparent .png logos, you should always explicitly set "background_mode": "transparent", otherwise they will render with a blurred background copy of themselves.
{
"id": "transparent-logo",
"type": "image",
"asset_id": "asset-logo-1",
"background_mode": "transparent",
"layout": {
"x": "10px",
"y": "10px",
"width": "100px",
"height": "100px",
"fit": "contain"
}
}
Styling Images
The style object uses snake_case keys (consistent with the rest of the manifest):
opacity(number, 0–1)border_radius(string, e.g."24px")box_shadow(string, e.g."0 10px 30px rgba(0,0,0,0.5)")
{
"id": "styled-image",
"type": "image",
"asset_id": "asset-pic",
"style": {
"opacity": 0.8,
"border_radius": "24px",
"box_shadow": "0 10px 30px rgba(0,0,0,0.5)"
}
}
The Full Image Request Example
This example places a transparent PNG logo in the top right corner of the video for the entire 10-second duration.
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"
},
{
"id": "asset-logo",
"type": "image",
"url": "https://example.com/logo.png"
}
],
"composition": {
"timeline": [
{
"id": "base-video",
"type": "video",
"asset_id": "asset-bg-video",
"time": {
"start_seconds": 0,
"duration_seconds": 10
}
},
{
"id": "overlay-logo",
"type": "image",
"asset_id": "asset-logo",
"background_mode": "transparent",
"time": {
"start_seconds": 0,
"duration_seconds": 10
},
"layout": {
"x": "80%",
"y": "5%",
"width": "15%",
"height": "10%",
"fit": "contain",
"z_index": 10
}
}
]
}
}'