Video
Clips of 2 to 10 seconds with a generated soundtrack, from a prompt or a first frame, on ltx-2.3.
Access: Keys with the media:read or media:generate scope, on an account with media access granted by Albastar Corp.
A video job makes one clip of 2 to 10 seconds with a generated soundtrack on ltx-2.3, from a prompt or from an
image and a prompt, with POST /v1/media/jobs and kind video.
Make a video
POST /v1/media/jobs with kind video, model ltx-2.3 and params.prompt queues one video. The prompt
describes the action over time and the sounds. The example asks for 5 seconds at 720p with ?wait=85, then reads
the job with GET /v1/media/jobs/{id}?wait=85 until the job settles.
curl
JOB=$(curl -s "https://api.albastov.com/v1/media/jobs?wait=85" \
-H "Authorization: Bearer $ALBASTAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "video",
"model": "ltx-2.3",
"params": {
"prompt": "rain on a harbour at night, neon reflections, distant thunder",
"duration_s": 5,
"resolution": "720p",
"seed": 13
}
}' | python3 -c 'import json, sys; print(json.load(sys.stdin)["id"])')
until curl -s "https://api.albastov.com/v1/media/jobs/$JOB?wait=85" \
-H "Authorization: Bearer $ALBASTAR_API_KEY" -o job.json \
-w '%{http_code}' | grep -q 200; do :; done
cat job.jsonPython
import json
import os
import urllib.request
BASE = "https://api.albastov.com/v1"
HEADERS = {
"User-Agent": "my-app/1.0",
"Authorization": f"Bearer {os.environ['ALBASTAR_API_KEY']}",
"Content-Type": "application/json",
}
def call(path, body=None):
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(BASE + path, data=data, headers=HEADERS)
with urllib.request.urlopen(req, timeout=120) as res:
return json.load(res)
job = call("/media/jobs?wait=85", {
"kind": "video",
"model": "ltx-2.3",
"params": {
"prompt": "rain on a harbour at night, neon reflections, "
"distant thunder",
"duration_s": 5,
"resolution": "720p",
"seed": 13,
},
})
while job["state"] in ("queued", "waiting_device", "running"):
job = call(f"/media/jobs/{job['id']}?wait=85")
print(job["state"], [r["url"] for r in job["results"]])JavaScript
const base = "https://api.albastov.com/v1";
const headers = {
Authorization: `Bearer ${process.env.ALBASTAR_API_KEY}`,
"Content-Type": "application/json",
};
async function call(path, body) {
const res = await fetch(base + path, {
method: body ? "POST" : "GET",
headers,
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
return res.json();
}
let job = await call("/media/jobs?wait=85", {
kind: "video",
model: "ltx-2.3",
params: {
prompt: "rain on a harbour at night, neon reflections, distant thunder",
duration_s: 5,
resolution: "720p",
seed: 13,
},
});
while (["queued", "waiting_device", "running"].includes(job.state)) {
job = await call(`/media/jobs/${job.id}?wait=85`);
}
console.log(job.state, job.results.map((r) => r.url));The response is the settled job, with one MP4 result of 5.042 seconds at 1280 by 720 pixels:
{
"id": "mj_BHxQnx8Q688dnTPB8qTGDV",
"kind": "video",
"model": "ltx-2.3",
"state": "done",
"waiting": null,
"position": null,
"priority": "batch",
"params": {
"aspect": "16:9",
"audio": true,
"cfg": 1,
"duration_s": 5,
"fps": 24,
"negative_prompt": "pc game, console game, video game, …",
"prompt": "rain on a harbour at night, neon reflections, distant thunder",
"resolution": "720p",
"seed": 13
},
"results": [
{
"index": 0,
"url": "…/v1/media/files/mj_BHxQnx8Q688dnTPB8qTGDV/0.mp4",
"content_type": "video/mp4",
"bytes": 1474233,
"width": 1280,
"height": 720,
"seed": 13,
"duration_s": 5.042,
"fps": 24,
"audio": true,
"thumb_url": null,
"poster_url": null,
"preview_url": null
}
],
"error": null,
"created_at": "2026-10-21T23:48:13.671Z",
"started_at": "2026-10-21T23:49:03.785Z",
"finished_at": "2026-10-21T23:51:33.702Z",
"queue_timeout_s": null
}The response above shortens url to its path and the default negative_prompt with …, and leaves out label
and fields beyond the job object table.
GET /v1/media/models?kind=video returns the parameters of ltx-2.3 with their ranges and defaults:
curl "https://api.albastov.com/v1/media/models?kind=video" \
-H "Authorization: Bearer $ALBASTAR_API_KEY"params | Type | Values |
|---|---|---|
prompt required | string | The action over time and the sounds; 4,000 characters at most |
duration_s | number | 2 to 10 seconds in steps of 0.5; default 5 |
aspect | string | 16:9 (default), 9:16, 1:1 or 4:5 |
resolution | string | 720p (default) or 1080p |
fps | integer | 24 (default), 25 or 30 |
seed | integer | 0 to 9007199254740991; without seed, a random seed, returned in params and on the result |
cfg | number | 1 to 5 in steps of 0.1; default 1 |
audio | boolean | true (default) keeps the generated soundtrack; false returns a video without sound |
negative_prompt | string | What the video leaves out, 2,000 characters at most; default pc game, console game, video game, cartoon, childish, ugly, text, watermark |
first_frame | string | An image the video starts from: an upload up_…, a job result job:<id>/<i> or an https:// URL |
first_frame_strength | number | 0.1 to 1 in steps of 0.05, default 0.7: how strongly first_frame holds the start of the video; with first_frame only |
Start from an image
first_frame names the image the video starts from: an upload up_…, a result of an earlier job of the account as
job:<id>/<i>, or an https:// URL. With first_frame, the job runs image to video. The size of the video follows
aspect and resolution, not the size of the image. first_frame_strength without first_frame fails with
400 bad-param.
The example starts a 4:5 video from the first image of an earlier image job.
curl
curl "https://api.albastov.com/v1/media/jobs?wait=85" \
-H "Authorization: Bearer $ALBASTAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "video",
"model": "ltx-2.3",
"params": {
"prompt": "a timelapse of the canyon lake rising",
"first_frame": "job:mj_bLuDshhr9LrHsJMFBgWesW/0",
"aspect": "4:5",
"seed": 4017539827
}
}'The settled job's results, from an image of 832 by 1248 pixels, with a poster and a preview:
[
{
"index": 0,
"url": "…/v1/media/files/mj_9NmNoASRC2iLJcdZDuAsGV/0.mp4",
"content_type": "video/mp4",
"bytes": 854952,
"width": 720,
"height": 900,
"seed": 4017539827,
"duration_s": 5.042,
"fps": 24,
"audio": true,
"thumb_url": null,
"poster_url": "…/v1/media/files/mj_9NmNoASRC2iLJcdZDuAsGV/0.poster.webp",
"preview_url": "…/v1/media/files/mj_9NmNoASRC2iLJcdZDuAsGV/0.preview.mp4"
}
]The response above shortens each URL to its path; every URL starts with https://api.albastov.com.
Result
A done video job has one result, index 0:
| Field | Value |
|---|---|
url | The MP4 file: H.264 video, with an AAC soundtrack when audio is true |
content_type | video/mp4 |
bytes | The size of the MP4 file |
width, height | The size in pixels, from aspect and resolution: 1280 by 720 at 16:9 and 720p, 720 by 900 at 4:5 and 720p |
duration_s | The length in seconds, such as 5.042 for duration_s 5 |
fps | Frames per second |
audio | true when the file carries the soundtrack |
seed | The seed the video ran with |
poster_url | A WebP still at the size of the video; null when the job has none |
preview_url | A 3-second MP4 at 480 pixels tall, without sound; null when the job has none |
url, poster_url and preview_url fetch the file without a key. thumb_url is null on a video.
Waits and limits
- Typical time
GET /v1/media/models?kind=videoreportstypical_s300 forltx-2.3: a video takes about 5 minutes once the job starts, plus the time the job waits in the queue.- Waiting
?waitholds a request 85 s at most from its arrival, so a video job outlasts one hold. Read the job again withGET /v1/media/jobs/{id}?wait=85untilstateisdone,failed,cancelledorexpired.- Queue
- A video job without
priorityruns asbatchand waits in the queue as long as it takes;queue_timeout_sisnull. - One video per job
ltx-2.3takes nocount. Each video is 2 to 10 seconds; aduration_soutside the range fails with400 bad-paramandparamduration_s.- Processing time
- A member account has 600 s of media processing time a UTC day by default. Queuing a video sets aside 300 s, and the done job counts the time the video took. Past the limit,
POST /v1/media/jobsfails with429 budget-exhausted.
Reference
Media jobs reference
The job object, the parameters of a video job, ?wait, the job list by kind and the model list.
Uploads reference
A PNG, JPEG or WebP image stored as up_…, to start a video from.
Image & video
Image jobs, image to image and the GenAI app.
Rate limits
The daily processing time of a member account.