본문으로 건너뛰기

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.

Kling video API pricing, promotion and usage

POST/v1/video/generations

Submit a job#

ParameterTypeRequiredDescription
modelstringRequiredVideo model ID, e.g. dreamina-seedance-2-0-260128.
promptstringRequiredVideo description. Up to 4,000 characters.
duration_secondsintegerOptionalRequested duration. 2–20 seconds, default 8. Kling V3 accepts integer durations of 3–15 seconds; specify 5 or 10 for V2.5/V2.6; LTX and ModelArk models apply narrower model-specific ranges.
resolution480p | 720p | 1080p | 1440p | 4kOptionalOutput resolution. Defaults to 720p.
generate_audiobooleanOptionalWhether to generate audio. It defaults to false to avoid an unexpected extra charge for audio. Do not send this field to a model that does not support it, whatever the value; even false returns 400.
imagestring | nullOptionalCompatibility alias for the first image URL. It is combined with images while preserving order.
imagesstring[]OptionalInput-image URLs. Combined with the image alias, there may be at most 9; only HTTP(S) is accepted.
videosstring[]OptionalInput-video reference URLs. At most 3; only HTTP(S) is accepted.
audiosstring[]OptionalInput-audio reference URLs. At most 3; only HTTP(S) is accepted.
request
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"]
  }'
submit + poll (Python)
import os, time, requests

BASE = "https://apirouter.pleum.ai/v1"
HEADERS = {
    "Authorization": f"Bearer {os.environ['PLEUM_API_KEY']}",
    "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"] != "processing":
        break
    time.sleep(5)

print(job["result_url"] if job["status"] == "succeeded" else job["error"])
submit + poll (TypeScript)
const BASE = "https://apirouter.pleum.ai/v1";
const HEADERS = {
  Authorization: `Bearer ${process.env.PLEUM_API_KEY}`,
  "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 === "processing");

console.log(job.status === "succeeded" ? job.result_url : job.error);
200 OK
{
  "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 credits are deducted. Unsupported combinations return 400 with no charge.

ParameterTypeRequiredDescription
KlingdurationOptionalV3 accepts integer durations of 3–15 seconds; V2.5/V2.6 support 5 or 10 seconds. Specify duration_seconds explicitly for the desired model and length. Image references are limited to one. For resolution, kling-v3-turbo supports 720p and 1080p, kling-v3-omni supports 720p, 1080p and 4k, and the other Kling models are fixed at 720p; any other value returns 400. Models: kling-v3, kling-v3-turbo, kling-v3-omni, kling-v2-5-turbo, kling-v2-6.
LTX 2.3 Fast / Produration + resolutionOptionalText-to-video only. Resolutions are 720p, 1080p, 1440p, and 4k; 480p returns 400. 720p is generated at 1280x720 and billed at the 720p price. Fast supports 6/8/10/12/14/16/18/20 seconds at 720p and 1080p and 6/8/10 seconds at 1440p/4k. Pro supports 6/8/10 seconds at every resolution.
LTX 2.5 Fast / Produration + resolutionOptionalText-to-video only, like LTX 2.3. Fast has the same resolution and duration rules as LTX 2.3 Fast. Pro supports 6/8/10 seconds at 720p and 1080p only.
Seedance 2.0duration + referencesOptional4–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 / MiniresolutionOptionalOnly 480p or 720p. Mini does not support video or audio references.
Seedance 2.5resolutionOptionalOnly 480p or 720p.
Seedance 1.0 Produration + referencesOptional2–12 seconds and no 4k. At most two image references (one for Fast), no video/audio references, and no generate_audio support.
Gemini OmniresolutionOptionalText-to-video only. Resolution 720p, 1080p, or 4k (default 720p). The model decides the 3–10 s length, so sending duration_seconds returns 400; image/videos/audios references are not supported either. Settlement uses the output tokens reported by the completed response. Fetch the result through the /content endpoint under “Download the result”.

Poll a job#

GET/v1/jobs/{job_id}

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. A job that expired at the provider is reported as failed. For how to fetch results from Google models (Gemini Omni), see “Download the result” below.

succeeded
{
  "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"}]
}

Download the result#

GET/v1/jobs/{job_id}/content

For most models result_url is a directly downloadable URL. For Google models (Gemini Omni, etc.) result_url points at /v1/jobs/{job_id}/content and must be fetched with the API key that submitted the job in the Authorization header (it cannot be used where headers cannot be attached, such as <video src>). Other keys get 404; a job still processing returns 409. A single Range request (206) is supported. Google keeps the file for only about 48 hours, after which the endpoint returns 410. Downloads are not billed — copy the file to your own storage right after completion.

download
# When result_url points at /v1/jobs/{job_id}/content, download it with the API key that submitted the job.
curl -L https://apirouter.pleum.ai/v1/jobs/$JOB_ID/content \
  -H "Authorization: Bearer $PLEUM_API_KEY" \
  -o result.mp4

# A single Range request is supported (206 Partial Content).
curl https://apirouter.pleum.ai/v1/jobs/$JOB_ID/content \
  -H "Authorization: Bearer $PLEUM_API_KEY" \
  -H "Range: bytes=0-1048575" -o part.mp4

Settlement and BYOK#

LTX video is settled from the requested duration at the per-second price of the selected resolution. ModelArk video is finally settled from the output-token usage reported by the completed job. Idempotency-Key is optional (max 128 chars). Resubmitting with the same key creates no new job and returns the job_id of the first submission. The same key with a different body returns 422, and a submission that is still processing returns 409. A key is kept for 24 hours.

Async generation such as video and 3D does not support BYOK. A BYOK-key request returns 400. A missing or not-owned job_id also returns 404.