Live video
An endless video that keeps going while you watch — POST /v1/videos/live streams ~5 s chunks, each carrying on from the one before, and you change what happens next at any moment. Events, steering, pricing and limits.
POST /v1/videos/live starts a live video: a stream of server-sent events that delivers a new ~5 s mp4 chunk every few seconds. Each chunk carries on from the last second of the one before — the motion included, not just a still — so played back to back they make one continuous shot — and it follows whatever prompt is current, which you can change while it runs. Give it a first frame to start from, and a director — a chat model that writes every next shot and takes your directions while it plays. Try it without code in the playground, where an image model can also draw the first frame.
Models#
| Model | Price | What it makes |
|---|---|---|
ltx-live | $0.019 per second of video made, at least $0.42 per session | LTX-2.5, 704×384 landscape or 384×704 portrait, 24 fps, with sound. Renders faster than real time: a 5 s chunk takes about 3 s. Keeps the people and the place of the first frame for the whole stream. |
It runs on our own GPUs in the creative-hosted channel group and is under the LTX terms: every request sets consent: true, accepting them and the responsibility for following them.
Start a stream#
curl -N https://lovelyrouter.com/v1/videos/live \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{"model": "ltx-live", "prompt": "A fox trots through fresh snow at dusk, the camera tracking beside it", "seconds": 120, "consent": true}'Body (JSON, or multipart with image as a file)
modelstringRequiredltx-live.
promptstringRequiredWhat is on screen and what happens: subject, action, place, light, camera. Up to 1,000 characters; short prompts render fastest.
secondsnumberDefault 60The most video to make, 5–600. The stream ends there, or earlier when you stop it or close the connection.
sizestringDefault 704x384704x384 (landscape) or 384x704 (portrait).
imagefile or stringThe first frame to start from: a file, an http(s) URL or a data: URL. PNG, JPEG or WebP, up to 15 MB; cropped to size from the center. Make one with any image model and pass its file. It also stays the stream's reference: faces, clothes and the room are kept as they are in it, however long it runs (without one, the first chunk is).
directorstring or objectA chat model that writes every next chunk's prompt: its id, or {"model": "…", "instructions": "…"} with notes on style and story (up to 2,000 characters). See The director.
voicefile or stringThe speaker's voice: an audio clip (WAV, MP3, M4A, Ogg, FLAC or WebM, up to 15 MB) as a file, an http(s) URL or a data: URL. Its first ~5 seconds of speech are used; every chunk speaks in it. See Voice.
keep_voicebooleanDefault trueWithout voice: the voice heard in the first chunk with speech is kept for every later chunk. false: each chunk makes its own.
camerastringDefault freefixed for one locked-off shot: the camera never moves or cuts and the place stays the same. See Fixed camera.
seedintegerRepeatable chunks: chunk n uses seed + n.
consentbooleanRequiredtrue: you accept the LTX terms.
Events#
| Event | When | Data |
|---|---|---|
session | first | the session object, plus seconds_per_chunk, price_per_second and price_min (the least a session pays) |
status | every ~10 s while a GPU starts (state: "starting"), the director writes ("directing") or a chunk takes long ("rendering"); once if the director fails ("director_error", the video keeps the last prompt) | state, chunk, waiting_s, error |
next | when the director has written a coming chunk's prompt | index, prompt, by |
chunk | one per ~5 s of video | index, url (the mp4), prompt (what it followed), by (director or you), seconds, total_seconds, render_s, charge_usd (so far) |
end | last | reason (max_seconds, stopped, client_left, insufficient_quota, error), error, seconds, charge_usd |
The first chunk takes longer when no GPU is warm: up to about a minute while one starts, with status events meanwhile. After that, chunks arrive a little faster than they play. Buffer two before you start playback and play each one as the previous ends — two <video> elements, swapping, play it gaplessly.
Chunk URLs need no API key (each has its own unguessable path) and are kept for 7 days.
The director#
With director, a chat model writes the prompt of every chunk: while one chunk renders, it writes the next as if told "continue": from your prompt (the story), the video so far (up to its last 15 shots, your directions where you gave them) and anything you said since — keeping the same people, place and look, and moving the action on a little each shot. Each prompt says what is on screen, what happens, what the camera does and what we hear — the model makes the sound too. Spoken lines go in quotes with who says them, about 10 words per chunk (that is what ~5 s holds); a longer speech carries on over the next chunks from where the last line stopped. Its calls go through your key like any chat call: billed at that model's price and listed in your logs. A fast, cheap model is plenty. It writes two shots per call and has about 10 seconds (two chunks) for each call, or the video pauses until it is done — claude-haiku-5.5 takes about 6 s. It writes a few chunks ahead: while a finished chunk waits to play, the next call waits until that chunk starts, and a new direction has the shots not filmed yet written again at once — so your directions show within seconds.
curl -N https://lovelyrouter.com/v1/videos/live \
-H "Authorization: Bearer $LOVELY_API_KEY" -H "content-type: application/json" \
-d '{"model": "ltx-live", "prompt": "A woman walks home through a rainy city at night", "seconds": 300,
"director": {"model": "claude-haiku-5.5", "instructions": "Slow, moody, film noir"}, "consent": true}'Tell it what should happen while it plays:
curl https://lovelyrouter.com/v1/videos/live/LIVE_ID/direct \
-H "Authorization: Bearer $LOVELY_API_KEY" -H "content-type: application/json" \
-d '{"message": "A stray dog starts following her"}'A direction is worked into the next prompt it writes. After that it stays in the video so far where you gave it, so what it changes keeps applying (a new place, mood or language) and an event happens once. A direction that arrives after a prompt was written gets that prompt rewritten before its chunk starts. A session takes up to 100 directions; they are listed in the session object.
Fixed camera#
With "camera": "fixed" the whole stream is one locked-off shot — for a person talking to the camera, a room, a window. The director is told the camera never moves or cuts and the place never changes, whatever the story or your directions say, and only the people move. Every prompt sent to the model ends with "Static camera, locked-off shot." unless it already says so — the director's and your own (POST …/prompt). The chunk events report the prompt as sent.
A long fixed shot would slowly lose its background: every chunk starts where the one before ended, so small losses add up. With a fixed camera, the room each chunk starts from is cleaned — the person and anything that changed are kept, the rest comes from a clean copy of the room taken at the start. The video itself is not touched, so the room keeps its own small movements. If the framing changes, the clean copy is taken again.
Voice#
Each chunk makes its own sound, so a person talking would get a new voice every few seconds. By default the voice heard in the first chunk with speech is kept: every later chunk is given that clip as the speaker's voice. Send voice to choose it yourself — about 5 seconds of clear speech, one speaker. "keep_voice": false turns this off.
Change what happens next#
curl https://lovelyrouter.com/v1/videos/live/LIVE_ID/prompt \
-H "Authorization: Bearer $LOVELY_API_KEY" -H "content-type: application/json" \
-d '{"prompt": "It starts to snow harder; the fox stops and looks up"}'The next chunk to start follows the new prompt word for word (the one rendering now keeps its own); with a director, it then continues from there. LIVE_ID is the id from the session event or the x-lovely-request-id header.
POST /v1/videos/live/LIVE_ID/stop ends the session after the chunk in progress. Closing the connection ends it too.
The session#
GET /v1/videos/live/LIVE_ID returns the session object: id, object: "video.live", model, status (live, stopping, ended), prompt, size, seconds (made so far), max_seconds, chunks (every chunk URL so far), camera, voice (keep, upload or off), director, directions, end_reason, error, charge_usd (once ended).
Pricing#
You pay per second of video made, at least a minimum per session ($0.42 for ltx-live, about 22 seconds of video: starting a GPU and keeping it ready costs us that much). The director's calls are billed separately, as chat calls. When the session starts, the most it can cost is held from your balance — seconds × the price (at least the minimum), or less when your balance is lower, in which case the stream ends with insufficient_quota when the held amount is used. The hold is released when the session ends and the seconds made are billed as one call in your logs. A session that ends on our error pays only for the video it made, without the minimum.
Limits#
- One open session per account. A second one is refused with
429until the first ends. - A small number of GPUs serve each model; when all are streaming, a new session gets
503withretry-after. - Sessions run up to 600 s. Start another to keep going — pass the last chunk's final frame as
imageto continue the same shot.