Video Generation
Generate video as an async job. Model-specific constraints for LTX 2.3 and BytePlus ModelArk are validated before submission.
POST /v1/video/generations returns a job_id immediately. Poll GET /v1/jobs/{job_id} until it finishes. Every request needs a plm_ API key.
Submit a job#
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | Optional | Video model ID. Defaults to veo-3. |
| prompt | string | Required | Video description. Up to 4,000 characters. |
| duration_seconds | integer | Optional | Requested duration. 2–20 seconds, default 8. Kling allows only 5 or 10, so specify it explicitly; LTX and ModelArk models apply narrower model-specific ranges. |
| resolution | 480p | 720p | 1080p | 1440p | 4k | Optional | Output resolution. Defaults to 720p. |
| generate_audio | boolean | Optional | Whether to generate audio. It defaults to false to avoid an unexpected audio-variant charge. |
| image | string | null | Optional | Compatibility alias for the first image URL. It is combined with images while preserving order. |
| images | string[] | Optional | Input-image URLs. Combined with the image alias, there may be at most 9; only HTTP(S) is accepted. |
| videos | string[] | Optional | Input-video reference URLs. At most 3; only HTTP(S) is accepted. |
| audios | string[] | Optional | Input-audio reference URLs. At most 3; only HTTP(S) is accepted. |
| charge_amount_krw | integer | null | Optional | Fixed KRW settlement amount. Normal API keys cannot use it; only first-party delegated keys may. |
curl https://apirouter.pleum.ai/v1/video/generations \
-H "Authorization: Bearer $PLEUM_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: seedance-shot-001" \
-d '{
"model": "dreamina-seedance-2-0-260128",
"prompt": "A drone shot flying over a misty mountain valley at sunrise",
"duration_seconds": 8,
"resolution": "720p",
"generate_audio": false,
"images": ["https://example.com/first-frame.png"],
"videos": ["https://example.com/motion-reference.mp4"]
}'import time, requests
BASE = "https://apirouter.pleum.ai/v1"
HEADERS = {"Authorization": "Bearer plm_...", "Content-Type": "application/json"}
# 1. Submit the job — returns job_id immediately.
resp = requests.post(f"{BASE}/video/generations", headers=HEADERS, json={
"model": "dreamina-seedance-2-0-260128",
"prompt": "A drone shot flying over a misty mountain valley at sunrise",
"duration_seconds": 8,
"resolution": "720p",
})
job_id = resp.json()["job_id"]
# 2. Poll until the job finishes.
while True:
job = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS).json()
if job["status"] in ("succeeded", "failed"):
break
time.sleep(5)
print(job["result_url"] if job["status"] == "succeeded" else job["error"])const BASE = "https://apirouter.pleum.ai/v1";
const HEADERS = { Authorization: "Bearer plm_...", "Content-Type": "application/json" };
// 1. Submit the job — returns job_id immediately.
const submit = await fetch(`${BASE}/video/generations`, {
method: "POST",
headers: HEADERS,
body: JSON.stringify({
model: "dreamina-seedance-2-0-260128",
prompt: "A drone shot flying over a misty mountain valley at sunrise",
duration_seconds: 8,
resolution: "720p",
}),
});
const { job_id } = await submit.json();
// 2. Poll until the job finishes.
let job: any;
do {
await new Promise((r) => setTimeout(r, 5000));
job = await (await fetch(`${BASE}/jobs/${job_id}`, { headers: HEADERS })).json();
} while (job.status !== "succeeded" && job.status !== "failed");
console.log(job.status === "succeeded" ? job.result_url : job.error);{
"job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "processing",
"model": "dreamina-seedance-2-0-260128",
"result_url": null,
"cost": null,
"error": null,
"assets": []
}Provider-specific video input limits#
The selected LTX or ModelArk model's duration, resolution, and reference combination is validated before a hold is created. Unsupported combinations return 400 with no charge.
| Parameter | Type | Required | Description |
|---|---|---|---|
| Kling | duration | Optional | Only 5 or 10 seconds are supported. Specify duration_seconds explicitly as 5 or 10, otherwise a 400 may be returned. Models: kling-v2-master, kling-v2-1, kling-v1-6, kling-v1-5, kling-v1-0. |
| LTX 2.3 Fast / Pro | duration + resolution | Optional | Text-to-video only. Fast supports 6/8/10/12/14/16/18/20 seconds at 1080p and 6/8/10 seconds at 1440p/4k. Pro supports 6/8/10 seconds at every resolution. 480p/720p requests normalize to LTX's 1080p output. |
| Seedance 2.0 | duration + references | Optional | 4–15 seconds. image≤9, video≤3, audio≤3. An audio reference needs at least one image or video reference. One/two images are first/last frames; with video, audio, or more than two images, every image is a reference_image. |
| Seedance 2.0 Fast / Mini | resolution | Optional | Only 480p or 720p. Mini does not support video or audio references. |
| Seedance 1.5 Pro | duration + references | Optional | 4–12 seconds and no 4k. It accepts at most two image references and no video/audio references. |
| Seedance 1.0 Pro | duration + references | Optional | 2–12 seconds and no 4k. At most two image references (one for Fast), no video/audio references, and no generate_audio support. |
Poll a job#
POST initially returns status: processing. GET /v1/jobs/{job_id} returns the same job shape; a completed job can include video results in assets.
status is one of processing, succeeded, failed, or canceled. Success populates result_url/cost; failure or cancellation returns error. An expired upstream task is normalized to failed. Veo results are mirrored to the router's own storage, so result_url is a working presigned URL.
{
"job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "succeeded",
"model": "dreamina-seedance-2-0-260128",
"result_url": "https://cdn.pleum.ai/video/f47ac10b-58cc-4372-a567-0e02b2c3d479.mp4",
"cost": {"krw": 4200},
"error": null,
"assets": [{"type": "video", "url": "https://cdn.pleum.ai/video/f47ac10b-58cc-4372-a567-0e02b2c3d479.mp4"}]
}Settlement and BYOK#
LTX video is held and settled from the requested duration at the selected resolution's per-second price. ModelArk video is finally settled from the completed task's reported completion-token/output usage. Idempotency-Key is optional (max 128 chars) and replays the same body for 24 hours.
400. A missing or not-owned job_id also returns 404.