GET /v1/render/videos/{video_id}/timeline
Returns the compiled timeline of a video that has finished planning: beats, narration with word timings, the timed action list the recorder replayed, cursor path, camera keyframes, captions and style (`timeline.schema.json`). `frames=1` adds the per-frame compositor state (large; for debugging).

Authentication

Bearer Token (b3os_sk_ API key or b3os_pat_ token) API Key (cookie: __Host-b3os_session)

Path Parameters

video_id string required path
The video ID (`vid_…`).
Example: "vid_01m5t4c5ep9bdfhtx7nk2k3vq7"

Query Parameters

frames boolean optional query
Include the per-output-frame state.

Responses

200 The timeline.
application/json
$schema string (uri)
version unknown REQUIRED
Enum: 1
job string
duration_us integer REQUIRED
Length of the video. Output frame i exists for every i with round(i * 1e6 / output.fps) < duration_us.
viewport object REQUIRED
Browser viewport in CSS pixels. Capture runs at device pixel ratio 1; sharp zoom comes from clip.scale at capture time (ARCHITECTURE 5.2).
width integer REQUIRED
height integer REQUIRED
capture object REQUIRED
fps integer REQUIRED
Page capture rate. Capture frame seq is taken at virtual time t(seq) = round(seq * 1e6 / fps) us.
format unknown
Enum: jpeg, png
quality integer
JPEG quality passed to Chrome.
backend unknown
screenshot: Page.captureScreenshot per virtual tick (any OS). beginframe: HeadlessExperimental.beginFrame with screenshot (Linux chrome-headless-shell; reports damage).
Enum: screenshot, beginframe
segments integer
Number of segments captured in parallel; 1 means serial.
output object REQUIRED
Composed video. Output frame index i is presented at t = round(i * 1e6 / fps) us.
width integer REQUIRED
height integer REQUIRED
fps unknown REQUIRED
Enum: 24, 25, 30, 50, 60
seed integer
Seeds Math.random and crypto.getRandomValues in the page and every PRNG in the director, so every segment worker sees the same sequence.
start_time string (date-time)
Value of Date at t = 0; the page clock then advances with virtual time only.
source object
url string (uri) REQUIRED
profile string
style object
References to style presets resolved by b3os-compose. Restyle replaces only this object.
background string
A preset id known to b3os-compose (GET /v1/render/presets), e.g. midnight, browser-dark, mac, arrow. Ids are unique across kinds; none (any kind) and auto and transparent (background) are values, not presets.
frame string
A preset id known to b3os-compose (GET /v1/render/presets), e.g. midnight, browser-dark, mac, arrow. Ids are unique across kinds; none (any kind) and auto and transparent (background) are values, not presets.
cursor string
A preset id known to b3os-compose (GET /v1/render/presets), e.g. midnight, browser-dark, mac, arrow. Ids are unique across kinds; none (any kind) and auto and transparent (background) are values, not presets.
captions string
A preset id known to b3os-compose (GET /v1/render/presets), e.g. midnight, browser-dark, mac, arrow. Ids are unique across kinds; none (any kind) and auto and transparent (background) are values, not presets.
click_effect string
A preset id known to b3os-compose (GET /v1/render/presets), e.g. midnight, browser-dark, mac, arrow. Ids are unique across kinds; none (any kind) and auto and transparent (background) are values, not presets.
overrides object
Style fields that override the presets, validated by b3os-compose against its Style type (NOTES/render-compose.md 1.1): padding, corner_radius, shadow, border, background_color, background_gradient, aspect_ratio, canvas, fit, frame_title, frame_url, theme, cursor_size, cursor_zoom, click_color, click_duration_ms, caption_size, caption_color, caption_highlight, caption_background, caption_position, motion_blur, matte. Unknown keys and bad values are refused with 422 style_invalid.
layout object
Where the page layer lands in the output frame, computed by b3os-compose from style and output size and recorded for reproducibility.
page object REQUIRED
Output space.
x number REQUIRED
y number REQUIRED
width number REQUIRED
height number REQUIRED
corner_radius number
beats object[]
Narration-sized units of the story: what is said and what happens while it is said.
Array of:
id string REQUIRED
title string
start_us integer REQUIRED
Microseconds on the virtual timeline.
end_us integer REQUIRED
Microseconds on the virtual timeline.
narration string
Narration segment spoken during this beat.
actions string[]
Array of: string
narration object | null
Voice-over. Audio is synthesized before capture so actions can be placed on words (ARCHITECTURE 5.2). Word times are absolute on the timeline: segment.start_us + the voice sidecar's start_ms * 1000.
voice object REQUIRED
model string REQUIRED
voice string REQUIRED
speed number
sample_rate unknown REQUIRED
Enum: 16000, 22050, 24000, 44100, 48000
gain_db number
segments object[] REQUIRED
Array of:
id string REQUIRED
beat string
text string REQUIRED
start_us integer REQUIRED
Microseconds on the virtual timeline.
end_us integer REQUIRED
Microseconds on the virtual timeline.
audio object REQUIRED
Mono PCM s16le at narration.sample_rate, stored by b3os-render (job-relative path or art_ id).
ref string REQUIRED
samples integer REQUIRED
words object[] REQUIRED
Array of:
text string REQUIRED
start_us integer REQUIRED
Microseconds on the virtual timeline.
end_us integer REQUIRED
Microseconds on the virtual timeline.
byte_start integer
UTF-8 byte offset of the word in its segment text.
byte_end integer
actions object[] REQUIRED
Timed browser actions in at_us order (ties keep array order). The recorder replays exactly this list in the probe pass and in every capture segment. The virtual clock is frozen while navigate and wait actions settle, so their wall time never shows in the video.
Array of:
id string REQUIRED
kind unknown REQUIRED
Enum: navigate, click, hover, type, key, scroll, select, wait
at_us integer REQUIRED
When the action starts.
beat string
target unknown | unknown | unknown
What an action acts on. Resolution (littledemo targeting): candidates matching selector, text (visible text, case-insensitive substring unless exact), or role plus accessible name, limited to within; the best-scored candidate wins, or the nth match when nth is set. A target that is still outside the viewport after scrolling it into view fails the action with target_not_found.
Any of:
Option 1unknown
Option 2unknown
Option 3unknown
url string (uri)
wait_until unknown
Enum: load, domcontentloaded, networkidle
button unknown
Enum: left, right, middle
count integer
press_us integer
click: time between mouse down and mouse up.
modifiers unknown[]
Array of: unknown
text string
interval_us integer
type: delay between characters; character i (a Unicode scalar value) is inserted at at_us + i * interval_us.
key string
KeyboardEvent.key, e.g. Enter, Tab, a.
to object
scroll: document scroll offset to reach.
x number REQUIRED
y number REQUIRED
by object
scroll: delta from the current offset.
x number REQUIRED
y number REQUIRED
duration_us integer
scroll: animation length on the virtual clock.
easing unknown | object | object
Easing for the segment that ends at this keyframe; u in [0, 1]. linear: u. ease_in_out_cubic: u < 0.5 ? 4u^3 : 1 - (2 - 2u)^3 / 2. ease_out_quart: 1 - (1 - u)^4. smootherstep: 6u^5 - 15u^4 + 10u^3. hold: 0 until u = 1, then 1. cubic_bezier: CSS cubic-bezier(x1, y1, x2, y2). critically_damped: s(u) / s(1) with s(u) = 1 - (1 + w u) e^(-w u). Default ease_in_out_cubic.
One of:
Option 1unknown
Option 2
cubic_bezier array REQUIRED
Option 3
critically_damped object REQUIRED
omega number REQUIRED
value string
select: option value.
for object
wait: the condition. The virtual clock is frozen until it holds.
selector string
text string
url string
Substring the page URL must contain.
network_idle unknown
Enum: true
timeout_ms integer
navigate and wait: wall-clock budget for settling.
observed object
What the probe pass observed when the action ran; filled by the recorder, read by the director to plan cursor and camera. rect and point are viewport space at at_us.
ok boolean REQUIRED
rect object
x number REQUIRED
y number REQUIRED
width number REQUIRED
height number REQUIRED
point object
x number REQUIRED
y number REQUIRED
selector string
A unique selector for the resolved element.
url string
Page URL after the action.
scroll object
Document scroll offset after the action.
x number REQUIRED
y number REQUIRED
settled_us integer
Virtual time at which a navigate or wait finished.
error object
code string REQUIRED
detail string
cursor object
Composited cursor (not drawn in the page). Position is linear between consecutive points; pressed and visible keep their last value until a point changes them. Before the first point and after the last, the nearest point applies.
points object[] REQUIRED
Array of:
t_us integer REQUIRED
Microseconds on the virtual timeline.
x number REQUIRED
y number REQUIRED
pressed boolean
visible boolean
camera object
Camera keyframes. For t between keyframes k-1 and k: u = (t - t[k-1]) / (t[k] - t[k-1]), e = easing[k](u), zoom = zoom[k-1] * (zoom[k] / zoom[k-1])^e, center = center[k-1] + (center[k] - center[k-1]) * e. Before the first keyframe and after the last, the nearest keyframe holds. The camera rect is width = viewport.width / zoom, height = viewport.height / zoom, x = clamp(center.x - width / 2, 0, viewport.width - width), y likewise. Absent: zoom 1 centered.
keyframes object[] REQUIRED
Array of:
t_us integer REQUIRED
Microseconds on the virtual timeline.
center object REQUIRED
x number REQUIRED
y number REQUIRED
zoom number REQUIRED
easing unknown | object | object
Easing for the segment that ends at this keyframe; u in [0, 1]. linear: u. ease_in_out_cubic: u < 0.5 ? 4u^3 : 1 - (2 - 2u)^3 / 2. ease_out_quart: 1 - (1 - u)^4. smootherstep: 6u^5 - 15u^4 + 10u^3. hold: 0 until u = 1, then 1. cubic_bezier: CSS cubic-bezier(x1, y1, x2, y2). critically_damped: s(u) / s(1) with s(u) = 1 - (1 + w u) e^(-w u). Default ease_in_out_cubic.
One of:
Option 1unknown
Option 2
cubic_bezier array REQUIRED
Option 3
critically_damped object REQUIRED
omega number REQUIRED
captions object
burn_in unknown REQUIRED
none: sidecar files only. static: draw each cue. karaoke: draw each cue and highlight the word being spoken.
Enum: none, static, karaoke
sidecars unknown[]
Array of: unknown
max_chars_per_line integer
max_lines integer
max_chars_per_second number
cues object[] REQUIRED
Array of:
id string REQUIRED
start_us integer REQUIRED
Microseconds on the virtual timeline.
end_us integer REQUIRED
Microseconds on the virtual timeline.
lines string[] REQUIRED
Array of: string
words object[]
Array of:
text string REQUIRED
start_us integer REQUIRED
Microseconds on the virtual timeline.
end_us integer REQUIRED
Microseconds on the virtual timeline.
line integer REQUIRED
byte_start integer REQUIRED
byte_end integer REQUIRED
capture_plan object[]
Per capture frame: the viewport region to capture. Sent to the recorder for each segment. Frames not listed are not captured.
Array of:
seq integer REQUIRED
camera object REQUIRED
x number REQUIRED
y number REQUIRED
width number REQUIRED
height number REQUIRED
scale number
Explicit clip.scale; default derived as above.
frames object[]
Optional FrameState dump (debugging, tests, GET .../timeline?frames=1).
Array of:
index integer REQUIRED
t_us integer REQUIRED
Microseconds on the virtual timeline.
page object REQUIRED
segment integer REQUIRED
seq integer REQUIRED
Latest capture frame with t(seq) <= t_us; when it had damage false, the image of the latest earlier frame with damage.
camera object REQUIRED
x number REQUIRED
y number REQUIRED
width number REQUIRED
height number REQUIRED
camera object REQUIRED
x number REQUIRED
y number REQUIRED
width number REQUIRED
height number REQUIRED
cursor object REQUIRED
x number REQUIRED
y number REQUIRED
visible boolean REQUIRED
pressed boolean REQUIRED
effects object[] REQUIRED
Array of:
kind unknown REQUIRED
Enum: click
x number REQUIRED
y number REQUIRED
age_us integer REQUIRED
Time since the effect started; the style decides how long it lasts.
caption object | null REQUIRED
cue string REQUIRED
lines string[] REQUIRED
Array of: string
highlight object
line integer REQUIRED
byte_start integer REQUIRED
byte_end integer REQUIRED
opacity number REQUIRED
Opacity of the window layer (page, frame chrome, shadow, border, cursor, click effects) over the background; the background and the caption stay opaque.
motion object
Change since the previous output frame, for motion blur: camera center delta and log-zoom delta of the keyframe path (before the viewport clamp, so a camera held at an edge still reports its path), cursor delta (viewport space).
camera_dx number
camera_dy number
camera_dlog_zoom number
cursor_dx number
cursor_dy number
400 The request failed validation (`invalid_request`, `invalid_url`).
401 Missing, malformed, expired or revoked credentials (`unauthorized`).
403 Authenticated but not allowed (`forbidden`, `egress_denied`).
404 No such video in this project (`video_not_found`).
409 The video has not finished planning yet (`conflict`).
429 A rate, concurrency or quota limit applies (`rate_limited`, `concurrency_limited`, `quota_exceeded`).
500 Something failed inside B3OS (`internal`). Retry with backoff.
503 The node or the product is not available right now (`node_unavailable`, `product_unavailable`, `capacity_unavailable`).
curl -X GET 'https://beta-api.b3os.org/v1/render/videos/vid_01m5t4c5ep9bdfhtx7nk2k3vq7/timeline' \  -H 'Authorization: Bearer YOUR_API_TOKEN'
const response = await fetch('https://beta-api.b3os.org/v1/render/videos/vid_01m5t4c5ep9bdfhtx7nk2k3vq7/timeline', {  method: 'GET',  headers: {      "Authorization": "Bearer YOUR_API_TOKEN"  }});const data = await response.json();console.log(data);
import requestsheaders = {    'Authorization': 'Bearer YOUR_API_TOKEN'}response = requests.get('https://beta-api.b3os.org/v1/render/videos/vid_01m5t4c5ep9bdfhtx7nk2k3vq7/timeline', headers=headers)print(response.json())
200 Response
{  "version": 1,  "job": "vid_01m5t4c5ep9bdfhtx7nk2k3vq7",  "duration_us": 2000000,  "viewport": {    "width": 1440,    "height": 900  },  "capture": {    "fps": 30  },  "output": {    "width": 1920,    "height": 1080,    "fps": 60  },  "source": {    "url": "https://app.example.com"  },  "actions": [    {      "id": "a1",      "kind": "click",      "at_us": 600000,      "target": {        "role": "link",        "name": "Billing"      }    }  ]}
Ask a question... ⌘I