Music video endpoints
Every /v1/videos/music endpoint — create a music video from a song, poll it, review and edit its scenes, render, download the video, one scene or a look's reference sheet, delete — with parameters, responses and errors.
The music videos API lives under https://lovelyrouter.com/v1/videos/music. Authenticate every request with your API key as Authorization: Bearer $LOVELY_API_KEY (Authentication). Requests are JSON or multipart; responses are JSON, except the video files. Videos are billed from your prepaid balance.
For a walkthrough — how a song becomes a video, writing the brief, timing and pricing — start with the music videos guide.
The music video object#
Every endpoint returns this object, or a list of them.
Attributes
idstringUnique id, mv_ followed by 24 characters.
objectstringAlways music_video.
modelstringThe model it renders with: ltx-music-video or minimax-h3-music-video.
statusstringanalyzing, planning, ready (waiting for Render, with auto_render: false), in_progress, completed, failed or cancelled.
stepstringThe step in more detail: analyzing, planning, ready, rendering, stitching (joining the scenes), succeeded, failed or cancelled.
planning_stepstring | nullWhile planning: casting (the director defines the singer and the looks), profile (the looks' reference sheets are drawn), directing (the shots are written) or frames (each scene's first frame is drawn). null in any other status.
progressinteger0–100: analysis to 5, writing the scenes to 15, rendering to 95, joining to 100.
created_atintegerUnix seconds.
completed_atinteger | nullWhen it finished, once completed.
expires_atinteger | nullWhen the files are deleted, 7 days after completed_at.
secondsnumber | nullThe song's length (or the slice's) once it is analysed; the video's length once it is finished.
startnumber | nullWhere the slice begins in the song, in seconds. null when the whole song is used.
endnumber | nullWhere the slice ends, in seconds — after analysis, as applied (an end past the song's end becomes its end). null when the whole song is used.
sizestringThe aspect you asked for (16:9, 9:16, 1:1), then the video's pixels once it is finished, such as 1472x832.
modestringimage (with the character profile) or text.
briefobjectstory, style, character and locations as you sent them (null when not sent). With character_id and no character, character is the saved character's description.
character_idstring | nullThe saved character the video was made with, or null.
director_modelstringThe chat model that writes the scenes.
image_modelstring | nullThe image model that draws the reference sheets and the first frames, in mode: "image".
first_framesbooleanWhether minimax-h3-music-video also drew a first frame per scene (first_frames in the request).
temponumber | nullThe song's tempo in beats per minute, after analysis.
languagestring | nullThe language the lyrics were transcribed in, after analysis.
characterstring | nullThe singer as cast by the director: face, hair, body, no clothes. null with mode: "text" and until casting is done.
looksarrayThe singer's looks (outfits), at most four; empty with mode: "text" and until casting is done.
scenesarrayOne entry per scene, in order; empty until the song is analysed.
errorobject | nullFor failed and cancelled videos: code and message (which says whether anything was charged).
urlstring | nullThe finished mp4, once completed. See Download the video.
hold_usdnumberThe amount held from your balance: the whole song's price, from the end of the analysis until the video is settled. 0 before.
charge_usdnumber | nullWhat the video cost, once it is settled. null before.
other_usdnumberWhat the director's chat calls and the reference sheets' and first frames' image calls have cost so far. They are billed as their own calls, not in charge_usd.
powered_bystringLTX or MiniMax H3.
{
"id": "mv_8c1f3a9e2b7d4c60a5e9f1b3",
"object": "music_video",
"model": "ltx-music-video",
"status": "completed",
"step": "succeeded",
"planning_step": null,
"progress": 100,
"created_at": 1792915200,
"completed_at": 1792915330,
"expires_at": 1793520130,
"seconds": 16.13,
"start": null,
"end": null,
"size": "1472x832",
"mode": "image",
"brief": {
"story": "A night drive through a neon city that ends at the sea at dawn",
"style": "Cinematic 35 mm film, teal and orange, light rain",
"character": "A woman in her twenties with short black hair and a red leather jacket",
"locations": null
},
"character_id": null,
"director_model": "gemini-3.8-flash",
"image_model": "gpt-image-2",
"first_frames": false,
"tempo": 118,
"language": "en",
"character": "A woman in her twenties with short black hair in a blunt bob, dark brown eyes, light olive skin, a slim build and a small scar above her left eyebrow",
"looks": [
{
"id": 1,
"outfit": "A red leather jacket over a black T-shirt, dark jeans, black boots, silver hoop earrings",
"url": "https://lovelyrouter.com/v1/videos/music/mv_8c1f3a9e2b7d4c60a5e9f1b3/looks/1/content"
}
],
"scenes": [
{
"index": 0,
"look": 1,
"start": 0,
"seconds": 5.375,
"lyrics": null,
"prompt": "A woman in her twenties with short black hair in a blunt bob, dark brown eyes, light olive skin, a slim build and a small scar above her left eyebrow, wearing a red leather jacket over a black T-shirt, dark jeans, black boots, silver hoop earrings. Style: Cinematic 35 mm film, teal and orange, light rain. She drives through the neon city, signs smearing across the wet windshield; the camera pushes in from the passenger seat.",
"status": "done",
"url": "https://lovelyrouter.com/v1/videos/music/mv_8c1f3a9e2b7d4c60a5e9f1b3/scenes/0/content"
},
{
"index": 1,
"look": 1,
"start": 5.375,
"seconds": 5.042,
"lyrics": "we never looked back",
"prompt": "A woman in her twenties with short black hair in a blunt bob, … wearing a red leather jacket over a black T-shirt, … Style: Cinematic 35 mm film, teal and orange, light rain. Medium close-up: she sings \"we never looked back\" to the camera, hair whipping in the wind of the open window, handheld.",
"status": "done",
"url": "https://lovelyrouter.com/v1/videos/music/mv_8c1f3a9e2b7d4c60a5e9f1b3/scenes/1/content"
},
{
"index": 2,
"look": 1,
"start": 10.417,
"seconds": 5.708,
"lyrics": null,
"prompt": "A woman in her twenties with short black hair in a blunt bob, … wearing a red leather jacket over a black T-shirt, … Style: Cinematic 35 mm film, teal and orange, light rain. She steps out of the car on an empty beach road as the sky turns pink; the camera tracks alongside her toward the sea.",
"status": "done",
"url": "https://lovelyrouter.com/v1/videos/music/mv_8c1f3a9e2b7d4c60a5e9f1b3/scenes/2/content"
}
],
"error": null,
"url": "https://lovelyrouter.com/v1/videos/music/mv_8c1f3a9e2b7d4c60a5e9f1b3/content",
"hold_usd": 0,
"charge_usd": 1.1288,
"other_usd": 0.1621,
"powered_by": "LTX"
}Create a music video#
/v1/videos/musicStarts a music video from a song and returns 202 with the music video object at once. The work runs in the background; follow it with Retrieve a music video. Send multipart (song and character_image as files) or JSON (the same as http(s) or data: URLs). The singer can come inline with the call (character, character_image) or from a saved character (character_id); both work, and neither is required. By default the singer is cast and drawn first (character profile). Starting needs a balance that covers the shortest video (15 seconds); the whole song's price is held once its length is known.
Body parameters
modelstringRequiredltx-music-video or minimax-h3-music-video (see Models).
songfile or stringRequiredThe song: MP3, WAV, FLAC, OGG or M4A, 5 seconds to 6 minutes, up to 60 MB. A file, or an http(s) / data: URL (also accepted as song_url).
startnumberUse only part of the song: where the slice begins, in seconds (default 0). Analysis, scenes, lyrics and the soundtrack all follow the slice, and you pay for its length. See Use part of a song.
endnumberWhere the slice ends, in seconds (default: the song's end). end − start must be at least 5 seconds and at most 6 minutes.
consentbooleanRequiredtrue: you accept the model's terms — the LTX terms or the MiniMax H3 terms, its territory clause included — and the responsibility for following them, and confirm that anyone recognisable in your brief or picture is 18 or older and agreed to this use of their likeness.
storystringWhat happens over the song. Up to 4,000 characters, like the other brief fields.
stylestringThe look: film or animation, colours, light, lens. Added to every scene's prompt.
characterstringThe singer (face, hair, build, the main outfit). Casting keeps every detail and fills in the rest; with mode: "text" it is added to every scene's prompt as it is.
locationsstringThe places the story moves through.
lyricsstringThe song's words as written, for the right spelling. Optional: the lyrics are transcribed anyway.
languagestringThe song's language for the transcription, such as en, zh or ja. Default: detected.
sizestringDefault 16:916:9, 9:16 or 1:1: 1472×832, 832×1472 or 1152×1152 with ltx-music-video; 1344×768, 768×1344 or 1024×1024 with minimax-h3-music-video.
modestringDefault imageimage: the character profile — the director casts the singer and up to four looks, image_model draws a reference sheet per look, and every scene starts from a first frame drawn from its look's sheet (minimax-h3-music-video: every scene is filmed from the sheet itself; see first_frames). text: no pictures, every scene from its prompt alone; not with minimax-h3-music-video, which needs the profile.
image_modelstringDefault gpt-image-2mode: "image" only. An image model your key can use that accepts reference images (edits), such as gpt-image-2; a generation-only model is refused with 400. Billed as normal image jobs, typically one per look plus one per scene.
first_framesbooleanDefault falseminimax-h3-music-video only (other models always draw first frames in mode: "image"). This model films the singer from their look's sheet, with no first frame; true also draws each scene's opening frame and gives it to the model alongside the sheet: more control over where and how each scene opens, one more picture per scene, and slower renders. The video is then billed at $0.2 per second instead of $0.13.
character_imagefile or stringmode: "image" only. A picture of your singer, the source of look 1's sheet: PNG, JPEG or WebP up to 20 MB, as a file or a URL (also character_image_url).
character_idstringmode: "image" only. A saved character of your account: its sheet is used as character_image would be, and its description as character when you don't send one. Not together with character_image.
director_modelstringDefault gemini-3.8-flashThe chat model that writes the scenes. Any chat model your key can use; billed as normal chat calls.
scene_secondsnumberDefault 5The scene length to aim for, 2–10 seconds. Cuts land on beats, so scenes vary around it.
auto_renderbooleanDefault trueseedintegerRepeatable scenes (0–2147483647). Default: random.
Query parameters
waitinteger0–300. Hold the request until the video changes (a step, a finished scene) or the time runs out; 200 if it has ended by then.
curl https://lovelyrouter.com/v1/videos/music \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-F model=ltx-music-video \
-F song=@song.mp3 \
-F story="A night drive through a neon city that ends at the sea at dawn" \
-F style="Cinematic 35 mm film, teal and orange, light rain" \
-F character="A woman in her twenties with short black hair and a red leather jacket" \
-F start=42.5 -F end=102.5 \
-F consent=true
# With a saved character instead of the inline character text and picture:
curl https://lovelyrouter.com/v1/videos/music \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-F model=ltx-music-video -F song=@song.mp3 \
-F character_id=chr_3b9e1f0c7a2d4e58b6c1a9f2 \
-F consent=true{
"id": "mv_8c1f3a9e2b7d4c60a5e9f1b3",
"object": "music_video",
"model": "ltx-music-video",
"status": "analyzing",
"step": "analyzing",
"planning_step": null,
"progress": 2,
"seconds": null,
"size": "16:9",
"mode": "image",
"character": null,
"looks": [],
"scenes": [],
"error": null,
"url": null,
"hold_usd": 0,
"charge_usd": null,
"other_usd": 0,
"powered_by": "LTX"
}Retrieve a music video#
/v1/videos/music/{id}Returns the music video object. Poll it until status is completed, failed or cancelled.
Query parameters
waitinteger0–300. Long-poll: return as soon as the step changes or another scene finishes, or when the time runs out. A video at ready returns at once.
curl "https://lovelyrouter.com/v1/videos/music/MUSIC_ID?wait=120" \
-H "Authorization: Bearer $LOVELY_API_KEY"List music videos#
/v1/videos/musicYour music videos, newest first.
Query parameters
limitintegerDefault 201–100.
afterstringA music video id: list the ones created before it (the next page).
curl "https://lovelyrouter.com/v1/videos/music?limit=10" \
-H "Authorization: Bearer $LOVELY_API_KEY"{
"object": "list",
"data": [{ "id": "mv_8c1f3a9e2b7d4c60a5e9f1b3", "object": "music_video", "status": "completed" }],
"first_id": "mv_8c1f3a9e2b7d4c60a5e9f1b3",
"last_id": "mv_8c1f3a9e2b7d4c60a5e9f1b3",
"has_more": false
}Edit scenes#
/v1/videos/music/{id}Rewrites scene prompts while the video is ready (created with auto_render: false). Each prompt you send replaces the scene's prompt as it is — the character, its look and the style are not added again, so keep them in it. In mode: "image" the first frames are already drawn; a new prompt changes the scene's motion, not its first frame. Returns the music video object; 409 in any other status.
Body parameters
scenesarrayRequiredThe scenes to change.
curl -X PATCH https://lovelyrouter.com/v1/videos/music/MUSIC_ID \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{"scenes": [{"index": 2, "prompt": "A woman in her twenties with short black hair and a red leather jacket. She sings \"we never looked back\" on an empty pier at dawn, the camera orbiting her."}]}'Render a music video#
/v1/videos/music/{id}/renderStarts rendering a video that is ready. Returns the music video object, now in_progress; 409 in any other status. A plan that isn't rendered within a day is cancelled without charge.
curl -X POST https://lovelyrouter.com/v1/videos/music/MUSIC_ID/render \
-H "Authorization: Bearer $LOVELY_API_KEY"Download the video#
/v1/videos/music/{id}/contentThe finished mp4, with the song as its soundtrack. Range requests work, so players can seek. Kept for 7 days; 409 before it is completed, 410 once deleted or expired.
curl https://lovelyrouter.com/v1/videos/music/MUSIC_ID/content \
-H "Authorization: Bearer $LOVELY_API_KEY" -o music-video.mp4Download a scene#
/v1/videos/music/{id}/scenes/{n}/contentOne rendered scene's mp4, with its part of the song, as soon as that scene is done — before the whole video is finished. n is the scene's index. 409 while it isn't rendered.
curl https://lovelyrouter.com/v1/videos/music/MUSIC_ID/scenes/0/content \
-H "Authorization: Bearer $LOVELY_API_KEY" -o scene-0.mp4Download a look's sheet#
/v1/videos/music/{id}/looks/{n}/contentA look's turnaround reference sheet (front, three-quarter, side, back), as soon as it is drawn — during planning, before any scene is rendered. n is the look's id, from 1. 404 while it isn't drawn, and with mode: "text".
curl https://lovelyrouter.com/v1/videos/music/MUSIC_ID/looks/1/content \
-H "Authorization: Bearer $LOVELY_API_KEY" -o look-1.pngDelete#
/v1/videos/music/{id}On a finished video (completed, failed or cancelled): deletes its files and removes it from your list. On a plan waiting at ready (auto_render: false): discards it; nothing is charged. A video that has started analysing or rendering can't be stopped: 409. Let it finish, then delete it.
curl -X DELETE https://lovelyrouter.com/v1/videos/music/MUSIC_ID \
-H "Authorization: Bearer $LOVELY_API_KEY"{ "id": "mv_8c1f3a9e2b7d4c60a5e9f1b3", "object": "music_video.deleted", "deleted": true }Errors#
Errors use the standard error body. A video that fails after it started is not an HTTP error: its status is failed and error says why.
| Status | type / code | Why |
|---|---|---|
400 | consent_required | consent wasn't true. |
400 | invalid_request_error | A missing or unreadable song or picture, a file that's too large, a field out of range, a slice shorter than 5 seconds or longer than 6 minutes, character_image, character_id or first_frames without mode: "image", mode: "text" with minimax-h3-music-video, both character_image and character_id, or a director_model / image_model your key can't use. |
401 | authentication_error | A missing or invalid API key. |
402 | insufficient_quota | The balance, or the key's spend limit, doesn't cover the shortest video. |
404 | not_found_error | Unknown model or music video, a model that doesn't make music videos, a character_id that isn't one of your saved characters, or a look whose sheet isn't drawn yet. |
409 | invalid_request_error | Editing or rendering a video that isn't ready, or downloading a file that isn't rendered yet. |
410 | not_found_error | The video was deleted or has expired. |
429 | rate_limit_exceeded | Two music videos are already in progress on your account, or your key's rate limit. |
Failed videos carry one of these error.code values: invalid_request_error (the song couldn't be used, such as shorter than 5 seconds or longer than 6 minutes, or a start past its end), insufficient_quota (the balance didn't cover the whole song), capacity_exhausted (no GPU became available), api_error (something failed on our side), expired (a ready plan waited a day) and cancelled (a plan discarded at ready). Nothing is charged for the video in any of them.